A server straight from the provider answers to root with a password, on port 22, to the whole internet. Within the hour, bots are trying passwords. This page closes those doors in five steps, each one verified before the next.
Before you start
$ssh-keygen -t ed25519 -C "@laptop"$cat ~/.ssh/id_ed25519.pubssh-ed25519 AAAA… @laptop
| What | Before | After this page |
|---|---|---|
| Who can log in | root, anyone with the password | , with a key |
| Port | 22 | |
| Wrong passwords | unlimited | 3, then banned for an hour |
Create your own user
$ssh root@$adduser $usermod -aG sudo $rsync --archive --chown=: ~/.ssh /home/$ssh @ sudo -n true && echo OKOK
If sudo asks for a password
Debian and Ubuntu grant password-less sudo to nobody by default; sudo -n then fails. Either type the password (fine), or allow the group without password:
$echo '%sudo ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/90-sudo-nopasswdDo this only if the account is protected by a key, which is what the next step enforces.
Harden the SSH daemon
Port PermitRootLogin noPasswordAuthentication noKbdInteractiveAuthentication no$sudo sshd -t && echo syntax OKsyntax OK
Firewall
$sudo apt install -y ufw$sudo ufw allow /tcp$sudo ufw enable$sudo ufw statusStatus: active /tcp ALLOW Anywhere
Now restart SSH and, from a second terminal, log in on the new port:
$sudo systemctl restart ssh$ssh -p @ echo connectedconnected
If the new connection fails
Your first terminal is still logged in: nothing is lost. In order of likelihood:
- The firewall does not list
: re-run the firewall step. sshd -treports an error: fix the drop-in, restart again.- The provider has its own network firewall in front of the server (common at OVH, Hetzner, cloud providers): open the port there too.
- You are testing from the first terminal by mistake: use a new one.
Ban brute force
$sudo apt install -y fail2ban[sshd]enabled = trueport = maxretry = 3bantime = 1h$sudo systemctl enable --now fail2ban$sudo fail2ban-client status sshd | head -3Status for the jail: sshd |- Filter | |- Currently failed: 0
If you ban yourself
Three typos in a row from your own address and you are out for an hour. From another address (phone hotspot, the provider's console), unban yourself:
$sudo fail2ban-client set sshd unbanip To never ban your office or home, add ignoreip = 203.0.113.0/24 to the jail.
Done
Root is locked out, passwords are refused, the port is off the beaten path, and repeat offenders are banned. From now on you connect with:
$ssh -p @