Blocking an IP Address with Fail2Ban

Let’s configure our first jail that blocks an IP address

An Example of What you can do with Fail2ban

The following is a simple example of what can be done with fail2ban. To get the most out of fail2ban you must read the documentation. There are links at the bottom of this page.

Setting Up an Unprotected WordPress Login

I have just installed WordPress. It has no plugins. It is version 5.5.3. I have added one line of code into wp‑includes/user.php.

<?php // Line 89
        global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie().
        $auth_secure_cookie = $secure_cookie;

        add_filter( 'authenticate', 'wp_authenticate_cookie', 30, 3 );

        $user = wp_authenticate( $credentials['user_login'], $credentials['user_password'] );

        if ( is_wp_error( $user ) ) {
// CUSTOM CODE HERE:
error_log('WORDPRESS - CANNOT REMEMBER PASSWORD! '.$credentials['user_login'],0);
                return $user;
        }
?>

With that addition to the code, I will attempt to login with incorrect credentials:

This could be someone attempting a brute-force attack!

The login fails and the following text is added to the log file /var/log/apache2/error.log

[Thu Nov 12 12:53:37.374928 2020] [:error] [pid 1203] [client 192.168.0.13:51361] 
    WORDPRESS - CANNOT REMEMBER PASSWORD! IdontKnow, referer: http://noodle.ee/wp-login.php

Using Fail2ban to Block Repeated login Failures

We have created a reliable method of knowing when someone fails to login on wordpress. Now, we can block such failures with fail2ban.

The jail configuration

The first file to create is /etc/fail2ban/jail.d/jail-debian.local

[wp-auth]
enabled = true
port    = 80
filter  = wp-auth-filter
logpath = /var/log/apache2/error.log
maxretry = 2
bantime = 20
findtime = 180
action =  iptables-allports
          wp-auth-action
ignoreip = 127.0.0.1

This configuration says:

  • watch the log file /var/log/apache2/error.log
  • Do something if the failure occurs 2 or more times in the most recent 180 seconds
  • Block the offending IP address for 20 seconds
  • action #1 is iptables-allports (this actions is baseline for fail2ban)
  • action #2 is wp-auth-action (this action is custom)
  • Don’t take any action if the offending IP address is 127.0.0.1

The filter configuration

The second file to create is /etc/fail2ban/filter.d/wp-auth-filter.conf

[Definition]
failregex = .+?\[client <HOST>(:\d{1,10})?\] WORDPRESS - CANNOT REMEMBER PASSWORD(.*)
ignoreregex =

Fail2ban uses regular expressions to filter matches in log files. I use an online regex tester to help me create regular expressions.

You can use regex101.com to test your fail2ban regular expressions. In the "Regular Expression" section, replace <HOST> with the IP address found in the log, then paste the line of text found in the log into the TEST String section.

The action configuration

The final file to create is /etc/fail2ban/action.d/wp-auth-action.conf

[Init]
init ='sending XMPP Instant Message with fail2ban'
name = wp-auth

[Definition]
actionban = /bin/echo "Fail2ban violation: <name> <ip>" >> /var/log/custom-fail2ban.log
            /usr/local/bin/monitor.chat.sh "<SMILINGIMP> Fail2Ban blocked IP Address <ip> for violating <name>."

Now, reload fail2ban:

service fail2ban reload

When I test failed logins, I get a text message on the second failure:

Fail2ban reports the block of an IP address to my monitor chatroom!


Topics covered on this page:

Last modified March 5, 2021