Adding the action
If you’ve read my other fail2ban guides you already know I’m using linuxservers swag container. So there won’t be any walkthrough of installing fail2ban. I will only go through the cloudflare configuration.
Go to your appdata location and find the action.d
folder appdata/swag/fail2ban/action.d
Create a new file called
cloudflare-apiv4.conf
and add the following:#
# Author: Gilbn from https://technicalramblings.com
# Adapted Source: https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf and https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide/
#
# To get your Cloudflare API key: https://dash.cloudflare.com/profile use the Global API Key
#
[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 <name>"}'
# 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 '"' | sed -e 's/^[ \t]*//' | head -n 1)" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json"
[Init]
# Name of the jail in your jail.local file. default = [jail name]
name = default
# Option: cfuser
# Notes.: Replaces <cfuser> in actionban and actionunban with cfuser value below
# Values: Your CloudFlare user account
cfuser = [email protected]
# Option: cftoken (Global API Key)
# Notes.: Replaces <cftoken> in actionban and actionunban with cftoken value below
# Values: Your CloudFlare API key
cftoken = YOUR-API-KEY
The unban curl command from https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide/ did not work for me but changing it to what this user on serverfault shared did https://serverfault.com/a/912547
Use the “Global API Key“
Updating jail.local
Next is updating or adding your jails in the jail.local file. Go to your appdata location appdata/swag/fail2ban/
and edit the file called jail.local.
The only thing you really need to add is the action fail2ban will run after it has banned an IP.
Add action = cloudflare-apiv4
in the jails you want to use it on. For me that would be all the jails.
Example:
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
action = cloudflare-apiv4
iptables-allports
port = http,https
logpath = /config/log/nginx/error.log
ignoreip = 192.168.1.0/24
[organizrv2-auth]
enabled = true
filter = organizrv2-auth
action = cloudflare-apiv4
iptables-allports
port = http,https
logpath = /fail2ban/organizrLoginLog.json
ignoreip = 192.168.1.0/24
Optional: Specifying which site the ban works on
If you have several sites on your Cloudflare account and you want to specify which one the action should work on, you need to change the URL on the actionban line.
Instead of user it needs to say /zones/ and then your zone ID.
actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/zones/YOUR-CLOUDFLARE-ZONE-ID/firewall/access_rules/rules" \
And the same on the actionunban line:
actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/YOUR-CLOUDFLARE-ZONE-ID/firewall/access_rules/rules/$( \
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/YOUR-CLOUDFLARE-ZONE-ID/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=1.2.3.4&page=1&per_page=1&match=all" \
Your zone ID can be found on the overview page on Cloudflare.
I recommend adding a whitelist on your WAN IP so you don’t accidently ban yourself!
You can add the whitelist on Cloudflare by going to Firewall and then Tools. There you can add the access rule.
Nginx
Next up is configuring nginx so that it won’t just ban the Cloudflare CDN IP but the actual IP of the visitor.
For any questions you can find me here:
Sources:
Tronyx 😘 Thank you Tronyx for creating the first draft of the guide.
https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide