fail2ban regex not matching

Solution 1:

After a couple of iterations with fail2ban-regex, I think what happens is that fail2ban tries to pick the date from the log line itself, before testing it against your filter pattern.

$ line='0.0.0.0 - - [06/Apr/2017:07:45:42 +0000] "POST /xmlrpc.php'

With .* in place of the timestamp, it matches, but as you noticed, explicitly looking for a number at the start of the timestamp doesn't match:

$ ./fail2ban-regex "$line"  '<HOST> - - \[.*\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 1 matched, 0 missed

$ ./fail2ban-regex "$line"  '<HOST> - - \[\d+.*\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 0 matched, 1 missed

But check this out:

$ ./fail2ban-regex "$line"  '<HOST> - - \[ \+0000\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 1 matched, 0 missed

I removed the whole timestamp from the pattern, instead expecting it to be empty (there's just the timezone indicator). It still matches, hinting that fail2ban actually removes the timestamp before testing against the pattern in the configuration.

So, it may be better to just leave that part out of the filter pattern, and match anything in place of the timestamp:

<HOST> - - \[.*?\] "POST /xmlrpc.php HTTP/1.0" 200

As a side note, your original RE has an unquoted + where the timestamp starts, the plus sign means "at least one repetition of the previous element", so you need to escape it.

Solution 2:

Try this regex - I tested it with regexr.com and it is definitely being matched:

<HOST> - - \[\d{2}\/\w{3}\/\d{4}(:\d{2}){3} \+0000\] "POST \/xmlrpc.php HTTP\/1.0" 200

One of the issues was not escaping the slashes - this needs to be done.

EDIT (After I saw your edit): I tried simplifying it a bit and came up with this that matches:

failregex = ^<HOST> - - \[.*\] "POST \/xmlrpc.php.*$

It is not exactly what you wanted but it works