Hardening sshd

Port 22 on a public address is probed by password-guessing bots around the clock. Once your key works, turn passwords off, refuse root and name who may log in, in a drop-in file that package upgrades never touch:

/etc/ssh/sshd_config.d/10-harden.confShell
PermitRootLogin no
PasswordAuthentication no
AuthenticationMethods publickey
AllowGroups sshusers
MaxAuthTries 3
X11Forwarding no
Match User deploy
  AllowTcpForwarding no
  PermitTTY no

sshd_config starts with Include /etc/ssh/sshd_config.d/*.conf, and sshd keeps the first value it reads for each keyword, so 10-harden.conf beats both the main file and the 50-cloud-init.conf that some cloud images use to re-enable passwords (one was in place below, and lost). Run sshd -t before every reload:

Validating the drop-in and reading the effective settingsShell
sudo sshd -t                      # 11-typo.conf contains "PasswordAuthentcation no"
sudo rm /etc/ssh/sshd_config.d/11-typo.conf && sudo sshd -t && echo "config OK"
sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|maxauthtries|allowgroups) '
sudo sshd -T -C user=deploy,host=pc1,addr=192.0.2.10 | grep -E '^(allowtcp|permittty)'
sudo systemctl reload ssh
ssh -o PubkeyAuthentication=no bk3ssh@localhost true
Output
/etc/ssh/sshd_config.d/11-typo.conf: line 1: Bad configuration option: PasswordAuthentcation
/etc/ssh/sshd_config.d/11-typo.conf: terminating, 1 bad configuration options
config OK
maxauthtries 3
permitrootlogin no
passwordauthentication no
allowgroups sshusers
permittty no
allowtcpforwarding no
bk3ssh@localhost: Permission denied (publickey).

sshd -T prints every effective setting and -C evaluates Match blocks for a hypothetical connection; Ubuntu 225 's defaults were permitrootlogin prohibit-password, passwordauthentication yes and maxauthtries 6. AllowGroups locks out anyone outside sshusers, so add yourself first (sudo usermod -aG sshusers bk3ssh) and keep one session open until a fresh login works. ssh.socket owns port 22 on Ubuntu, so a new Port needs sudo systemctl daemon-reload && sudo systemctl restart ssh.socket, after opening it in ufw 280 and the security group (Opening 80 and 443 with ufw and Cloud Security Groups). Since OpenSSH 9.8 23,707 , PerSourcePenalties (on by default) temporarily refuses addresses that keep failing; fail2ban 18,687 adds firewall bans.