- Key login instead of a password practically rules out brute-force attacks on SSH
- Root login by password should be fully disabled – root should only log in with a key
- Changing the port reduces the background noise from automated scans, but is no substitute for real security
- fail2ban automatically blocks IP addresses once too many login attempts fail
Any root server with port 22 open receives its first login attempts within minutes – not from a human, but from scripts that scan IP ranges around the clock looking for open SSH ports. Most fail at the password. Some don't, either because the password was weak, because it already leaked somewhere else, or because a service itself undermines authentication, as in the case of the Proxmox VE vulnerability that let attackers log in as root without any password at all. Against the second case there's little you can do besides patching – against the first, there is.
Why password login is the real risk
A password is a secret you can remember – and that's exactly what makes it vulnerable. It can be guessed, tried against a dictionary, or reused from a leak at a completely different service. An SSH key pair, by contrast, consists of a public part that lives on the server and a private part that never leaves your machine. Without the private key, no one gets in, no matter how many attempts they make.
The safest login attempt is the one that's technically not possible in the first place – not the one that gets locked out after five wrong passwords.
| Feature | Password login | Key login |
|---|---|---|
| Vulnerable to brute force | Yes | Practically no |
| Reusable from another leak | Yes, if the password is reused | No, the key is unique |
| Memorable for the user | Yes, that's the problem | No, doesn't need to be remembered |
| Revocation on loss | Change the password | Remove the public key from authorized_keys |
Step by step: securing SSH access
- Generate a key pair. On your own machine, not on the server. Ed25519 is the current standard – shorter keys than RSA, at least as secure.
ssh-keygen -t ed25519 -C "your-name@rootserver" - Copy the public key to the server. As long as password login is still active, this takes one command. Leave the old session open while you do this.
ssh-copy-id -p 22 root@your-server-ip - Test the login before you switch anything off. Open a second terminal window and log in with the new key without closing the first connection.
ssh root@your-server-ip - Disable password login and root password login. In
/etc/ssh/sshd_config, set (or adjust) the following lines, then restart the service.PasswordAuthentication no PermitRootLogin prohibit-password systemctl restart sshd - Change the port. Also in
/etc/ssh/sshd_config, then adjust the firewall rule and restart the service. Ports above 1024 avoid collisions with other standard services.Port 2222 ufw allow 2222/tcp systemctl restart sshd - Install fail2ban and enable it for SSH. Create your own
jail.localso updates don't overwrite the configuration.apt install fail2ban # /etc/fail2ban/jail.local [sshd] enabled = true port = 2222 maxretry = 5 bantime = 1h systemctl restart fail2ban
Changing the port – useful or just cosmetic?
A different port isn't a security feature in the strict sense; what it mainly does is reduce the amount of automated noise in your logs. Anyone specifically looking for your server will find the open port on 2222 or 22022 just as easily – a simple port scan takes seconds.
- Significantly fewer log entries from automated mass scans
- fail2ban and other evaluations stay readable
- No ongoing effort after the one-time setup
- No protection against a targeted attack
- Must be kept in mind for every new firewall rule and every client
- Doesn't replace key login and fail2ban, only complements them
Checking that it worked
After setup, it's worth doing a quick check before you rely on the new configuration.
- Test password login: A connection attempt with the wrong key or no key at all must be rejected, not prompt for a password.
- Check the port:
ssh -p 2222 root@your-server-ipmust work, and an attempt on port 22 should go nowhere. - Query fail2ban status:
fail2ban-client status sshdshows active bans and the number of failed attempts. - Check the log:
/var/log/auth.log(orjournalctl -u sshd) should show noticeably fewer login attempts after a few days than before.
If your server then runs quietly over a longer period, that's the real confirmation – but someone has to actually look. If you don't want to track this manually in the log, you can have our monitoring continuously check the server's reachability instead.
The steps above apply to Linux root servers, like those listed in our root server overview. If you also run a Windows server via RDP alongside it, a completely different set of rules applies there – we've covered the details in our post on securing a publicly reachable Windows server.