What you need first
Complete the SSH key and sudo guides first. You must be able to log in with a key as a non-root account and run sudo before you disable anything. If you cannot, this guide will lock you out.
Keep your current SSH session open throughout, and make sure you can reach your provider's recovery console. Changes below are tested before they are applied and are confirmed from a second terminal.
sudo sshd -T | grep -Ei "^(passwordauthentication|permitrootlogin|pubkeyauthentication|kbdinteractiveauthentication|port) "Write a hardening drop-in file
Modern OpenSSH reads files in /etc/ssh/sshd_config.d/ at the top of the main configuration. OpenSSH uses the first value it sees for each setting, so name your file with a low number such as 00-hardening.conf. Provider images often include a later file, such as 50-cloud-init.conf, that turns password login back on, and the earlier file wins.
This file disables password and keyboard-interactive login, forbids direct root login and limits attempts per connection.
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf >/dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
EOF
sudo sshd -t && echo "Configuration OK"Check what OpenSSH will actually use
The sshd -T command prints the effective configuration after reading every file. Check that each setting shows the value you expect. If passwordauthentication still says yes, another file is overriding yours; find it with grep.
sudo sshd -T | grep -Ei "^(passwordauthentication|permitrootlogin|kbdinteractiveauthentication|maxauthtries) "
sudo grep -ri "PasswordAuthentication" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/Reload and test from a second terminal
Reloading applies the configuration without ending existing sessions. The service is called ssh on Ubuntu and sshd on AlmaLinux. Then open a new terminal on your own computer and log in with your key. Also confirm that a password login is refused.
sudo systemctl reload sshsudo systemctl reload sshdssh deploy@YOUR_SERVER
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password deploy@YOUR_SERVERInstall Fail2ban
Fail2ban watches logs and temporarily bans addresses that repeatedly fail to log in. With password login off it mostly reduces log noise and load from bots, which still matters on a small VPS. On Ubuntu it is in the main archive. On AlmaLinux it comes from the EPEL repository, and the fail2ban-firewalld package connects it to firewalld.
sudo apt update
sudo apt install fail2bansudo dnf install epel-release
sudo dnf install fail2ban fail2ban-firewalldConfigure the SSH jail
Never edit jail.conf, which package updates replace. Create /etc/fail2ban/jail.d/sshd-local.conf instead. This bans an address for one hour after five failures within ten minutes and reads from the systemd journal, where both distributions log SSH. Add your own fixed IP address to ignoreip if you have one, so a typing mistake cannot ban you.
Fail2ban must ban the port actually used by SSH. The default ssh service name means port 22; the commands below read the effective configured port instead.
SSH_PORT=$(sudo /usr/sbin/sshd -T | awk '/^port /{print $2;exit}')
sudo tee /etc/fail2ban/jail.d/sshd-local.conf >/dev/null <<EOF
[sshd]
port = $SSH_PORT
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
# ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client reloadsudo fail2ban-client status
sudo fail2ban-client status sshdUnban yourself and review bans
If you ban your own address, use the recovery console or another network, then remove the ban. List the failures that led to it in the journal. Keep bantime modest at first; repeated offenders can be handled later with the recidive jail.
sudo fail2ban-client set sshd unbanip 203.0.113.50sudo journalctl -u ssh -u sshd --since "1 hour ago" --no-pager | grep -i "failed" | tailOfficial documentation
These upstream references provide more detail on the commands and workflows in this guide.