Learn how to secure WordPress and CMS logins on Ubuntu 24.04 with advanced Fail2Ban custom jails. Step-by-step guide with commands to block brute force attacks and protect websites.
Cybercriminals know that brute force attacks against WordPress and other CMS logins are easy money. Bots scrape admin pages, hammer login forms, and keep guessing passwords until they succeed. If we are serious about security, we cannot rely only on strong passwords and basic firewalls. Fail2Ban gives us a way to automatically detect and block suspicious login attempts in real time.
Ubuntu 24.04 ships with modern packages and systemd integration, making it a great environment to harden WordPress or any PHP-based CMS against brute force attempts. Let’s walk through advanced Fail2Ban techniques, focusing on writing custom jails that target CMS login endpoints.
Prerequisites
Before we begin, ensure we have the following:
- An Ubuntu 24.04 dedicate server or KVM VPS.
- Basic Linux Command Line Knowledge.
Advanced Fail2Ban on Ubuntu 24.04 Custom Jails
Step 1: Install Fail2Ban on Ubuntu 24.04
We start with a clean installation of Fail2Ban from the official repositories.
sudo apt update
sudo apt install fail2ban -y
Enable and start the service:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Verify it is active:
sudo systemctl status fail2ban
Step 2: Understand the Jail and Filter Concept
Fail2Ban has two main parts:
- Filter: Defines what log pattern to look for (regex that matches failed logins, suspicious requests, etc.).
- Jail: Defines how Fail2Ban reacts when a filter triggers (ban time, IP tables, max retries).
By combining these, we can block bots that target /wp-login.php
or /xmlrpc.php
.
Step 3: Create a Custom Filter for WordPress
We’ll monitor Nginx or Apache logs to catch failed login attempts. Create a new filter:
sudo nano /etc/fail2ban/filter.d/wordpress.conf
Add:
[Definition]
failregex = <HOST> -.*"(POST|GET).*wp-login.php.*" (200|401|403)
<HOST> -.*"(POST|GET).*xmlrpc.php.*" (200|401|403)
ignoreregex =
- failregex looks for requests hitting wp-login.php or xmlrpc.php.
- ignoreregex stays empty because we want to catch every match.
Save and exit.
Step 4: Create the Custom Jail
Now we connect the filter to a jail.
sudo nano /etc/fail2ban/jail.d/wordpress.local
Add:
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 600
bantime = 86400
action = iptables[name=WordPress, port=http, protocol=tcp]
Explanation:
- logpath should match our web server’s access log. Change path if using Apache (/var/log/apache2/access.log).
- maxretry 3 means after 3 failed requests within findtime (600 seconds), the IP is banned.
- bantime 86400 is 24 hours.
- Action blocks the IP via iptables.
Step 5: Test the Filter
Before reloading Fail2Ban, test our regex to confirm it catches the right lines.
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress.conf
If the output shows matches, the filter is working.
Step 6: Restart Fail2Ban
Apply changes:
sudo systemctl restart fail2ban
Check jail status:
sudo fail2ban-client status
To see WordPress jail details:
sudo fail2ban-client status wordpress
Step 7: Unban or Manage IPs
Sometimes we need to unban an IP:
sudo fail2ban-client set wordpress unbanip 203.0.113.45
List all banned IPs:
sudo fail2ban-client status wordpress
Step 8: Extend Protection for Other CMS
The same concept works for Joomla, Drupal, Magento, or custom PHP apps. For example, change failregex to match /administrator/index.php
(Joomla) or /user/login
(Drupal). Just copy the jail and filter, adjust the paths, and reload Fail2Ban.
Step 9: Harden Further with Recidive Jail
Bots often return after bans expire. Fail2Ban has a built-in recidive jail to permanently block repeat offenders.
Enable it:
sudo nano /etc/fail2ban/jail.d/recidive.local
Add:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 604800
findtime = 86400
maxretry = 5
This bans IPs for 7 days if they trigger bans multiple times in 24 hours.
Step 10: Monitor and Maintain
Check logs regularly:
sudo tail -f /var/log/fail2ban.log
Rotate logs to avoid disk bloat:
sudo logrotate -f /etc/logrotate.d/nginx
Keep updating your regex patterns as attackers change tactics.
Final Thoughts
By writing custom jails in Fail2Ban, we gain precise control over brute force protection. WordPress and other CMS platforms are juicy targets, but we can make our servers much harder to break into by monitoring login endpoints and blocking suspicious patterns. Ubuntu 24.04, combined with Fail2Ban’s flexibility, lets us stay ahead of attackers without heavy resource usage.
This approach is not a silver bullet, but it’s an essential layer of defense. Combine Fail2Ban with secure passwords, two-factor authentication, and timely updates to keep CMS platforms resilient against constant brute force attempts.