Fail2ban on Ubuntu 24.04: Minimal setup to block SSH and wp-login.php
Commands, jail.local file and WordPress filter: minimal fail2ban configuration on Ubuntu 24.04 LTS, with the known bug to fix first.
UptimeMag editorial team · 22 October 2026 · 3 min read

Anyone managing even a single VPS with WordPress knows the score: auth.log and access.log fill up with automated login attempts within hours of going live. Fail2ban remains the most straightforward tool to cut them off at the source, without installing resource-hungry PHP plugins. This is the minimal configuration tested on Ubuntu 24.04 LTS (noble), updated 22 October 2026.
Installation
The package is in the official repositories, universe component:
sudo apt update
sudo apt install fail2ban
On Ubuntu 24.04 the repository version is fail2ban 1.0.2-3 (noble) and 1.0.2-3ubuntu0.1 in noble-updates.
The bug to fix first
On a clean 24.04 installation the service may not start. The bug is tracked on Launchpad as "fail2ban is broken in 24.04 Noble": the fail2ban package doesn't list 'python3-setuptools' as a dependency, even though it's needed for distutils, which is required by the default sshd jail and therefore for fail2ban to work. The root cause is the removal of the asynchat module from Python 3.12, which became default with Ubuntu 24.04. The fix is a single command:
sudo apt install python3-setuptools
sudo systemctl restart fail2ban
Once done, fail2ban should start correctly. Check with systemctl status fail2ban before proceeding: if the status is not active (running), the rest of the configuration is pointless.
The jail.local file
Never edit /etc/fail2ban/jail.conf directly: it gets overwritten on every package update. Rules go in a separate file that fail2ban reads as an override:
sudo nano /etc/fail2ban/jail.local
Minimal configuration for SSH:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 10m
bantime = 1h
On Ubuntu 24.04 the default firewall backend for fail2ban is nftables, whilst sshd logs are read via systemd rather than from file: if the sshd jail isn't catching anything, it's worth checking that backend is set to systemd in the [sshd] block, not auto with a non-existent logpath.
Blocking attempts on wp-login.php
Fail2ban doesn't include a WordPress filter out of the box: you need to create a dedicated filter and jail.
Filter file, /etc/fail2ban/filter.d/wordpress-login.conf:
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php HTTP.* 200
ignoreregex =
The key detail: the 200 response code identifies a failed login (the page reloads), whilst a successful login returns a 302 redirect, which the regex doesn't catch. Without this distinction the filter would ban legitimate users as well.
Corresponding jail in /etc/fail2ban/jail.local:
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 10m
bantime = 1h
With Apache use /var/log/apache2/access.log as the logpath. Before trusting the jail, it's worth testing the filter against the actual log:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf
If the number of lines found is zero, the log format doesn't match the regex (this often happens with reverse proxies or CDNs in front of the site, which rewrite the IP in a field different from what fail2ban expects).
Apply and verify
After saving jail.local:
sudo systemctl restart fail2ban
To check the overall status of active jails:
sudo fail2ban-client status
To see the details of a single jail, with the number of IPs currently banned and the failure history:
sudo fail2ban-client status sshd
sudo fail2ban-client status wordpress-login
The output lists the currently banned addresses. To remove one manually, for example to unblock an IP that was jailed by mistake:
sudo fail2ban-client set sshd unbanip 203.0.113.10
This minimal configuration covers the basic case: brute force on SSH and wp-login.php. It doesn't replace a broader access policy (SSH keys instead of passwords, 2FA on WordPress), but it immediately reduces the noise in your logs and the server load generated by automated attempts.
Written with the help of artificial intelligence and checked by the editors (EU AI Act, art. 50).