What each measure does
| Measure | What it does | What it leaves |
|---|---|---|
| Move SSH to another port | Removes most of the noise from bots that only try 22 | Internet-wide scanners index every port; the service is just as reachable |
| fail2ban, sshguard | Bans an address after several failed logins | The port still answers; botnets rotate addresses; no help against a pre-auth bug |
| Keys only, passwords off | Ends password guessing for good | The port still answers and runs sshd's pre-authentication code for everyone |
| IP allow-list | Closes the port to everyone else — the best fix when your address is fixed | Breaks for home, mobile and travelling admins with changing addresses |
| Port knocking (knockd) | Keeps the port closed until a secret sequence of packets arrives | The sequence is sent in the clear and can be replayed |
| Single packet authorization (fwknop) | One encrypted, non-replayable packet opens the port | A key file and a dedicated client; UDP may be blocked on guest networks |
| VPN | SSH is reachable only inside the tunnel | A network to run; no second factor by itself |
| Key-gated port | Opens the port for your IP after a FIDO2 key touch or a one-time code | A gate service on the server and a client on your computer |
Less noise is not less exposure
The first three rows are about logins. They make guessing harder or quieter, and you should do them: PasswordAuthentication no, PermitRootLogin prohibit-password, a ban tool if you like.
But the worst SSH incidents of recent years were not logins. regreSSHion (CVE-2024-6387) was remote code execution in sshd before authentication; the xz backdoor (CVE-2024-3094) hid in a library that sshd loaded. On the day each was disclosed, servers whose port strangers could not reach had nothing to rush.
Default-deny, opened on proof
The last four rows share one idea: the firewall drops everything, and the port opens only for someone who has proved something first. They differ in what is proved. A knock proves you know a sequence. Single packet authorization and a VPN prove you hold a key file. A key-gated port proves you are holding a hardware key right now — with a PIN or a fingerprint if you require it.
Set up a key-gated SSH port
- Install the RDP-FIDO-GATE package on the server — one package, nothing else comes with it — and run its setup: it prints a one-time enrollment code.
- Install the client on your computer, add the server and enroll your security key with the code.
- Back on the server, add port 22 to the guarded ports. The port closes at that moment; the session you are in stays open.
- Connect by touching the key: the gate opens port 22 for your address for 90 seconds and the client starts
ssh.
sudo apt install ./rdpfido-gate_1.25.2_amd64.deb
sudo rdpfido-gate setup # prints a one-time enrollment code
# enroll a key from the client, then:
sudo rdpfido-gate ports add 22
# from a machine that has not touched a key:
nc -vz -w 3 your-server 22 # times out
The complete walk-through, including how not to lock yourself out, is in Keep the SSH port closed until you touch a FIDO2 key.
Keep doing the basics
- Key-only logins, and no root login by password.
- Automatic security updates. A hidden port buys time on disclosure day; it does not replace the patch.
- A second way in — the provider's console or IPMI — before you change anything in front of SSH.