Adding Cloudflare to the mix of ServerPilot and fail2ban

This guide looks at adding Cloudflare to a set up of ServerPilot and fail2ban with a WordPress jail set up.

Once you start using Cloudflare as a CDN solution for your hosting, you are adding another firewall into the equation, albeit a very good one, but you may want to pass your servers local firewall fail2bans IP blocks over to Cloudflare and keep the two firewalls synchronised. This guide is using ServerPilot/fai2ban on a Vultr instance but similar hosting will be the same.

2 problems need to be overcome, the first is the transparency of Cloudflares IP addresses and the second is pushing the fail2ban IP bans on your server firewall over to the Cloudflare firewall.

Reveal True IP Addresses

Cloudflare wraps a visitors IP address in its own address, this can cause issues with the fail2ban IP rules as you may be blocking the wrong addresses, so the real IPs need to be revealed – this is referenced on the Cloudflare site, and has a number of solutions for different web serving apps.

ServerPilot uses nginx as a front end tool and have already made these changes in their nginx config. Check /etc/nginx-sp/nginx.conf 

 # CloudFlare proxy addresses.
 # Do not modify this list. If you believe the CloudFlare proxy address list is
 # out of date, please contact [email protected]
 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;
 set_real_ip_from 104.16.0.0/12;
 set_real_ip_from 108.162.192.0/18;
 set_real_ip_from 131.0.72.0/22;
 set_real_ip_from 141.101.64.0/18;
 set_real_ip_from 162.158.0.0/15;
 set_real_ip_from 172.64.0.0/13;
 set_real_ip_from 173.245.48.0/20;
 set_real_ip_from 188.114.96.0/20;
 set_real_ip_from 190.93.240.0/20;
 set_real_ip_from 197.234.240.0/22;
 set_real_ip_from 198.41.128.0/17;
 set_real_ip_from 199.27.128.0/21;
 set_real_ip_from 2400:cb00::/32;
 set_real_ip_from 2405:8100::/32;
 set_real_ip_from 2405:b500::/32;
 set_real_ip_from 2606:4700::/32;
 set_real_ip_from 2803:f800::/32;
 set_real_ip_from 2c0f:f248::/32;
 set_real_ip_from 2a06:98c0::/29;
 real_ip_header X-Forwarded-For;

So that’s great – already done here, if you are not using ServerPilot look at the earlier referenced link for a solution.

Pushing fail2ban IP rules to Cloudflare

For every fail2ban jail client you set up, as in the one set up for wordpress-hard you can add an action when the fail2ban rule is triggered, there is a whole bunch of actions in /etc/fail2ban/action.d/ directory including a cloudflare.conf one, which synchronises your local firewall to the Cloudflare one.

However the one supplied is not using the new Cloudflare v4 API and will fail to work, but this script does work from Mike Andreasen @ WP Bullet Guides does work with v4.

#
# Author: Mike Andreasen from https://guides.wp-bullet.com
# Adapted Source: https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf
# Referenced from: https://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE
#
# To get your Cloudflare API key: https://www.cloudflare.com/my-account
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: IP address
# number of failures
# unix timestamp of the ban time
# Values: CMD
actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json" \
--data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"Fail2ban"}'
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: IP address
# number of failures
# unix timestamp of the ban time
# Values: CMD
#
actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$( \
curl -s -X GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=<ip>&page=1&per_page=1&match=all" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' | tr -d '"' | head -n 1)" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json"
[Init]
# Option: cfuser
# Notes.: Replaces <cfuser> in actionban and actionunban with cfuser value below
# Values: Your CloudFlare user account
cfuser = put-your-cloudflare-email-here
# Option: cftoken
# Notes.: Replaces <cftoken> in actionban and actionunban with cftoken value below
# Values: Your CloudFlare API key
cftoken = put-your-API-key-here
view raw cloudflare.conf hosted with ❤ by GitHub

You just rename/backup the old cloudflare.conf and add in the new one above and add in your Cloudflare username/email and API key at the bottom where indicated on lines 67 & 73.

Then you reference the action in your jail.local file under the WordPress defined jail.

[wordpress-hard]
enabled = true
filter = wordpress-hard
logpath = /var/log/auth.log
maxretry = 3
port = http,https
action = cloudflare

Restart fail2ban

service fail2ban restart

Now you will see your Cloudflare firewall updated with your ServerPilots fail2ban banned IP addresses and if you unban addressess they will also be sync’ed.

So if you unban an IP address at your server firewall (example below uses our wordpress_hard jail…

fail2ban-client set wordpress-hard unbanip 1.2.3.4

It will be sync’ed to Cloudflare so also removed there.

ref and ref

Leave a Comment





%d bloggers like this: