How to Install and Configure Fail2Ban on Ubuntu (SSH, Nginx and WordPress Jails)

Overview

To set up Fail2Ban on Ubuntu, install it with apt, put your settings in /etc/fail2ban/jail.local (never in jail.conf), enable the sshd jail, add your own IP to ignoreip, and restart the service. Fail2Ban then watches your logs and blocks any IP that fails to log in too many times in a short window. A basic SSH setup takes about ten minutes.

This guide is for anyone running their own Ubuntu 22.04 or 24.04 VPS or dedicated server. You’ll end up with SSH protection, optional jails for Nginx and WordPress logins, a longer ban for repeat offenders, and the commands to check, test and undo bans. If you haven’t hardened the server yet, start with how to secure your Linux server; Fail2Ban is one layer, not the whole job.

Note: on cPanel servers, use cPHulk (built into WHM) instead of Fail2Ban for login protection, and on Plesk use the built-in IP Address Banning (Fail2Ban) screen under Tools & Settings. This guide is for servers you manage without a control panel.

Prerequisites

  • Ubuntu 22.04 or 24.04 with sudo access.
  • A firewall already set up. See how to configure UFW on Ubuntu.
  • Your own public IP address (search “what is my IP”), so you can exclude it from bans.
  • Access to your provider’s web console, in case you ban yourself while testing.

Step-by-Step: Install and Configure Fail2Ban on Ubuntu

Step 1: Install Fail2Ban

sudo apt update
sudo apt install fail2ban -y
fail2ban-client --version

On Ubuntu 24.04, check you have the fixed package. The original 24.04 release of Fail2Ban did not start at all because of a Python 3.12 change; version 1.0.2-3ubuntu0.1 or later fixes it:

apt policy fail2ban

Step 2: Create jail.local

Package updates overwrite jail.conf, so your settings go in jail.local, which overrides it. Create the file:

sudo nano /etc/fail2ban/jail.local

Paste this, replacing 203.0.113.50 with your own IP:

[DEFAULT]
# Never ban these (localhost + your office/home IP)
ignoreip = 127.0.0.1/8 ::1 203.0.113.50
bantime  = 1h
findtime = 10m
maxretry = 5
# Use UFW to apply bans (remove this line if you don't use UFW)
banaction = ufw

[sshd]
enabled = true
port    = ssh

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

The recidive jail is the one most guides leave out. It reads Fail2Ban’s own log and bans an IP for a week if it has been banned three times in a day, which stops the bots that simply wait out a one-hour ban and come back. If you moved SSH to another port, set port = 2222 (your port) in the [sshd] section, or the ban blocks the wrong port and does nothing.

Step 3: Add jails for Nginx and WordPress logins (optional)

Fail2Ban ships filters for common web servers. Add these to jail.local if you run Nginx with password-protected areas or get bot scans:

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

For WordPress, there’s no built-in filter, so create one that counts login and XML-RPC attempts in the Nginx access log:

sudo nano /etc/fail2ban/filter.d/wordpress-login.conf

[Definition]
failregex = ^<HOST> .* "POST /wp-login\.php
            ^<HOST> .* "POST /xmlrpc\.php
ignoreregex =

Then add the jail to jail.local:

[wordpress-login]
enabled  = true
port     = http,https
filter   = wordpress-login
logpath  = /var/log/nginx/access.log
maxretry = 6
findtime = 10m

This counts every login POST, successful or not, so keep maxretry a little above what a real person would ever do. For Apache, change logpath to /var/log/apache2/access.log.

Step 4: Test the configuration and start Fail2Ban

sudo fail2ban-client -t
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban

fail2ban-client -t checks every jail and filter and reports the exact line with a problem, which is much easier than reading a failed service log.

Step 5: Check that the jails are running

sudo fail2ban-client status
sudo fail2ban-client status sshd

The second command shows the number of failed attempts seen, the number currently banned and the banned IP list. On a public server, SSH usually shows failures within minutes of going online.

To prove a custom filter matches your log before relying on it:

sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf

Look for Lines: ... matched with a number above zero.

Step 6: Unban an IP

sudo fail2ban-client set sshd unbanip 198.51.100.7
# or remove it from every jail at once
sudo fail2ban-client unban 198.51.100.7

If you banned yourself and SSH no longer answers, log in through your provider’s web console and run the second command, then add your IP to ignoreip.

Common Issues & Troubleshooting

ERROR No module named ‘asynchat’

Cause: the original Fail2Ban package in Ubuntu 24.04 wasn’t compatible with Python 3.12, so the service fails to start.

Fix: run sudo apt update && sudo apt install --only-upgrade fail2ban to get 1.0.2-3ubuntu0.1 or newer, then restart the service.

ERROR Failed during configuration: Have not found any log file for sshd jail

Cause: Fail2Ban is looking for /var/log/auth.log, but on this server SSH logs only go to the systemd journal (common on minimal images without rsyslog).

Fix: add backend = systemd under [sshd] in jail.local, make sure python3-systemd is installed, then run fail2ban-client -t again.

Fail2Ban shows failed attempts but never bans anyone

Cause: usually the attacker’s IP is covered by ignoreip, the jail’s port doesn’t match the real port, or the site sits behind a CDN or proxy so every request comes from the proxy’s IP.

Fix: check ignoreip and port. Behind a proxy, configure the web server to log the real visitor IP first; otherwise Fail2Ban would ban the proxy and take the whole site offline for everyone.

WARNING ‘allowipv6’ not defined in ‘Definition’

Cause: a notice from newer Fail2Ban versions when an action file doesn’t state whether it handles IPv6. It shows in systemctl status fail2ban and looks like an error.

Fix: nothing is broken and bans still work. To silence it, add allowipv6 = auto under a [Definition] section in /etc/fail2ban/fail2ban.local and restart the service.

Setting up a new server? A Host & Tech VPS or dedicated server comes with root access, so you can apply this guide from the first login. For flood-style attacks rather than password guessing, see preventing DDoS attacks, and switching SSH to key-only logins removes most of the risk Fail2Ban is guarding against.

Frequently Asked Questions

Do I need Fail2Ban if I already have a firewall?

Yes, they do different jobs. A firewall like UFW decides which ports are open to everyone, while Fail2Ban watches logs and blocks individual IPs that misbehave on the ports you left open, such as SSH or a login page. Fail2Ban uses the firewall to apply its bans.

How long does Fail2Ban ban an IP for?

The default is 10 minutes, which is too short to deter bots. This guide sets one hour for normal jails and one week for repeat offenders through the recidive jail. You can set bantime = -1 for a permanent ban, but permanent bans pile up and are easier to manage in the firewall.

Should I use Fail2Ban on a cPanel server?

No. cPanel includes cPHulk for login brute-force protection, and servers usually also run a firewall such as CSF or Imunify360. Running Fail2Ban on top of those can cause conflicting firewall rules. On Plesk, use the built-in IP Address Banning feature, which is Fail2Ban managed from the panel.

How do I see which IPs Fail2Ban has banned?

Run sudo fail2ban-client status followed by the jail name, for example sshd. It lists the banned IPs and counts for that jail. The full history is in /var/log/fail2ban.log.

Does Fail2Ban work with IPv6?

Yes. Fail2Ban has supported IPv6 since version 0.10, and Ubuntu 22.04 and 24.04 ship versions newer than that. Add your own IPv6 address to ignoreip as well if you connect over IPv6.

SHARE THIS ARTICLE

Need help with your hosting?

Host & Tech provides 24/7 support for all VPS, dedicated, and shared hosting customers.

Scroll to Top