Chapter 2 of 7 · 7 checks · 4 min
SSH
Checks on the front door: key-only logins, no root, a tested configuration and as little exposure as possible.
SSH accepts keys only: password and keyboard-interactive logins are offMust
Why it matters and how to check
Any server with SSH open to the internet receives constant password guessing. The OpenSSH defaults for
PasswordAuthenticationandKbdInteractiveAuthenticationare bothyes, so you have to turn them off yourself. With keys only, guessing has nothing to guess.To verify: print the effective configuration with
sudo sshd -Tand check thatpasswordauthentication noandkbdinteractiveauthentication noappear. From another machine, tryssh -o PubkeyAuthentication=no user@server. It must fail withPermission denied (publickey)and never offer a password prompt.Example
Shell # /etc/ssh/sshd_config.d/10-hardening.conf PasswordAuthentication no KbdInteractiveAuthentication no PermitRootLogin no PermitEmptyPasswords no sudo sshd -T | grep -Ei 'passwordauthentication|kbdinteractive|permitrootlogin'Root cannot log in over SSHMust
Why it matters and how to check
The OpenSSH default for
PermitRootLoginisprohibit-password, which still allows root to log in with a key. Some cloud images add root keys at boot. Set it tonoso every session starts as a named user and escalates withsudo.To verify:
sudo sshd -T | grep permitrootloginshould printpermitrootlogin no. Then tryssh root@serverfrom your machine: it must be refused even if a key exists in/root/.ssh/authorized_keys. Empty that file too, so turning the setting back on by accident does not reopen access.SSH changes go in a drop-in file and are tested before restartMust
Why it matters and how to check
On Ubuntu, the main
sshd_configincludes/etc/ssh/sshd_config.d/*.confat the top, and OpenSSH uses the first value it finds for most options. That means a drop-in wins over the main file, and a cloud image's own drop-in can silently override your setting. The Ubuntu docs warn that an invalid directive can stopsshdfrom starting and lock you out.To verify: put your settings in one file such as
10-hardening.confand list the directory for others that conflict. Runsudo sshd -tbefore every restart; it must print nothing. Keep your current session open, restart withsudo systemctl restart ssh(sshdon RHEL), and confirm a new login works from a second terminal before closing the first.Example
Shell ls /etc/ssh/sshd_config.d/ sudo sshd -t && sudo systemctl restart ssh # open a NEW terminal and log in before closing the old oneOnly members of a named group can log in over SSHShould
Why it matters and how to check
By default any account with a valid key or shell can log in over SSH, including service accounts that should never be used interactively.
AllowGroupsturns this into an allowlist: only members of the listed groups can connect, and new system accounts are excluded automatically.To verify: create a group such as
sshusers, add each admin, and setAllowGroups sshusersin your drop-in. Runsudo sshd -T | grep allowgroups. Try to log in as an account outside the group (for example a test user with a key): it must be refused, andjournalctl -u sshshould show the denial.Admin keys are Ed25519, passphrase protected, and authorized_keys is not writable by othersShould
Why it matters and how to check
The Ubuntu docs recommend Ed25519 keys (or 4096-bit RSA) and a passphrase on the private key, with an agent so you do not retype it. An
authorized_keysfile that group or others can write lets another local user add their own key to your account.To verify: check each key type in
authorized_keys; it should start withssh-ed25519orsk-ssh-ed25519for hardware keys, notssh-dssor short RSA keys. Runls -l ~/.ssh/authorized_keysand confirm it is not group or world writable (chmod go-wfixes it). Ask each admin to confirm their private key has a passphrase.Example
Shell ssh-keygen -t ed25519 -C "alice@laptop" ssh-copy-id -i ~/.ssh/id_ed25519.pub alice@server chmod go-w ~/.ssh ~/.ssh/authorized_keysSSH is reachable only from known networks, or not exposed at allShould
Why it matters and how to check
Key-only SSH is strong, but every exposed service is something that can have a vulnerability. Limit who can reach port 22: a cloud firewall or security group that allows only your office or VPN range, a bastion host, or a tool such as a cloud provider's session manager that needs no inbound port at all.
To verify: from a network outside your allowlist (a phone hotspot works), run
nc -zv server 22. It should time out. In the cloud console, check the inbound rules for port 22 and confirm none allow0.0.0.0/0or::/0. Recent OpenSSH also appliesPerSourcePenaltiesby default, which temporarily refuses sources that keep failing; leave it on.Unused SSH features such as forwarding and version banners are turned offNice to have
Why it matters and how to check
Agent forwarding, TCP forwarding and X11 forwarding are useful on some hosts and unnecessary on most app servers. The OpenSSH default for
AllowTcpForwardingisyes. On Ubuntu,DebianBanner nostops the server announcing its exact OS version before login, which the Ubuntu docs suggest. A lowerMaxAuthTriesthan the default of 6 also reduces noise.To verify: in
sudo sshd -T, checkallowtcpforwarding no,allowagentforwarding no,x11forwarding noand, on Ubuntu,debianbanner no, unless you have written down a reason to keep one. Runnc server 22and read the banner line that comes back.Example
Shell # /etc/ssh/sshd_config.d/10-hardening.conf (continued) AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no MaxAuthTries 3 DebianBanner no # Ubuntu and Debian only