In today’s digital landscape, websites are constantly under attack. According to recent studies, over 80% of website breaches occur due to brute force or stolen credentials. This makes it increasingly important to secure your website from unauthorized access.
Fail2ban is an open-source tool designed to protect your website from malicious attacks by automatically blocking suspicious IP addresses. It works by scanning log files for patterns of suspicious activity, such as multiple failed login attempts, and then blocking the IP addresses associated with those actions.
In this guide, we’ll walk you through the steps to secure your WordPress site using Fail2ban, and also ensure it works effectively with Cloudflare’s proxy, so you can block malicious IPs without risking legitimate traffic disruptions.
What is Fail2ban?
Fail2ban is a proactive security tool that monitors system logs for signs of malicious activity, such as repeated failed login attempts. It automatically blocks the offending IP addresses by updating firewall rules, preventing further attempts from those sources. This tool is widely used to secure servers and applications against brute-force attacks, DDoS attacks, and other malicious behavior.
Fail2ban is particularly effective for applications such as WordPress, where brute force login attempts are common. By configuring Fail2ban to monitor WordPress login attempts, you can mitigate the risk of unauthorized access to your site.
Configuring Fail2ban for WordPress
Step 1: Log in to Your Server
To begin, you need to access your server via SSH. Ensure that you have superuser privileges to make the necessary configuration changes.
ssh user@your-server-ip
Step 2: Locate the Log Files
Fail2ban requires access to log files to monitor for suspicious activity. On most Linux servers running Nginx or Apache, the log files are stored in the /var/log/
directory. For Nginx, you can typically find the access logs in:
/var/log/nginx/access.log
For Apache, the location would likely be:
/var/log/apache2/access.log
To check the contents of these log files, use the following command:
tail -f /var/log/nginx/access.log | grep "POST /wp-login.php"
This command will monitor login attempts on your WordPress site’s login page. Try logging in with invalid credentials to generate failed login attempts and confirm that these attempts are logged correctly.
Step 3: Configure Fail2ban Jail for WordPress
Fail2ban comes with default settings for SSH, but you’ll need to create a custom jail for WordPress. A jail defines the filter and the action that should be taken when suspicious activity is detected.
Start by copying the default configuration file to create a local version:
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
nano /etc/fail2ban/jail.local
Scroll down to the [jails]
section and add the following configuration to monitor the WordPress login attempts:
[wordpress-auths]
enabled = true
port = http,https
filter = wordpress-auth
logpath = /var/log/nginx/access.log
Replace the log path with the actual location of your access log file. This configuration will instruct Fail2ban to monitor the specified log file for failed login attempts on WordPress.
If you run multiple WordPress websites on the same server, you can specify multiple log files by appending them to the logpath
variable or use a wildcard (*
) to monitor all log files in the directory.
Step 4: Create the Fail2ban Filter
Next, you need to create a filter that defines what kind of login attempts should be considered suspicious. This filter will use regular expressions (regex) to identify failed login attempts in the log file.
Create a new filter file for WordPress:
nano /etc/fail2ban/filter.d/wordpress-auth.conf
Add the following content to filter out failed login attempts:
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php HTTP.* 200
This regex pattern matches failed POST requests to the WordPress login page. If you are using Apache or OpenLiteSpeed, you may need to adjust the pattern slightly depending on the server’s log format.
Once the filter is saved, exit the text editor.
Step 5: Test the Fail2ban Filter
Before applying the configuration, it’s important to test the filter to ensure it works correctly. Run the following command to test the filter against your log file:
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-auth.conf
The output will show the number of log entries that matched the filter. If everything is set up correctly, the output should show the failed login attempts.
Step 6: Restart Fail2ban and Verify Configuration
Now that everything is configured, restart Fail2ban to apply the changes:
systemctl restart fail2ban
Check if Fail2ban is running correctly by executing:
fail2ban-client status
To see which IPs have been banned, use:
fail2ban-client status wordpress-auths
Fail2ban will now block IP addresses that exceed the maximum number of allowed login attempts.
Using Fail2ban with Cloudflare Proxy
If you use Cloudflare as a proxy for your website, Fail2ban may incorrectly block Cloudflare’s IP addresses instead of the real IP addresses of the attackers. This is because Cloudflare hides the original IP addresses of visitors.
To fix this, you need to configure Nginx (or your web server) to correctly identify the real IP address of the visitors. This can be done by ensuring that Cloudflare’s proxy headers are used to restore the real IP.
Step 1: Restore Visitor IP with Cloudflare
You can configure Nginx to restore the visitor’s original IP address by using a pre-configured option for Cloudflare in your Nginx settings. Add the following to your Nginx configuration:
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
real_ip_header CF-Connecting-IP;
This configuration ensures that Nginx will correctly interpret the real IP addresses from Cloudflare’s headers.
Step 2: Use Cloudflare API to Ban IPs
To automate IP banning through Cloudflare, create a Fail2ban action that will trigger Cloudflare to block malicious IP addresses. First, generate your Cloudflare API token, then create the Fail2ban action configuration:
nano /etc/fail2ban/action.d/cloudflare.conf
Paste the following configuration, replacing the placeholders with your actual Cloudflare API token and email address:
# Cloudflare API action configuration
After saving the configuration, modify your jail.local
file to use the new action:
action = cloudflare
iptables-allports
Restart Fail2ban to apply the changes:
systemctl restart fail2ban
Fail2ban will now automatically block malicious IP addresses using Cloudflare’s firewall, even if they are behind the proxy.
Conclusion
Using Fail2ban with WordPress is an excellent way to secure your site from brute force attacks and unauthorized login attempts. By following the steps outlined in this guide, you can easily set up Fail2ban on your WordPress site and integrate it with Cloudflare for enhanced protection.
With Fail2ban in place, your WordPress site will be shielded from malicious login attempts, and by utilizing Cloudflare’s firewall, you’ll prevent legitimate traffic from being affected. This setup ensures that your site remains secure and performs optimally, even when under attack.