When you're running a public-facing web application—especially one routed through a Cloudflare Tunnel—security is paramount. While tunnels hide your server’s IP, bots and malicious actors still hammer away at exposed endpoints. That’s where Fail2Ban helps reinforce your defenses.
Cloudflare is a global network platform that sits between your website visitors and your web server. When you use Cloudflare, your website’s DNS is pointed to Cloudflare’s servers. This means all incoming web traffic first passes through Cloudflare’s network before reaching your actual server.
Cloudflare Tunnel (formerly Argo Tunnel) provides a secure, outbound-only connection from your internal server to Cloudflare’s global network. It acts as a first line of defense by masking your server’s true IP and minimizing the attack surface.
When you combine Cloudflare with tools like Fail2Ban, you get layered protection: Cloudflare filters and blocks threats at the network edge, while Fail2Ban monitors your application for suspicious activity and can trigger Cloudflare to block abusive IPs in real time. This synergy helps keep your web application secure, fast, and reliable.
Fail2Ban is an intrusion prevention tool that helps protect your server from brute-force attacks and other malicious activity. It works by continuously monitoring log files generated by services like SSH, web servers, or mail servers.
Fail2Ban uses a set of configurable filters—regular expressions that match specific patterns in log entries, such as repeated failed login attempts, suspicious HTTP requests, or known attack signatures. When a filter detects a pattern that matches its rules, Fail2Ban considers it a trigger event.
Each filter is paired with a jail, which defines what action to take when a trigger event occurs. Common actions include updating firewall rules to block the offending IP address for a set period, sending notifications, or, as in this setup, calling Cloudflare’s Firewall API to block the IP at the network edge.
By automating the detection and response to suspicious activity, Fail2Ban helps reduce the risk of successful attacks and minimizes manual intervention.
Even with your origin hidden behind a Cloudflare Tunnel, bots can reach exposed routes via your public hostname. I saw repeated scraping attempts and malformed requests hitting my endpoints. Here’s how I automated the blocking process using Fail2Ban and Cloudflare’s API. You can find these examples on Github.
IP="$1"
ZONE_ID=$(cat /etc/cloudflare/ZONE_ID)
API_TOKEN=$(cat /etc/cloudflare/API_TOKEN)
DATE_MMDDYY=$(TZ=America/New_York date +"%m/%d/%y")
TIME_HHMMSS=$(TZ=America/New_York date +"%H:%M:%S")
ASN=$(whois "$IP" | grep -iE 'origin:|OriginAS:' | grep -Eo 'AS[0-9]+' | head -n1)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/access_rules/rules" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"mode": "block",
"configuration": {
"target": "ip",
"value": "'"$IP"'"
},
"notes": "Blocked by fail2ban on '"$DATE_MMDDYY $TIME_HHMMSS"' (ASN: '"$ASN"')"
}'
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = /usr/local/bin/fail2ban-cloudflare-ban.sh <ip>
actionunban =
[cloudflared-endpoint]
enabled = true
port = http,https
filter = cloudflared-abuse
logpath = /var/log/nginx/access.log
action = cloudflare-ban[name=cloudflare-ban]
maxretry = 10
findtime = 86400 # 1 day
This configuration ensures that persistent abuse against your tunneled service results in an IP block—enforced at the Cloudflare edge before malicious requests touch your server.
Here’s how it works in detail: Fail2Ban continuously monitors your service’s log files for suspicious patterns, such as repeated failed logins or malformed requests. When it detects an IP address that matches these patterns, it triggers a jail—a set of rules specifying what to look for and what action to take.
In this setup, the jail is configured to call a custom script whenever a rule is triggered. The script receives the offending IP address as an argument. It then uses the Cloudflare API to add a firewall rule that blocks this IP at the Cloudflare edge. This means any future requests from that IP are stopped by Cloudflare and never reach your server or tunnel.
This automated process helps protect your service by quickly identifying and blocking abusive IPs, reducing the risk of successful attacks and minimizing manual intervention.
Imagine your website is like a treehouse with a secret ladder. You want your friends to visit, but you don’t want sneaky robots or strangers climbing up when you’re not looking. So, you use Cloudflare, like a friendly robot gatekeeper, who checks everyone before they get to your ladder. Then, you also use Fail2Ban, which is like a watchful owl sitting in the tree—if it sees someone doing something suspicious over and over, like shaking the ladder or poking at the door, it hoots and triggers a trap that blocks them from coming back. Together, they help you keep your treehouse safe, fun, and only for the people you trust.
I served in the U.S. Army, specializing in Network Switching Systems and was attached to a Patriot Missile System Battalion. After my deployment and Honorable discharge, I went to college in Jacksonville, FL for Computer Science. I have two beautiful and very intelligent daughters. I have more than 20 years professional IT experience. This page is made to learn and have fun. If its messed up, let me know. Im still learning :)