How to Harden SSH on a Linux VPS
A practical, copy-paste guide to locking down the SSH daemon on your VPS โ the single most important service to secure on a public server.
SSH is the front door to your server, and it is the service attackers hammer hardest. If you run one command after provisioning a VPS, it should be tightening this daemon. This guide walks through the sshd_config directives that actually matter, with commands you can paste directly.
Before you touch anything: keep a second session open
The classic way to lock yourself out is to reload SSH with a broken config. Always keep your current SSH session open while you test changes in a new terminal. If the new login fails, you still have the old one to fix things.
Validate the config file before reloading:
sudo sshd -t
If that prints nothing, the syntax is valid. Only then reload:
sudo systemctl reload ssh
Use key authentication and disable passwords
Passwords can be brute-forced; a 4096-bit key cannot in any practical timeframe. Set up keys first โ our companion guide on SSH key authentication and disabling passwords covers the full flow. Once your key works, edit /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
Disable root login over SSH
Never let root log in directly. Create a sudo user first (see how to create a non-root sudo user), then set:
PermitRootLogin no
If you need root for automation, prohibit-password (key-only root) is a middle ground, but no is stronger. There's a dedicated walkthrough on disabling root login on a VPS.
Limit who and how people can connect
Restrict logins to specific users, cut the login grace window, and drop the retry count so brute-force sessions die quickly:
AllowUsers deploy admin
MaxAuthTries 3
MaxSessions 4
LoginGraceTime 20
AllowUsers is a whitelist โ only the named accounts can authenticate at all. If you manage users with groups, use AllowGroups sshusers instead.
{{SCREENSHOT}}
Change the port (a little quieter, not a lock)
Moving off port 22 won't stop a determined attacker, but it dramatically cuts the volume of automated noise hitting your logs:
Port 2222
Open the new port in your firewall before reloading, or you'll lock yourself out. If you use UFW:
sudo ufw allow 2222/tcp
Our UFW firewall guide explains this in full.
Prefer modern algorithms
Older OpenSSH ships with legacy ciphers for compatibility. On a fresh server you can insist on strong ones:
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
Turn off features you don't use
Every enabled feature is attack surface. If you don't forward X11 or use agent forwarding on the server, disable them:
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitEmptyPasswords no
Add an automated ban layer
Hardening the daemon stops weak logins; fail2ban stops the attacker from even trying thousands of times. It watches your auth log and bans IPs after repeated failures. Install and configure it with our fail2ban setup guide, and read the broader protect a VPS from brute-force attacks piece for the full defence-in-depth picture.
Apply and verify
After editing, always test then reload:
sudo sshd -t && sudo systemctl reload ssh
Open a fresh terminal and confirm you can still log in with your key. Then try logging in as root or with a password โ both should be refused.
A minimal hardened sshd_config to copy
Here's a consolidated block reflecting everything above. Drop the relevant lines into /etc/ssh/sshd_config (or a file in /etc/ssh/sshd_config.d/ on newer Ubuntu, which is cleaner because it survives package upgrades):
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
AllowUsers deploy
MaxAuthTries 3
LoginGraceTime 20
X11Forwarding no
AllowAgentForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
The ClientAlive pair is a small but useful addition: it disconnects idle or dead sessions after roughly ten minutes, so abandoned terminals don't linger as an open door. If you use a drop-in file, name it something like 99-hardening.conf so it loads last and wins over the defaults.
Common mistakes that lock you out
Almost every SSH lockout comes from one of a handful of errors, and they're all avoidable:
- Disabling passwords before the key works. Always confirm a successful key login in a second terminal first. If the key login prompts for a *server password* rather than your key passphrase, the key isn't installed correctly โ fix that before touching
PasswordAuthentication. - Wrong permissions on
~/.ssh. SSH silently ignoresauthorized_keysif the directory is group- or world-writable. It must be700, and the file600. - Changing the port without opening the firewall. Open the new port in UFW *before* you reload SSH, or the reconnect will fail.
- A typo in
AllowUsers. If you misspell the username, no one can log in. Runsudo sshd -tand test in a new session every time.
If you do get locked out, your provider's web console is the escape hatch โ you can log in locally, revert the config, and reload. Keeping that console access in mind removes the fear from experimenting with hardening.
FAQ
Does changing the SSH port improve security?
It reduces automated scanning noise but is not real security on its own. Treat it as tidying your logs, not a defence. Key-only auth and a firewall matter far more.
Will disabling password auth lock me out?
Only if your key isn't working yet. Always confirm a successful key-based login in a second session before setting PasswordAuthentication no.
How do I know if my SSH is being attacked?
Check sudo journalctl -u ssh or /var/log/auth.log for repeated "Failed password" or "Invalid user" lines. Our journalctl guide shows how to read these efficiently.
Is fail2ban enough by itself?
No โ it's one layer. Combine it with key-only auth, no root login, and a firewall for real protection.
Quick SSH hardening checklist
Run through this list on every new server and you've covered the essentials:
- Set up key authentication and confirm a key login works in a second session.
- Set
PasswordAuthentication noโ remove the thing brute-force attacks target. - Set
PermitRootLogin noand log in as a sudo user instead. - Restrict logins with
AllowUsersand tightenMaxAuthTries 3. - Disable unused features like X11 and agent forwarding.
- Add an automated ban layer with fail2ban, and a firewall in front.
- Always
sudo sshd -tbeforesystemctl reload ssh, and test in a new terminal.
Treat it as a repeatable routine rather than a one-off, and every server you spin up starts from a secure baseline instead of an open one.
A hardened SSH daemon is the foundation of a secure server. If you want a platform where you get full root access on fast NVMe VPS plans to apply all of this, take a look at Nxeon VPS hosting and our security overview.