This project integrates Fail2Ban with Cloudflare Security Rules to block malicious IP addresses by managing the Cloudflare custom IP list. It uses a Bash script to add or remove IPs from a Cloudflare blocklist, triggered by Fail2Ban to detect and ban IPs after failed login attempts (e.g., SSH, FTP, WordPress or Home Assistant, etc.). The project is designed for Cloudflare's free tier, which allows 1 custom IP list with a maximum of 10,000 IP addresses, and is inspired by the Python-based approach in Using Fail2Ban with Cloudflare on a free account by Kovasky Buezo.
- Automatically bans IPs after exceeding failed login attempts (configurable via Fail2Ban jails).
- Manages a Cloudflare custom IP list (up to 10,000 IPs) using the Lists API, compatible with free-tier accounts.
- Supports IPv4 and IPv6 (with optional
/64subnet blocking for IPv6). - Lightweight Bash implementation with minimal dependencies: using
curlandjqfor API interactions. - Integrates with Fail2Ban actions for seamless automation.
-
Set Up Cloudflare:
-
Log in to your Cloudflare dashboard.
-
Navigate to My Profile > API Tokens > Create a Token > Create a Custom Token.
-
Name the token (e.g.,
fail2ban) and grant permissions: -
Save the token securely.
-
Go to Manage Account > Configurations > Lists.
-
Create a new list with:
-
Save the List ID and your Account ID from the dashboard or API. You can obtain this data from the URL when editing the list. The URL looks like:
https://dash.cloudflare.com/<user id>/configurations/lists/<list id>
-
-
Install Fail2Ban (if not installed):
sudo apt update && sudo apt install fail2ban -
Install Dependencies: Install
curlandjq:sudo apt update && sudo apt install curl jq -
Set Up Scripts:
Place
cloudflare-list.shandcloudflare-list.confin/etc/fail2ban/action.d/. For Docker-based Fail2Ban installation put them in/data/action.d/and adjust the paths incloudflare-list.conf.
-
Cloudflare Security Rule:
-
Fail2Ban Jail:
- Add the
cloudflare-listaction to your jail, for example, for SSH jail add it to theactionline (edit/etc/fail2ban/jail.localor/etc/fail2ban/jail.d/sshd.conf):[sshd] enabled = true maxretry = 3 bantime = 2h findtime = 10m # NEW LINE GOES HERE: # First line is the default ban action, the second line is this Cloudflare list action action = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] cloudflare-list
- Adjust
maxretry,bantime, andfindtimeas needed. Add other jails (e.g., for Nginx) if required.
- Add the
-
Configure
cloudflare-list.sh:- Edit
/etc/fail2ban/action.d/cloudflare-list.shto include your Cloudflare credentials:- Account ID: Your Cloudflare account ID.
- List ID: The ID of the
block_list. - API Token: The token created earlier.
- Edit
- Follow the Installation and Configuration steps.
- Test the script:
sudo /etc/fail2ban/action.d/cloudflare-list.sh 192.168.100.100 add
- Verify the Cloudflare list in the dashboard should now contain the specified IP.
- Remove the IP from Cloudflare list:
sudo /etc/fail2ban/action.d/cloudflare-list.sh 192.168.100.100 del


