🧾 Fail2Ban Virtualmin With WordPress Setup Checklist
This is a followup to my SmarterMail Fail2Ban installation (see https://charlesworks.com/hardening-your-smartermail-server-the-bouncer-defense/). I’m not an expert at Fail2Ban, but installing these filters reduced server CPU usage by about 30% on both virtual and bare metal servers. On systems running hard drives it was especially helpful as this filtering greatly reduced hard drive accesses which can be a real bottleneck on servers. Feel free to contact me at support@charlesworks.com with any observations or improvements.
👍 Here’s a clean, no-nonsense checklist you can walk through with nano:
📁 1. Create a WordPress filter
nano /etc/fail2ban/filter.d/wordpress.conf
Paste:
[Definition]
failregex = ^<HOST> -.*"(POST)\s+/wp-login\.php
ignoreregex =
📁 2. Create a 404 scanner filter
nano /etc/fail2ban/filter.d/apache-404.conf
Paste:
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*(wp-admin|wp-login|xmlrpc|phpmyadmin|\.env|\.git).*" 404
ignoreregex =
📁 3. Create an xmlrpc filter
nano /etc/fail2ban/filter.d/xmlrpc.conf
Paste:
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*xmlrpc\.php
ignoreregex =
📁 4. Create an “aggressive ajax” filter
NOTE: Use cautiously on busy WooCommerce or heavily dynamic WordPress sites. Monitor logs carefully before enabling on production ecommerce systems. This may cause false positives and can break shopping carts on very high use sites.
nano /etc/fail2ban/filter.d/wp-ajax-spam.conf
Paste:
[Definition]
failregex = ^<HOST> -.*"POST /wp-admin/admin-ajax\.php
ignoreregex = .*post\.php\?post=.*action=edit # Ignore a user's actual editing activity
📁 5. Edit jail.local
nano /etc/fail2ban/jail.local
Add this line at the top of the file to prevent ever banning yourself, replacing the x.x.x.x with your IP address:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 x.x.x.x
Then add these sections at the bottom of the file:
🔐 WordPress login protection
[wordpress]
enabled = true
port = http,https
filter = wordpress
backend = polling
logpath = /var/log/virtualmin/*_access_log
maxretry = 5
findtime = 3600
bantime = 86400
⚡ XML-RPC is still accessible, but abusive clients are banned aggressively.
[xmlrpc]
enabled = true
port = http,https
filter = xmlrpc
backend = polling
logpath = /var/log/virtualmin/*_access_log
maxretry = 3
findtime = 600
bantime = 86400
🔍 404 scanner protection
[apache-404]
enabled = true
port = http,https
filter = apache-404
backend = polling
logpath = /var/log/virtualmin/*_access_log
maxretry = 20
findtime = 300
bantime = 86400
⚡ Aggressive Ajax protection
[wp-ajax-spam]
enabled = true
port = http,https
filter = wp-ajax-spam
backend = polling
logpath = /var/log/virtualmin/*_access_log
maxretry = 30
findtime = 60
bantime = 86400
📁 Save the file
🔄 6. Restart Fail2Ban
systemctl restart fail2ban
✅ 7. Verify all jails
fail2ban-client status
You should see with the others in the list:
wordpress
xmlrpc
apache-404
🔍 8. Check each jail (optional)
fail2ban-client status wordpress
fail2ban-client status xmlrpc
fail2ban-client status apache-404
Or check in Virtualmin at:
Webmin > Networking > Fail2Ban Intrusion Detector > Jails Status
👍 That’s it
You now have:
- WordPress login protection
- XML-RPC abuse control (not blocked, but aggressive bans)
- Bot/scanner detection via 404s
- Ajax abuse control
- All working across every Virtualmin domain automatically
Extra:
On some servers we have Remote Desktop enabled. We can monitor the access logs in those as well. Not a lot of sense in adding this to a box with no Remote Desktop enabled.
📁 1. Create XRDP filter
nano /etc/fail2ban/filter.d/xrdp.conf
Paste:
[Definition]
failregex = ^.*login failed for user .* from <HOST>
ignoreregex =
📁 2. Create XRDP jail file
nano /etc/fail2ban/jail.d/xrdp.local
Paste:
[xrdp]
enabled = true
port = 3389
filter = xrdp
logpath = /var/log/xrdp-sesman.log
maxretry = 5
bantime = 3600
findtime = 600
🔄 3. Restart Fail2Ban
systemctl restart fail2ban
✅ 4. Verify all jails
fail2ban-client status
You should see with the others in the list:
xrdp
🔍 5. Check the jail (optional)
fail2ban-client status xrdp
Or check in Virtualmin at:
Webmin > Networking > Fail2Ban Intrusion Detector > Jails Status
/>
Here are the official website URLs for Fail2Ban and FirewallD:
- Fail2Ban: https://www.fail2ban.org
- FirewallD: https://firewalld.org
While the Fail2Ban website is the official home for documentation and the project wiki, much of the active development and issue tracking happens on their GitHub repository: https://github.com/fail2ban/fail2ban.


