Installing fail2ban to block login attacks

Every server on the internet gets a steady stream of login attempts from bots. Fail2ban watches your logs, and when one address fails to log in too many times, it blocks that address in the firewall for a while. It is small, free and quick to set up.

This guide installs fail2ban on Ubuntu or Debian, protects SSH, adds protection for websites, and shows how to check, test and undo bans. An honest note first: if your SSH already accepts keys only, fail2ban will not stop a break-in there, because a key cannot be guessed. It still cuts log noise and wasted CPU, and it is genuinely useful for web logins, which often do use passwords.

Low-cost VPS plans in stock right now

In stock when this page loaded. See all 20 matching plans

What is in this guide

A few words you will see

TermWhat it means
JailOne set of rules in fail2ban, such as "watch SSH logins and ban after five failures".
FilterThe pattern fail2ban looks for in a log to spot a failed login.
BanA firewall rule that blocks one IP address for a set time.
bantimeHow long a ban lasts.
findtimeThe time window in which failures are counted.
maxretryHow many failures within findtime trigger a ban.
ignoreipAddresses that are never banned, such as your own.

How fail2ban works

  1. It reads log files, or the system journal, as new lines arrive.
  2. Each jail's filter looks for lines that mean a failed login, and notes the address.
  3. If one address fails maxretry times within findtime, fail2ban adds a firewall rule blocking it.
  4. After bantime, the rule is removed automatically.

It only knows about services whose logs it reads, and only blocks the addresses that attack. It is one layer among several, not a replacement for keys, updates and a firewall. A beginner's guide to securing your VPS covers the rest.

Before you start

  • A VPS running Ubuntu or Debian, with SSH keys set up. See how to connect with SSH and set up SSH keys.
  • Your own public IP address, so you can tell fail2ban never to ban it. Search "what is my IP" in your browser to find it. If your home address changes often, skip that line and rely on the control panel console if you lock yourself out.
  • Access to the console in the VPS control panel, as a backup way in.

1. Install fail2ban

sudo apt update
sudo apt install fail2ban python3-systemd

python3-systemd lets fail2ban read the system journal, which matters on systems that do not keep a separate login log file.

2. Create your own settings file

Never edit jail.conf: updates replace it. Put your settings in jail.local, which overrides it and survives updates:

sudo nano /etc/fail2ban/jail.local

Put this in it, replacing YOUR_IP with your own address, or removing it:

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

[sshd]
enabled = true
backend = systemd

This bans an address for an hour after five failures within ten minutes. backend = systemd tells the SSH jail to read the system journal, which works whether or not your system keeps a separate login log file.

Fail2ban adds its bans through the system's firewall tools and works alongside UFW without extra setup.

3. Start it and check SSH protection

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

The first status command lists active jails. The second shows how many failures the SSH jail has seen and which addresses are banned now. On a server that has been online for a while, you may see bans within minutes.

4. Protect your websites

Fail2ban includes filters for many common services. Turn on the ones that match what you run by adding sections to jail.local. Only enable jails for software you actually use, or fail2ban may fail to start because the log file it expects does not exist.

You runJail to enableWhat it catches
nginx with password-protected areasnginx-http-authFailed basic-auth logins
nginxnginx-botsearchBots probing for common weak pages
Apache with password-protected areasapache-authFailed basic-auth logins
Apacheapache-badbotsKnown bad crawlers

For example, for nginx:

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

Restart with sudo systemctl restart fail2ban after any change, and check sudo fail2ban-client status lists the new jails.

WordPress and other apps log failed logins inside the app, not in the web server's log, so the built-in filters cannot see them. A login-limiting or security plugin is usually the simpler answer. Some plugins can also write failed logins to the system log for fail2ban to read, with a matching filter. Follow the plugin's own documentation if you go that way. See installing WordPress on a VPS.

5. Ban repeat offenders for longer

Some addresses come back as soon as their ban ends. The recidive jail watches fail2ban's own log and gives repeat offenders a much longer ban, a week by default. Add it to jail.local:

[recidive]
enabled = true

Restart fail2ban. Be careful with ignoreip before enabling this: banning yourself for a week is inconvenient, though the control panel console still works.

1 GB and 2 GB VPS plans in stock

In stock when this page loaded. See all 7 matching plans

6. Check, test and undo bans

What you wantCommand
List active jailssudo fail2ban-client status
See bans in one jailsudo fail2ban-client status sshd
Unban an addresssudo fail2ban-client set sshd unbanip 203.0.113.5
Ban an address by handsudo fail2ban-client set sshd banip 203.0.113.5
Read fail2ban's own logsudo tail -n 50 /var/log/fail2ban.log
Check settings for mistakessudo fail2ban-client -t

The address 203.0.113.5 is an example from a range kept for documentation. To check that a filter matches a log, test it without banning anyone:

sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf

It reports how many lines matched. Zero matches on a log you know contains failures means the filter and log do not fit.

Troubleshooting

SymptomLikely causeFix
fail2ban will not startA typo in jail.local, or a jail for a log file that does not existRun sudo fail2ban-client -t and sudo journalctl -u fail2ban -n 30, then fix or disable that jail
SSH jail shows no failures at allIt is not reading the right logCheck backend = systemd and that python3-systemd is installed
You banned yourselfToo many wrong logins from your addressLog in from the control panel console and run the unban command
A web jail never bans anyoneThe filter does not match your log formatTest with fail2ban-regex as in step 6
A banned address still gets throughIt was already connected, or fail2ban's firewall action does not suit your systemBans block new connections, not ones already open. Check /var/log/fail2ban.log for errors when a ban is added
Real users get bannedLimits too strict, or many users share one addressRaise maxretry, shorten bantime, or add their address to ignoreip

Limits

  • It does not replace SSH keys. Keys stop password guessing completely. Fail2ban only slows it down.
  • Large networks of attackers get around it. Bots that use thousands of addresses, each trying only a few times, stay under the limit.
  • It only sees what is logged. Apps that log failures in their own databases need their own protection.
  • It uses some memory and CPU. Usually modest, but on a very busy site with large logs, keep the number of jails sensible. On a 512 MB plan, protect SSH and skip the rest unless you need it.
  • Bans are not a firewall policy. Keep UFW set to deny everything you have not opened. See securing your VPS.

When to step up

Fail2ban runs happily on any plan. If you find it constantly busy with a popular site under heavy bot traffic, a content delivery network in front of the site can filter much of that traffic before it reaches your server. If your server is short of memory because of the apps it runs, see how to read VPS specs before choosing a bigger plan.

2 GB and 4 GB VPS plans in stock, for busier websites

In stock when this page loaded. See all 6 matching plans

What next

To compare what is available now, start with the cheapest RackNerd VPS guide and check the sales page.

More RackNerd guides