Harden the SSH server

Hardening runbook. Closes the most common remote entry point: SSH exposed with password authentication, root login, and default settings. The aim is a server that cannot be brute-forced and that only the intended people can reach.

When to run

On every new server during initial setup. On an existing server that still accepts password authentication or root login. After any change to who needs SSH access.

Before starting

Working SSH key access for at least one admin account. Confirm a key login succeeds before disabling passwords:

ssh -i ~/.ssh/your_key adminuser@server-address

If key login does not yet work, set it up first (see key management). Disabling password authentication before keys work locks the server.

Risk

Disabling password authentication without confirmed key access locks everyone out. Keep the existing session open while testing a new one, so there is always a way back in.

Steps

All changes are in /etc/ssh/sshd_config. Edit, then reload at the end.

Disable password authentication

PasswordAuthentication no

Keys cannot be guessed; passwords can. This is the change that removes the brute-force surface.

Disable root login

PermitRootLogin no

Limit who can log in

AllowUsers adminuser deployuser

Only the listed accounts can authenticate. This does not replace strong authentication, but it narrows what an attacker can target.

Disable X11 forwarding

X11Forwarding no

The X11 protocol was not built with security in mind and is rarely needed on a server.

Optional: move off port 22

Port 2200

Port 22 attracts constant automated scanning. Moving the port does not add real security, but it cuts the noise in the logs considerably. If the port is changed, open the new port in the firewall and close 22 before reloading, or the next connection will fail.

Apply

sudo sshd -t && sudo systemctl reload ssh

sshd -t checks the configuration for syntax errors first. A reload with a broken config can drop the SSH daemon; the syntax check guards against it.

Verify

From a separate terminal, keeping the current session open:

ssh adminuser@server-address       # on the new port if changed

Confirm key login works, password login is refused, and root is refused:

ssh -o PreferredAuthentications=password adminuser@server-address   # should be rejected
ssh root@server-address                                             # should be rejected

Done

Key login works for allowed accounts. Password authentication refused. Root login refused. Configuration passes sshd -t. The fallback session was never needed.

Rollback

Revert the changed directives in /etc/ssh/sshd_config and reload. If locked out entirely, use the hosting provider’s console access to edit the file, since SSH is the path that just closed.

Follow-up

  • Add fail2ban for services that still accept passwords (web, mail, admin panels). It does not help SSH once keys are enforced, but it covers what cannot drop passwords.

  • For static-IP admin access, TCP wrappers (/etc/hosts.allow, /etc/hosts.deny) or a firewall rule can restrict SSH to known source addresses.