Fail2Ban not matching or banning new WordPress filter

OS type and version Ubuntu Linux 22.04.3
Webmin version 2.101
Usermin version 2.001
Virtualmin version 7.8.2
Theme version 21.04
Package updates 9 package updates are available


I have setup a new filter on Fail2Ban to block brute force attacks on xmlrpc.php and wp-login.php, however it is not matching or blocking any of the requests.

Here is my configuration, I hope someone can spot where the issue is:

Under log filters, I added a new log, and used :

^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|xmlrpc\.php)

as regular expression to match. I called the filter wordpress.

Under config files, /etc/fail2ban/filter.d/wordpress.config I have the following:

failregex = ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|xmlrpc\.php)

Under /etc/fail2ban/jail.local I have the following:

enabled = true
port     = http,https
filter = wordpress
logpath = /var/log/virtualmin/*_access_log
bantime = 43200
action = firewallcmd-allports[]
maxretry = 1
findtime = 1d

Is my jail.local entry correct? When I go to Jail Status tab, Everything is 0 under wordpress, its not matching nor banning any requests ( I’m hit with hundreds of request every few minutes).

In terminal I run :

fail2ban-regex /var/log/virtualmin/domain.com_access_log /etc/fail2ban/filter.d/wordpress.local

And it returns successful matches:


Failregex: 667 total
|-  #) [# of hits] regular expression
|   1) [667] ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|xmlrpc\.php)

So Whats wrong? Any help is greatly appreciated, as my server resources are being hammered right now. Thanks!

Wouldn’t it be easier just installing the Wordfence addon.

Fail2Ban is much faster at mitigating this.

No sure what you mean, but ok. Good luck. Maybe add it while your working it out if your getting hammered.

when it works, maybe.

I’m curious, wouldn’t this block all genuine login attempts as well?

Im using another login url.

Try this regex instead:

<HOST>.*(GET|POST|HEAD).*(wp-login\.php|xmlrpc\.php).* 200

Would 200 work if he has moved login location, i’m not good a regex, so its prob opposite to what I think :slight_smile:

Found this

I used your regex, fail2ban-regex command returns more matches, so I think yours captures better, but still, jail status shows all 0, and no bans. Im getting thousands of these under nginx access log: - - [26/Oct/2023:12:46:14 +0000] "POST //xmlrpc.php HTTP/1.1" 200 413 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.193 Safari/537.36"

Web-servers’ access log, a 200 response code indicates a successful HTTP request. The user will have to hit the actual page and get 200 response code for the page to be displayed anyway.

Here is the example of configuration that is proven to be working:

File: /etc/fail2ban/jail.d/10-wordpress.conf:

enabled = true
port = http,https
filter = wordpress
logpath = /var/log/virtualmin/example.com_access_log
maxretry = 2
bantime = 3600

File: /etc/fail2ban/filter.d/botsearch-common.conf (defaults):

# Generic configuration file for -botsearch filters


# Block is the actual non-found directories to block
block = \/?(<webmail>|<phpmyadmin>|<wordpress>|cgi-bin|mysqladmin)[^,]*

# These are just convenient definitions that assist the blocking of stuff that 
# isn't installed
webmail = roundcube|(ext)?mail|horde|(v-?)?webmail

phpmyadmin = (typo3/|xampp/|admin/|)(pma|(php)?[Mm]y[Aa]dmin)

wordpress = wp-(login|signup|admin)\.php

# DEV Notes:
# Taken from apache-botsearch filter
# Author: Frantisek Sumsal

I presume you restarted fail2ban

Does fail2ban allow wildcards in the filename ? Maybe it’s worth trying the filter with an exact log file and see if it works

if that is the case then why bother with fail2ban the old login it just needs to go to a 404 (or nothing) a brute force attack by definition has to go to some end point. As does any genuine request. If you no longer have an end point for wp-login then there is no problem to solve.

but it could be said if the default url is attempted, The person on this IP is up to no good, as a bonafide user would know the correct url ? This for me would be a reason to ban them from the whole server as they may also attempt mysql, ssh etc. but you are right if there is no end point there is no real point

If you have, or will never have, any valid WP using that page then you simply want to count ANY hit to that url because auth will never fail?
Does that make the filter easier then?

Yes that’s mainly the reason i wish to completely ban the IPs. Besides the login page, there are still thousands of other hits to xmlrpc.php, and the same actor attempting wp-login is also brute forcing xmlrpc.php so it makes sense to ban both.

The original issue still remains, tho, new filter is reporting all zeros, even with a direct log path without wildcard.

On my RHEL 9 system I found that Virtualmin messed with the jails when compared to a pre-Virtualmin system. Reported in a thread about regex experts, nobody noticed.

Update: Added backend = auto and now it seems like the filter is starting to pick up matches. Will see if its going to effectively start banning.

backend = auto solved the problem, and also offending IPs are properly banned through the firewall.

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.