SSH hardening basics: keys, no root login and fail2ban

SSH is the door to your server, and bots knock on it all day. A few settings make it far harder to break in.

A server door with a key and a guard

SSH is how you log in to a server remotely. Any server with a public IP receives constant automated login attempts, so securing SSH is one of the first jobs after you create a server.

1. Use SSH keys, not passwords

A key pair has a private key (stays on your computer, never shared) and a public key (placed on the server).

ssh-keygen -t ed25519 -C "you@example.com"      # create a key pair; use a passphrase
ssh-copy-id user@server                          # install the public key on the server

Protect the private key file (chmod 600) and use a passphrase, so a stolen laptop does not give away the server.

2. Edit the SSH server settings

Edit /etc/ssh/sshd_config (or a file in /etc/ssh/sshd_config.d/). Useful settings:

PasswordAuthentication no        # keys only
PermitRootLogin no               # log in as a normal user, then use sudo
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
AllowUsers deploy admin          # only these users may log in
X11Forwarding no

Check the file, then reload:

sudo sshd -t                     # test the configuration
sudo systemctl reload ssh        # the service is "sshd" on some systems

3. Do not lock yourself out

  • Keep your current session open while you test.
  • Open a second terminal and confirm you can log in with your key before closing the first one.
  • Make sure your public key is installed and your user has sudo rights before disabling passwords and root login.
  • If you are on a cloud provider, know how to reach the web console as a rescue.

4. Use a firewall

Allow only the ports you need. For example with ufw:

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable

Allow SSH before enabling the firewall. If you have a fixed IP, restrict SSH to it. Many cloud firewalls (security groups) can do this too.

5. Slow down attackers with fail2ban

fail2ban reads logs and temporarily blocks IPs that fail to log in many times.

sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

With keys only, password guessing cannot succeed, but fail2ban cuts noise and load.

6. Other good habits

  • Keep the system updated (security updates, automatic if possible).
  • Use one key per person and device, and remove keys of people who leave (~/.ssh/authorized_keys).
  • Consider two-factor for SSH or access through a VPN or bastion host.
  • Changing the port from 22 reduces log noise but is not real security. Keys and a firewall are what matter.
  • Review login activity with last and journalctl -u ssh.
  • Never share private keys, and never paste them into chat or a repository.

Quick checklist

  • Keys only, passwords off.
  • Root login off, named users with sudo.
  • AllowUsers set.
  • Firewall on, only needed ports open.
  • fail2ban running.
  • Updates on, old keys removed.
  • Tested from a second terminal.

Takeaway: keys instead of passwords, no root login, a firewall and fail2ban stop most attacks on SSH, and testing in a second terminal keeps you from locking yourself out.


Linux & DevOps series, Part 1 (servers and containers): 5 of 5. Previous: Docker basics: images, containers and a first Dockerfile.

Keep reading