Setting fail2ban to track admin attacks on WordPress sites


We have an ISPConfig (http://www.ispconfig.org/) setup for some of our web hosting, and I noticed one of our clients was being attacked. It appeared they were attacking a client's web server by attempting a login containing SQL commands. The line looked something like this (I have removed the client web site and replaced it with 'client.web.site')

client.web.site:80 219.94.129.19 - - [16/Feb/2014:12:57:56 -0600] "POST /wp-login.php HTTP/1.0" 200 7578 "-" "-"

fail2ban (http://www.fail2ban.org/) requires (as far as I can tell) the date/time stamp to be the first thing on a line, and you'll note the first thing on the line is the site being attacked.

Set up Apache

A standard IPSConfig install creates /var/log/apache2/other_vhosts_access.log but does not use it in any of its processing. That means we can take advantage of its existence to track for these problems with fail2ban. (other_vhosts_access.log is a place where all activity from virtual hosts is mirrored to, ie the virtuals send their log info to both their own private logs and this file).


Hint: The following works for ISPConfig, because its default setup sends logs to both the site's log files and /var/log/apache/other_vhosts_access.log. However, not all control panels do this. If yours does not, simply add the following line to the vhosts template and recreate the config files (generally a one key action). This will insert the following line in every vhost configuration file

CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined

Then, view the log file. Note that you can add as many logs as you like to an apache config file, though of course, it will increase the number of writes for every hit.


The first thing to do is set apache to use a format for its log file output to something fail2ban can understand. There are no pre-defined aliases, so we'll take an existing one, copy and modify the copy, then use it for the format of this file. We'll simply move the timestamp to the beginning.

  1. edit /etc/apache2/apache2.conf
  2. Search for the key phrase 'LogFormat'. You will see multiple lines. One of these lines say vhost_combined at the end of it (that is its alias). Copy this line and do the following:
    1. change the name (vhost_combined) to fail2ban
    2. Move the %t (and the following space) from inside the string to the beginning. See below for the results.
      LogFormat "%t %v:%p %h %l %u \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" fail2ban
      
  3. Save this file
  4. Edit /etc/apache2/conf.d/other-vhosts-access-log
    1. The CustomLog line says vhost_combined. Change that to fail2ban
      LogFormat "%t %v:%p %h %l %u \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" fail2ban
      
  5. Save the file
  6. Restart Apache
  7. View /var/log/apache2/other_vhosts_access.log (ie, tail) to see the new format appear

Set up fail2ban

Now, Apache is using a format fail2ban can understand, so we need to create a new rule set for fail2ban. I call mine apache-wordpress.conf, so edit /etc/fail2ban/filter.d/apache-wordpress.conf and place the following into it:

[Definition]
#failregex =  <HOST> - - "POST /wp-login.php HTTP/1.0" 200 \d+ "-" "-"
# bensig in the comments section below found this solution which should
# be much faster than the one I commented out above.
# I have not tested it yet, but it looks definitely right.
failregex = ^<HOST> - - "POST /wp-login.php HTTP/1.1" ignoreregex =

I only included the lines necessary in this case.

Now, edit /etc/fail2ban/jail.local and ADD the following lines (create the file if necessary)

[apache-wordpress]
enabled = true
banaction = iptables-allports
# ban for an hour
bantime = 3600
port = all
filter = apache-wordpress
logpath = /var/log/apache2/other_vhosts_access.log
maxretry = 5

 Joomla Configuration

This was contributed by David in the comments. Since the comments really don't do very good on copy/paste or formatting, I decided I'd put it here. Have not done this one yet, but I'm anxious to try it. Thank you David.

Hello my config for joomla if you post 5 bad login to admin of joomla in 10mn you are baned for life The filter :

# Fail2Ban configuration file
# [Definition] failregex = <HOST> - - "POST /administrator/index.php HTTP/1.0" 200 d+ "-" "-"
ignoreregex = 
# Option: ignoreregex 
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
# ignoreregex = 2 

And conf file:

[apache-joomla-admin]
enabled = true
banaction = iptables-allports
# ban for an anytime
bantime = -1
port = all
filter = apache-joomla-admin
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
logpath = /var/log/apache2/other_vhosts_access.log
findtime = 600 
maxretry = 5

 I need to study this as David is definitely ahead of me (what the !@#$%^ is an action_mwl). But, since I do have some Joomla sites, I definitely will try it (and correct any mistakes I made copy/pasting it in).

Tags: fail2ban, ispconfig, joomla, wordpress
Last update:
2014-09-11 08:05
Author:
Rod
Revision:
1.6
Average rating: 5 (1 Vote)

You can comment this FAQ

Chuck Norris has counted to infinity. Twice.

Comment of DAVID:
Hello my config for joomla if you post 5 bad login to admin of joomla in 10mn ... show moreyou are baned for life The filter : # Fail2Ban configuration file # [Definition] failregex = <HOST> - - "POST /administrator/index.php HTTP/1.0" 200 d+ "-" "-" ignoreregex = # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex = 2 And conf : [apache-joomla-admin] enabled = true banaction = iptables-allports # ban for an anytime bantime = -1 port = all filter = apache-joomla-admin action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"] logpath = /var/log/apache2/other_vhosts_access.log findtime = 600 maxretry = 5
Added at: 2014-07-26 10:10

Comment of bensig:
Very helpful, but I found the following REGEX to work on my Wordpress: failregex = ^<HOST> ... show more- - "POST /wp-login.php HTTP/1.1"
Added at: 2014-09-08 11:49

Comment of Rod:
David, thank you very much. I believe I will play with this a little. That sounds ... show moreexcellent. I saw something like a "super filter" one time which looks at /var/log/fail2ban.log and looks for repeat offenders and bans them for a month or something!
Added at: 2014-09-11 07:54

Comment of JPascal:
Thanks a lot for this tutorial! On my ISPConfig server, I found the other-vhosts-access-log to be ... show morein /etc/apache2/conf-available Then I believe the line to modify looks like this: CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log fail2ban CHeers!
Added at: 2015-03-30 05:48