# SSH hardening checklist

> A short list of SSH settings worth changing on a new server, with one drop-in file for Ubuntu 24.04 and Debian 12 and a safe way to apply it.

Source: https://vpsnine.com/help/ssh-hardening-checklist · Updated: 2026-10-10

A few SSH settings shut the ways in that bots try and leave the one you use. Do this after [SSH keys work](https://vpsnine.com/help/ssh-keys), because the first thing it does is turn passwords off.

## Before you start

Make sure you can log in with your key from a second terminal. If you're planning to stop logging in as root, create your normal user with `sudo` and copy your key to it first (step 4 of the [first-hour checklist](https://vpsnine.com/help/first-hour-checklist)).

And keep your current session open until the very end. If a change locks you out, that session is your way back in.

## The settings

All of it goes in one drop-in file. OpenSSH keeps the first value it reads for each setting and reads `sshd_config.d` in name order, so the `10-` prefix puts yours ahead of whatever the image ships, like `50-cloud-init.conf`. If you made `10-hardening.conf` in the SSH keys guide, this replaces it:

```bash
cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
AllowUsers root deploy
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowAgentForwarding no
EOF
```

What each line buys you: no passwords of any kind; root only with a key; only the named users can log in at all; three tries per connection and 30 seconds to finish logging in; and no X11 or agent forwarding, which you probably don't use.

Adjust before you apply:

- **`AllowUsers`** must list every account that logs in over SSH. Anyone missing is refused, even with a good key. This is the line that locks people out, so read it twice.
- **`PermitRootLogin`**: once you're happily logging in as `deploy` and using `sudo`, change it to `no` and take `root` out of `AllowUsers`.
- **`AllowAgentForwarding`**: set it to `yes` if you forward your agent to reach Git or other servers.
- **`MaxAuthTries 3`**: if your SSH agent holds lots of keys, it can use up the tries before it offers the right one. Fix that on your side with `IdentitiesOnly yes` and an `IdentityFile` for this host in `~/.ssh/config`.

## Apply it

Test, then reload. A syntax error stops the reload, and existing sessions are never dropped either way:

```bash
sshd -t && systemctl reload ssh
sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin|allowusers|maxauthtries)'
```

Now open a **new** terminal and log in. Only close the old session once that works.

## The rest of the list

- A firewall that allows SSH and the services you run, nothing else: [Set up a firewall with ufw](https://vpsnine.com/help/firewall-with-ufw).
- Something to ban the persistent guessers: [fail2ban](https://vpsnine.com/help/fail2ban).
- OpenSSH kept patched without you thinking about it: [Install security updates automatically](https://vpsnine.com/help/automatic-security-updates).

## Changing the port

It cuts the log noise. It isn't security, though; scanners find the new port soon enough. If you do it anyway, allow the new port in the firewall first (`ufw allow 2222/tcp`) and keep a session open. On Ubuntu 24.04, SSH starts through socket activation, so after changing `Port` run `systemctl daemon-reload` and `systemctl restart ssh.socket`; a plain reload won't move it. Keys plus fail2ban serve most people better.

If you do lock yourself out, fix it from the [serial console](https://vpsnine.com/help/serial-console): log in there, fix or delete `/etc/ssh/sshd_config.d/10-hardening.conf`, and run `systemctl reload ssh`.
