SSH is the most attacked service on any public server, and it is also the one that is easiest to close properly. Almost all of the risk comes from one thing: passwords. Remove them and the attempts continue and stop mattering.
The configuration
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers sara deploy
sudo sshd -t && sudo systemctl reload ssh
Before you reload: have a key that works, and a second terminal already logged in. Set PasswordAuthentication no with no key installed and you have locked yourself out of your own server - the provider console is then the only way back.
Line by line
- PermitRootLogin no - work as a named user with sudo. See users, sudo and never working as root.
- PasswordAuthentication no - the single most valuable line here.
- KbdInteractiveAuthentication no - closes the second password path people forget, which quietly keeps passwords working.
- AllowUsers - an explicit list. A new system account created by a package cannot log in.
Restrict where it answers
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw deny 22/tcp
If a fixed office address is not possible, Fail2ban is the fallback - see what Fail2ban stops. Moving the port is cosmetic; see changing the SSH port.
Check what you ended up with
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers'
sshd -T prints the effective configuration, including anything set in an Include file further down. It is the only reading that accounts for a distribution dropping a file into sshd_config.d and overriding you.