Skip to content
Launch offerNew accounts: we double your first deposit of $100 or more, up to $250 bonus.Claim my bonus
LiteKeep
Sign inDeploy a server

Step-by-step tutorial, 2026

SSH hardening, done in the right order. Tested on our own server.

We hardened our own server with exactly these steps. In the 24 hours before, it logged 821 failed password guesses. In the hours after: none.

  • 14 min read
  • 9 chapters
  • Updated

24 hours before

  • Failed passwords821
  • of which for root539
  • Unknown users183

00-hardening.conf

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers deploy

After

0 password guesses

Bots still connect. Nothing left to guess.

The short answer

Put four lines in a file called /etc/ssh/sshd_config.d/00-hardening.conf: PermitRootLogin no, PasswordAuthentication no, KbdInteractiveAuthentication no and AllowUsers you. Check it with sudo sshd -t, reload with sudo systemctl reload ssh, and test a new login before you close your session.

The 00- name matters: SSH uses the first value it reads, and other files can quietly override your edits. Confirm the result with sudo sshd -T, or paste it into our free checker.

Our own server was taking a password guess every couple of minutes. In one day: 821 failed passwords, 539 of them for root.

So we did what this tutorial describes. In the first hours after, not one password was tried, because the server no longer accepts passwords at all. Bots connect, see that only keys work, and leave.

Here’s the trap we nearly fell into. The server’s image shipped two extra SSH config files that switch passwords and root login on. Edit the main file, and nothing changes. Most tutorials never mention this, and most skip the way newer Ubuntu starts SSH, which is why so many port changes on 24.04 seem to do nothing.

This guide walks through it in the order that can’t lock you out, with the checks we used ourselves.

In this guide you’ll learn

  • The four settings that matter, and the one-file way to set them
  • A free checker: paste sshd -T, see what your server really allows
  • Why your edit may do nothing, and how drop-in files win
  • A safety net that undoes a bad change by itself
  • Changing the SSH port on Ubuntu 22.04 and 24.04, socket activation included
  • fail2ban and ufw limit, and what they add

Chapter 1

The short answer

These four settings do most of the work. Each is a keyword in sshd_config.

The SSH settings that matter
SettingSet toWhat it stops
PasswordAuthenticationnoAll password guessing
KbdInteractiveAuthenticationnoPassword prompts by another route
PermitRootLoginnoLogins as root, the most guessed account
AllowUsersyour userLogins as any other account

Before you start: log in with an SSH key as your own user with sudo. If you haven’t yet, follow our SSH keys tutorial and the user steps in the VPS security guide.

Starting fresh? Deploy a Lite 2 with your public key added at deploy, and you can apply all four settings in its first five minutes. It bills by the hour, and the web console is there if a setting goes wrong.

Chapter 2

Check what your server really allows

sudo sshd -T prints the settings SSH actually uses, after reading every config file. Paste it below. The checker flags what’s open and writes the fix.

No server handy?

Paste your sshd -T output on the left.

Click “Load our server’s old settings” to see what our server looked like before: two red flags, both from the image’s own files.

Chapter 3

What changed on our server

We counted login attempts in our server’s SSH log for the day before the change and the first hours after.

Our server's SSH log, before and after (October 2026)
24 hours beforeFirst 1 h 49 min after
Failed password guesses8210
of which for root5390
Logins for users that don’t exist18315
Refused by AllowUsersnot set81

The bots didn’t stop knocking. What changed is that they can’t try a password any more: the server offers only key login, and every account except ours is refused before it gets that far. fail2ban, which bans repeat offenders, had banned 193 addresses since the server last started.

Chapter 4

Why your edit may do nothing

Modern Ubuntu reads extra files from /etc/ssh/sshd_config.d/, and two rules decide who wins.

  • The first value wins. For each keyword, SSH uses the first value it reads and ignores the rest.
  • Drop-ins come first. Settings in sshd_config.d override those in the main configuration file. Files there are read in name order.

Our server’s image came with two drop-ins of its own, a 00- and a 99- file, both with PasswordAuthentication yes. Cloud images often add a file through cloud-init too, which controls password login with its ssh_pwauth setting. Any of these beats a change at the bottom of sshd_config.

$ sudo sshd -T | grep -Ei "^(permitrootlogin|passwordauthentication|allowusers) "
permitrootlogin no
passwordauthentication no
allowusers deploy
With 00-hardening.conf named so it sorts first, sshd -T shows our settings won.

Chapter 5

Lock it down without locking yourself out

Do this from a session that’s already logged in with your key. Don’t close it until the last step.

  1. Arm a safety net

    This undoes the change by itself in 3 minutes unless you cancel it:

    sudo systemd-run --on-active=180 --unit=ssh-rollback \
      sh -c 'rm -f /etc/ssh/sshd_config.d/00-hardening.conf; systemctl reload ssh'
  2. Write the drop-in

    sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
    PermitRootLogin no
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    AllowUsers maria
    EOF
  3. Test the config, then reload

    sudo sshd -t && sudo systemctl reload ssh

    sshd -t prints nothing when the config is valid. A reload keeps your current session.

  4. Open a new session

    From your PC, in a new window, log in with your key. If it fails, wait: the safety net puts things back.

  5. Verify, then cancel the safety net

    sudo sshd -T | grep -Ei "^(permitrootlogin|passwordauthentication|allowusers) "
    sudo systemctl stop ssh-rollback.timer

Chapter 6

Root login: no, or prohibit-password?

PermitRootLogin takes four values: yes, prohibit-password, forced-commands-only or no.

  • OpenSSH’s own default is prohibit-password: root can log in with a key, never a password. Some server images change it to yes, as the one we tested did.
  • no is safer still: log in as yourself and use sudo. Every root guess then fails before it starts.

MythRoot login is open by default in SSH.

Fact

Not in OpenSSH: the default is prohibit-password. It’s some server images and old configs that open it.

MythAllowUsers is enough on its own.

Fact

It limits who can try. Passwords off is what makes guessing pointless. Use both.

Chapter 7

Changing the SSH port

Moving SSH off port 22 cuts the noise in your logs. It isn’t security on its own: anyone who scans properly still finds the new port. Keys are what keep attackers out.

If you still want to, the order matters, and Ubuntu changed how it works in 22.10.

  1. Open the new port first

    sudo ufw allow 2222/tcp
  2. Set the port

    echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/00-port.conf
    sudo sshd -t
  3. Ubuntu 22.04: restart the service

    sudo systemctl restart ssh
  4. Ubuntu 22.10 and later (24.04): restart the socket

    Since 22.10, SSH starts from a systemd socket. After changing Port, run daemon-reload, then restart ssh.socket:

    sudo systemctl daemon-reload
    sudo systemctl restart ssh.socket
  5. Test, then close port 22

    In a new window: ssh -p 2222 you@server. Only when that works:

    sudo ufw delete allow 22/tcp

Chapter 8

fail2ban and ufw limit

With passwords off, guessing can’t succeed. These two tools cut the noise and the load.

  1. ufw limitHow to check: sudo ufw limit 22/tcp denies an address that makes 6 or more connections within 30 seconds.
  2. fail2ban sshd jailHow to check: fail2ban reads the log and bans repeat offenders for a while. Its jails are off until you enable them; the sshd jail is the one you want.
  3. Watch the effectHow to check: sudo fail2ban-client status sshd shows current and total bans. Ours had banned 193 addresses.
  4. Moved the port?How to check: Tell the jail: set port = 2222 under [sshd] in /etc/fail2ban/jail.local, or bans block port 22 only.

Chapter 9

If you do lock yourself out

With the safety net, a mistake fixes itself in three minutes. Without it, you need a way in that doesn’t use SSH.

  • Open your server’s web console. Every LiteKeep server has one on its page in your account. Log in there and delete or fix 00-hardening.conf, then sudo systemctl reload ssh.
  • Read the log to see why: sudo journalctl -u ssh -n 50. Our Permission denied guide decodes every line.

Now it’s your move

SSH hardening is four lines in the right file, done in the right order. The bots will keep knocking; they just won’t have anything to guess.

New server? A Lite bills by the hour, so practising this costs cents. Deploy a Lite 2, lock it down in ten minutes, and keep the web console as your safety net.