Link to home
Start Free TrialLog in
Avatar of sharingsunshine
sharingsunshineFlag for United States of America

asked on

Need Fail2Ban regex for wp-login attempts

Need help with regex for fail2ban to stop wp-login attempts.  Here is my jail.local.  I am on a Centos 6 server

[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/httpd/access_log*
action = iptables[name=WP,port=http,protocol=tcp]
port = http,https
maxretry = 3
findtime = 10
bantime = 2592000
ports = 80,443

Open in new window


this is the log file and this is a known marauder trying to break in.
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:23 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"

Open in new window


this is the filter.
#Fail2Ban configuration file
[Definition]
failregex = <HOST> - - \[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4}\] "POST /wp-login\.php HTTP/1\.1"
ignoreregex =

Open in new window


this is the regex I used to test it.  
 fail2ban-regex /var/log/httpd/access_log-20180218 /etc/fail2ban/filter.d/wordpress.conf

Open in new window


The regex is being ran on the log file of what is above.
Running tests
=============

Use regex line : /etc/fail2ban/filter.d/wordpress.conf:more
Use log file   : /var/log/httpd/access_log-20180218

No 'host' group in '/etc/fail2ban/filter.d/wordpress.conf:more'
Cannot remove regular expression. Index 0 is not valid
Traceback (most recent call last):
  File "/usr/bin/fail2ban-regex", line 354, in <module>
    fail2banRegex.testRegex(line)
  File "/usr/bin/fail2ban-regex", line 232, in testRegex
    self.__filter.addFailRegex(regex.getFailRegex())
  File "/usr/share/fail2ban/server/filter.py", line 90, in addFailRegex
    raise e
server.failregex.RegexException: No 'host' group in '/etc/fail2ban/filter.d/wordpress.conf:more'

Open in new window


Here is the results of the regex truncated.
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second

Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Summary
=======

Sorry, no match

Open in new window

Avatar of Dr. Klahn
Dr. Klahn

Try this one.  The one shown in the problem statement is too specific; for one thing, it'll only catch HTTP 1.1 attackers.

failregex =^.* "POST /wp/wp-login\.php

Open in new window

@Dr. Klahn, you just missed the IP address needed to match....
and the original assumes a lot of single spaces..

It even more simple:     the filename supplied is: /etc/fail2ban/filter.d/wordpress.conf:more
It has to loose the :more part.

failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp/wp-login\.php"\s+
datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z

Open in new window


(This is a variation of the openhub.conf example.)
I am, alas, but a simple man.  I'd have to study on that one for half an hour to figure it out.
failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp/wp-login\.php"\s+

Open in new window

Reads like: match begin of line (^) then hostname/ipv4adress/ipv6address (<HOST>) then any amount of whitespace (\s+) a dash (-) then again \s+-) then squar bracket .. square bracket close again..    some whitespace + quote (\s+") some uppercase character ending in whitespace
[A-Z]+\s+ followed by /wp/wp-... etc.)

(The datepatern should also remove the date from a line AFAICT..).
ASKER CERTIFIED SOLUTION
Avatar of noci
noci

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
HI
Create the file /etc/fail2ban/jail.d/wordpress.conf file add the following rules into that

[wordpress]
enabled = true
port = http,https
filter = wordpress
action = iptables-multiport[name=wordpress, port="http,https", protocol=tcp]
logpath = /var/log/httpd/access_log
          /var/log/apache2/access*log
          /var/log/virtualmin/*log
maxretry = 10
findtime = 600


Hope this will help what you want
Avatar of sharingsunshine

ASKER

Noci - I am not clear on this statement "Also note that you need to test with the filename part remove from thw data shown in the question."  Below is what I used to test with.

fail2ban-regex /var/log/httpd/access_log-20180218 /etc/fail2ban/filter.d/wordpress.conf

Open in new window


I copied your exact code into the wordpress.conf and commented out all of the original code
#Fail2Ban configuration file
[Definition]
#failregex = <HOST>.*]"POST /wp-login.php
#failregex = <HOST> - - \[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4}\] "POST /wp-login\.php HTTP/1\.1"
#failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp/wp-login\.php"\s+
#datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z
#ignoreregex =

[Definition]
failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp-login\.php\s+HTTP/1.[01]"\s+.*$
ignoreregex=

[Init]
datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z

Open in new window



This is the result I got
Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Summary
=======

Sorry, no match

Open in new window


Please advise
Hi Prabhin,

I couldn't see how any of your changes would be helpful.  Since I have no Apache2 or virtualmin.  Also my logs are only given a -yearmonthday ending.  So my wildcard appears to be sufficient.
Hi this log file is incorerct (filename prefix on everly line:
Noci - I am not clear on this statement "Also note that you need to test with the filename part remove from thw data shown in the question."  Below is what I used to test with.

/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
/var/log/httpd/access_log-20180218:195.22.127.169 - - [17/Feb/2018:08:05:23 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"

Open in new window


with this prefix removed:  /var/log/httpd/access_log-20180218:
195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
195.22.127.169 - - [17/Feb/2018:08:05:22 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"
195.22.127.169 - - [17/Feb/2018:08:05:23 -0500] "POST /wp-login.php HTTP/1.1" 503 2925 "http://thefrugallife.com/wp-login.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"

Open in new window

Rules will match.

If your logfiles have a filename prefix per line then there is a problem with the grep command used to get them.
dont's use multiple file on a grep command to prevent this
I see the confusion.  I was using
grep -r "195.22.127.169" /var/log/httpd/access_log*

Open in new window

to find where that known marauder had hit my logs.  I then unbeknownst to me copied the output which had the logfile with those locations appended to the output.  I won't make that mistake again.

now I just ran again
fail2ban-regex /var/log/httpd/access_log-20180218 /etc/fail2ban/filter.d/wordpress.conf

Open in new window

and I still don't get a match.

Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second

Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Summary
=======

Sorry, no match

Open in new window

there are two [Definition] line is your wordpress file. Like this....

[Definition]
[Definition]
failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp-login\.php\s+HTTP/1.[01]"\s+.*$
 ignoreregex=

[Init]
datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z

Open in new window


If I run this i get the error :
configparser.DuplicateSectionError: While reading from '/home/test/t.filter' [line  4]: section 'Definition' already exists
I made the change and still no matches
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second
Matched time template Day/MONTH/Year:Hour:Minute:Second

Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Summary
=======

Sorry, no match

Open in new window


This is my filter
[Definition]
failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+\s+/wp-login\.php\s+HTTP/1.[01]"\s+.*$
ignoreregex=

[Init]
datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z

Open in new window


this is the wordpress definition

[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/httpd/access_log*
action = iptables[name=WP,port=http,protocol=tcp]
port = http,https
maxretry = 3
findtime = 10
bantime = 2592000
ignoreip = 1.1.1.1
ports = 80,443

Open in new window


fasil2ban is working great for postfix
are you sure this is ok:

logpath = /var/log/httpd/access_log*

fail2ban follows ONE log file (it doesn't continuosly scan log files, but reads on files that are added onto), use logrotate to change files.
(fail2ban-regex is a debugging tool_.)  

If you supply a wildcard on the command line only the first file matching the glob expression will be used.
(anyway the wordpress.conf  entry only if configuration for the daemon).  it isn't used for the fail2ban-regex.
That only involves a filter and one logfile.
I checked the log files and they are loading correctly.  Also the manual says that it supports the use of wildcards

Feb 25 15:03:53 ip-172-31-22-236 fail2ban.filter : INFO   Added logfile = /var/log/httpd/access_log-20180211
Feb 25 15:03:53 ip-172-31-22-236 fail2ban.filter : INFO   Added logfile = /var/log/httpd/access_log-20180225
Feb 25 15:03:53 ip-172-31-22-236 fail2ban.filter : INFO   Added logfile = /var/log/httpd/access_log
Feb 25 15:03:53 ip-172-31-22-236 fail2ban.filter : INFO   Added logfile = /var/log/httpd/access_log-20180204
Feb 25 15:03:53 ip-172-31-22-236 fail2ban.filter : INFO   Added logfile = /var/log/httpd/access_log-20180218

Open in new window

First step.

Do not attempt to figure this out by parsing Apache logs.

Do install a plugin like https://wordpress.org/plugins/wp-fail2ban/ which output simple/clear log entries for when a WordPress login fails or succeeds... using either wp-admin/wp-login.php or xmlrpc.php which will also eventually be hit.

Then use https://wordpress.org/plugins/wp-fail2ban/#installation provided by the plugin.

This will save you a massive amount of time.
Thanks for all of your help.