The NinjaFirewall WP plugin is a very fast, reliable Web Application Firewall for WordPress. Fail2Ban is a daemon that scans a server’s log files once per second. If it finds evidence of an attack on the server, it can ban the IP address that the attack is coming from. This article outlines how to add a log file filter to Fail2Ban that detects attacks logged by NinjaFirewall so that it can ban the attacker’s IP address.
tl;dr version: You can get all the files you need in the fail2ban-filter-ninjafirewall-wp files Github repository.
First, enable brute force login protection on the NinjaFirewall | Log-in Protection settings page. Check-mark the Write incident to the server AUTH log. option. Note that the “Yes, if under attack” option is the only option that will generate brute-force attack log messages. Save these settings.
Next, log in into your web server (assuming you have Fail2Ban already installed and working) and create a new recipe file with the following command…
sudo vi /etc/fail2ban/filter.d/ninjafirewall.conf
Insert the following text…
[INCLUDES] after = common.conf [Definition] _daemon = ninjafirewall failregex = ^%(__prefix_line)sPossible brute-force attack from <HOST> on ignoreregex =
Next, enable the filter by editing or creating a jail.local file with…
sudo vi /etc/fail2ban/jail.local
and insert the following text…
[ninjafirewall] port = http,https filter = ninjafirewall logpath = %(syslog_authpriv)s backend = %(syslog_backend)s maxretry = 2 enabled = true
Restart the service…
sudo service fail2ban restart
To test the new filter run this command…
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/ninjafirewall.conf
If there are any entries from NinjaFirewall in the auth.log file fail2ban-regex will show you the number of matches.
If there are any IP addresses that are currently banned you can see them by running this command…
sudo iptables -L
PRECAUTIONS FOR CACHING AND PROXY SERVICES
When your web server is accessed through a caching or proxy service, such as CloudFlare, the connecting IP address in an attack will be a proxy server IP address. Banning the connecting IP address could result in your web site becoming inaccessible to some or all of the internet. Simply banning the true client IP address will not help either, since that IP address most likely would never connect directly to your web site. In this case, you may not want to use this Fail2Ban filter at all. Another possibility is to setup a custom actionban for the ninjafirewall filter as shown in the example of the next section.
To make sure that Fail2Ban does not ban any CloudFlare IP addresses, we will add a list of CloudFlare IP addresses to ignore. Get the current list of IP ranges of CloudFlare’s servers. Note that you only need the IPv4 list of IP addresses since, at the time this was written, Fail2Ban can not handle IPv6 addresses. The list of IP ranges is added to the ignoreip variable in the [DEFAULT] section of your jail.local file.
The following is an example of how that should look, but make sure you get the current list of IP ranges for CloudFlare.
[DEFAULT] # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not # ban a host which matches an address in this list. Several addresses can be # defined using space (and/or comma) separator. ignoreip = 127.0.0.1/8 220.127.116.11/22 18.104.22.168/22 22.214.171.124/22 126.96.36.199/12 188.8.131.52/18 184.108.40.206/22 220.127.116.11/18 18.104.22.168/15 22.214.171.124/13 126.96.36.199/20 188.8.131.52/20 184.108.40.206/20 220.127.116.11/22 18.104.22.168/17
To deal with the issue of the connecting IP address being a CloudFlare IP address, read this article about how to set the correct client IP address for NinjaFirewall to use. If you are using the Apache web server, another possibility is to install mod_cloudflare.
Once you have dealt with getting NinjaFirewall to report the true IP address of the client, you need to configure Fail2Ban to report the client IP address to CloudFlare. Log in to your CloudFlare account and get a copy of your Global API key from your account profile page.
Next, open your /etc/fail2ban/jail.local in an editor and search for action_cf_mwl. Add two new variables, cfemail and cfapikey, above the action_cf_mwl line. Add the correct values for your Cloudflare login email and global API key as shown in this example. Define the new action_cf_v4 in place of the old action_cf_mwl value.
cfemail = [email protected] cfapikey = aabbccddee1122334455a1b2c3d4e5qwertya action_cf_v4 = cloudflare-restv4[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"] %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
Next, replace the [ninjafirewall] section given above with the following section. This will tell iptables to ban the client IP address on all ports (in case the same hacker does have your true IP address and starts probing elsewhere). It will also send the client IP address to cloudflare and ask them to ban requests from the client IP address. Then it will send you an email about the event according to the settings you already have for Fail2Ban.
[ninjafirewall] port = http,https filter = ninjafirewall action = iptables-allports[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] cloudflare-restv4[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"] %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"] logpath = %(syslog_authpriv)s backend = %(syslog_backend)s maxretry = 2 enabled = true
Finally, restart the Fail2Ban service and make sure everything is working.
sudo service fail2ban restart
If fail2ban won’t restart after you have edited configuration files, you can try manually starting it with verbose messaging enabled to find out where it is failing as it is starting up.
fail2ban-client -vvv -x start
Once you have fixed all errors in your configuration files, restart it as a service.
fail2ban-client -x stop service fail2ban start