I close SSH port 22 (and what I use instead)

Most SSH hardening guides stop at key-only auth andfail2ban. That helps, but if your machine has a public IP, port 22 is still open to the internet. Every automated scanner can probe it and get a response: the SSH version string, the banner, proof that something is listening.

The log noise alone is annoying: even with key-only auth, failed attempts pile up every day. But the bigger problem is exposure. If a zero-day drops inOpenSSH, every server with port 22 open is a target before you have time to patch. That has happened before.

I wanted the SSH daemon itself to be unreachable: no banner, no version string, nothing fornmapto work with. Not just rate-limited or hidden behind a non-standard port, but genuinely not connectable unless you already hold the key.

Port knockingis the original approach to this problem. The idea is simple: the server watches for a specific sequence of connection attempts on closed ports. If a client connects to port 7000, then 8000, then 9000, the server recognizes the pattern and temporarily opens a real port, like 22.

It works, but it has a real weakness: the knock sequence travels in the clear. Anyone watching your traffic can capture the sequence and replay it. There is no authentication, only obscurity.

fwknopsolves this withSingle Packet Authorization(SPA). Instead of a knock sequence, you send a single UDP packet that is encrypted and cryptographically signed with anHMAC. The server only opens port 22 if it can verify the packet came from someone holding the right keys.

Before SSH is accessible at all, you send one encrypted UDP packet to the server.fwknopdvalidates the packet and temporarily inserts a firewall rule that opens port 22 for your source IP only, for a configurable time window (I use 120 seconds). After that window, the rule is removed automatically. If you are already connected, the session stays up because the connection was established before the rule disappeared.

From a scanner’s perspective, port 22 never responds. nmap reports it as filtered, the same state as any silently dropped packet. No banner, no RST, no confirmation that SSH is even listening there.

Because SPA uses UDP, the packet can be lost in transit. If SSH hangs on connect, runfwknop -n server1again and retry. It is stateless, so resending is safe.

The SPA packet itself is HMAC-SHA512-authenticated and encrypted. Replaying a captured packet does not work: the packet contains a timestamp and a single-use sequence counter.fwknopdchecks both, and drops the packet silently if either fails.

You need two keys: an encryption key and an HMAC key. The encryption key protects the contents of the SPA packet. The HMAC key authenticates it. They serve different purposes and should be separate; using the same key for both weakens the security properties of the scheme.

Key generation is a one-time step, and you need the output before configuring either side: