Turn off SSH passwords and the botnets lose interest
The claim Every public SSH port on the internet receives thousands of password guesses a day within hours of coming online. The standard responses — moving the port, installing fai...
The claim
Every public SSH port on the internet receives thousands of password guesses a day within hours of coming online. The standard responses — moving the port, installing fail2ban, rate-limiting — treat the noise. Disabling password authentication entirely treats the vulnerability: a guessing attack against a key-only server has no move to make. It is one configuration line, and most of the ritual that surrounds SSH hardening becomes optional the moment it is set.
The configuration
First, confirm your own key works — from a second terminal, while the first stays logged in:
ssh-keygen -t ed25519 -a 64
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
Then, in /etc/ssh/sshd_config:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
AuthenticationMethods publickey
MaxAuthTries 3
LoginGraceTime 20
AllowUsers deploy admin
sshd -t && systemctl reload sshd
sshd -t validates the file before reload — a syntax error in this particular file locks you out with precision. Keep that first session open until a fresh connection succeeds. Also check /etc/ssh/sshd_config.d/ for distribution-supplied drop-ins: on current Ubuntu, a cloud-init file there can re-enable password authentication behind your back, and the drop-ins win.
Why keys end the argument
An ed25519 key is a 256-bit secret. Password guessing works because the space of human passwords is small and structured; there is no equivalent campaign against a keyspace of 2255, and the attackers know it — watch your logs after the change and the attempts collapse to a trickle of scanners confirming the port is open and moving on. The class of incident where a contractor's reused password from an unrelated breach opens your server is not made harder. It is made impossible, because there is no password to reuse.
Passphrase-protect the private key, because the threat model shifts from your server to the laptop holding the key. An agent caches the passphrase per session, so the cost is typing it once a morning.
What you no longer need, and what you still do
Port changes are theatre after this — scanners find 2222 in the same sweep that finds 22, and non-standard ports mostly confuse your own tooling. fail2ban drops from security control to log hygiene; run it if the noise bothers you, but nothing depends on it. What still matters:
- Patching sshd itself. Key-only authentication does not protect against a vulnerability in the daemon. Unattended upgrades cover this.
- Key inventory. The control moves from passwords to
authorized_keysfiles, so audit them:
Every key should map to a named person or a named system. A file with nine keys and an employee list of four is your offboarding process reporting its own failure.for u in $(cut -d: -f1 /etc/passwd); do f="/home/$u/.ssh/authorized_keys" [ -f "$f" ] && echo "== $u" && wc -l < "$f" done - 2FA where a human logs in interactively. A hardware-backed key — resident on a security token — gets you possession-based authentication without one-time codes.
Deploy keys deserve narrower scope than people
The key your CI pipeline uses is not an administrator and should not authenticate as one. Give automation its own account, and constrain the key at the point of entry: a command="/usr/local/bin/deploy.sh" prefix in authorized_keys means that key can run exactly one script and nothing else, whatever the connecting side asks for, and restrict in the same line disables forwarding and tunnelling. A stolen CI key then buys an attacker one constrained action rather than a shell, which is the difference between rotating a credential and rebuilding a host.
Reduce the audience to zero where you can
The stronger version of this article is that port 22 should not be reachable from the internet at all. A WireGuard interface or your cloud provider's identity-based tunnel puts SSH on a private network, and the public attack surface for remote administration becomes one UDP port that does not respond to unauthenticated packets. For a small fleet this is an afternoon of work. Password-less SSH remains correct inside the tunnel — defence in depth, in the boring sense of two independent controls.
The recovery plan you set up first
The honest objection is "what if I lose the key". Answer it before flipping the switch, not after: enrol two keys per administrator, stored separately — one on the daily machine, one on a token in a drawer — and confirm your provider's out-of-band console works, because that console is the recovery path that does not involve SSH at all. Test it once. Then make the change, watch the auth log for a week, and enjoy reading it for the first time: with the noise gone, the log finally contains only entries that mean something.