How to install Fail2ban on Ubuntu to block brute-force attacks

Look at the login log of any server on the public internet and you will see the same thing: hundreds of failed attempts a day from strangers guessing usernames and passwords. Fail2ban watches those logs and, when an address fails too many times, blocks it for a while. It does not replace good security, such as keys instead of passwords, but it cuts noise, reduces load and slows down the persistent.

What Fail2ban does

It reads log files for patterns that mean "someone is trying to break in", counts how often each address triggers them, and when one crosses a limit, it adds a temporary firewall rule banning it. After the ban time, the rule is removed.

It works for SSH out of the box, and for many other services, such as web servers and mail, with extra settings.

Install it

sudo apt update
sudo apt install fail2ban

It starts automatically. Check with:

sudo systemctl status fail2ban

Configure it in a separate file

The main file, /etc/fail2ban/jail.conf, is overwritten when the package updates, so never edit it. Instead, create /etc/fail2ban/jail.local, which overrides it and survives updates:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP

[sshd]
enabled = true

What the settings mean:

  • maxretry is the number of failures that triggers a ban.
  • findtime is the window in which those failures must happen. Five failures within ten minutes means a ban.
  • bantime is how long the ban lasts. Start with an hour, and raise it if attacks keep coming.
  • ignoreip lists addresses that are never banned, such as your own. Add your home or office address, so a typo does not lock you out.

On recent Ubuntu versions, SSH logs go to the system journal, and Fail2ban reads them from there. If it does not detect failures, add backend = systemd under [sshd].

Restart to apply:

sudo systemctl restart fail2ban

Check what it is doing

sudo fail2ban-client status
sudo fail2ban-client status sshd

The second shows how many failures it has seen and which addresses are currently banned. On a public server, you will probably see entries within the hour.

Unban an address

If you get locked out by mistake, from another connection:

sudo fail2ban-client set sshd unbanip 203.0.113.50

If you are completely locked out, use the console in your provider's dashboard, and run the same command. Keep that option in mind, and set ignoreip before you test.

Make bans stricter

For repeat offenders, add the recidive jail, which watches Fail2ban's own log and bans addresses that keep coming back for much longer, such as a week. Add it to jail.local:

[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 3

Protect other services

Fail2ban ships with ready-made filters for many programs, such as nginx-http-auth for password-protected pages and nginx-botsearch for scanners hitting missing pages. Enable them by adding a section with enabled = true. Make sure the log path matches where your service writes its logs.

What Fail2ban cannot do

Be honest about its limits:

  • It does not make weak passwords safe. A guessed password on the first or second attempt gets through. Use keys. See How to set up SSH key authentication.
  • It reacts after the fact. It blocks after failures, rather than preventing them.
  • It is not protection against floods of traffic. Large attacks need other measures. See DDoS attacks explained for server owners.
  • Attackers can change address. Bans slow them but do not stop them.

It is one useful layer, together with a firewall, keys and updates, not a complete defence. Basic security for a new VPS lists the layers, and Set up a firewall on your VPS with UFW covers the firewall.

Check that it keeps working

  • After updates, confirm the service is still running.
  • Look at the status every so often, and check the ban count.
  • If you use a custom SSH port, make sure Fail2ban knows it, with port = YOURPORT in the [sshd] section.

Still stuck? Open a ticket on Discord - run /ticket in any channel, pick a department, and include your Server ID or Invoice ID so we can jump straight in.