How to block SSH password guessing with Fail2ban on Ubuntu or Debian

Every server on the internet gets a steady stream of bots guessing SSH passwords. Fail2ban watches for failed logins and blocks an address after a few tries.

First things first: Fail2ban slows attackers down, it doesn't replace good locks. Use SSH keys and turn off password login first. Fail2ban then keeps the noise down and blocks bots before they try anything else.

1. Install Fail2ban

sudo apt update
sudo apt install fail2ban

On Ubuntu and Debian it comes ready to protect SSH. It starts on its own and stays on after a restart.

2. Make your own settings file

Don't edit /etc/fail2ban/jail.conf: updates replace it. Put your changes in /etc/fail2ban/jail.local instead:

sudo nano /etc/fail2ban/jail.local

Paste this:

[DEFAULT]
# Block for 1 hour after 5 failed tries within 10 minutes
bantime = 1h
findtime = 10m
maxretry = 5
# Block repeat visitors for longer each time, up to one week
bantime.increment = true
bantime.maxtime = 1w
# Never block these: the server itself and your own address
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

[sshd]
enabled = true

Replace 203.0.113.10 with the address you connect from (search "what is my IP" if you're not sure). If it changes often, leave it out. You can always unban yourself from the hosting provider's web console.

SSH on another port? Add port = 2222 (your port) under [sshd]. Otherwise Fail2ban blocks port 22 only, and the attacker can keep going.

Debian 12 only: its Fail2ban looks for a log file that Debian 12 no longer writes, so it won't start (Debian bug 1037437). Ubuntu 24.04 and Debian 13 are fine. On Debian 12, also run sudo apt install python3-systemd nftables and add these lines to jail.local: under [DEFAULT], banaction = nftables and banaction_allports = nftables[type=allports]; under [sshd], backend = systemd.

3. Check the file and apply it

sudo fail2ban-client -t
sudo systemctl restart fail2ban

The first command should end with OK: configuration test is successful. If it shows an error, it names the line to fix.

4. See it working

sudo fail2ban-client status sshd

You'll see how many failed logins it has counted and which addresses are blocked right now.

Everyday commands

  • All blocked addresses: sudo fail2ban-client banned
  • Unblock an address: sudo fail2ban-client set sshd unbanip 203.0.113.10
  • What Fail2ban did and when: sudo tail -n 50 /var/log/fail2ban.log

If you block yourself

Wait for the ban to end (one hour with the settings above), or connect from another network, such as your phone's hotspot, and unban your address. If neither works, log in through your hosting provider's web console and run the unblock command there.

Good to know

  • It works with UFW. Fail2ban adds its own small block list in front of your firewall rules. You don't need to change anything in UFW.
  • It can protect more than SSH. It comes with ready-made rules for many services, for example Nginx, Apache and mail servers. Each is turned on with its own section in jail.local. Start with SSH and add others once you know what you need. For WordPress logins, see step 8 of our WordPress hardening guide.
  • Behind Cloudflare or another proxy? Blocking website visitors by address won't work there, because the server sees the proxy's address, not the visitor's. SSH isn't affected. For websites, Nginx rate limiting works there instead.

Official sources

Next steps: turn on automatic security updates, then work through the security checklist for a new PHP server.

ServerNest is being built to do many of these steps for you, with safe defaults. Join early access to try it first.

← Back to the security blog