Open Source · MIT · for cPanel + CSF Servers

Block Server Abuse Behind Cloudflare — Without Taking Your Own Sites Down

Swatter reads your web logs, scores every IP on behavioral signals plus threat-intel, and blocks attackers on the right firewall plane: CSF for direct-to-origin — even a valid-Host bypass that found your origin IP — and a Cloudflare managed challenge for proxied. It can never firewall a Cloudflare edge or lock out a real visitor.

Free & open source · Bash + awk on cron · no daemon, no agent, no phone-home

The Trap It Exists to Avoid

Behind Cloudflare, your logs show the real visitor IP — but the TCP socket your firewall sees is a Cloudflare edge. Ban the logged IP with fail2ban and nothing happens. Ban a Cloudflare range by mistake and every site on the box goes dark. The trap runs both ways: an attacker who finds your origin IP can hit :443 directly with a valid Host header and look exactly like proxied traffic — so a naive blocker fires a useless edge challenge while the flood keeps landing. Swatter is built around deciding, per attacker, which side of the proxy they're really on — reading the live socket, not just the logs — and sending the block where it actually works.

Safety-First by Design

The Right Plane, Every Time

Direct-to-origin scanners are blocked at CSF, where the socket really is the attacker. Proxied offenders get a Cloudflare managed challenge by default — a false positive solves a challenge, never a lockout. Ambiguous traffic defaults to the safe plane.

Catches the Valid-Host Bypass

Find your origin IP, hit :443 with a real Host header, and you look proxied — to everyone but Swatter. It reads the live TCP socket: a peer that isn't a Cloudflare edge is provably direct and goes straight to CSF, even mid-flood.

Never-Block Rails

Cloudflare's ranges are a hardcoded never-block set re-checked before every single block — and if the range list goes stale, Swatter fails closed rather than risk an outage.

Four Postures, Auto-Detected

auto detects whether the box sits behind Cloudflare and adapts daily — zero config on a bare CSF server. Run your own edge WAF? skip hands the proxied realm to you and keeps Swatter on the raw-IP scanners your rules never see.

Failure Evidence Required

Visiting wp-login.php isn't a crime — your clients do it daily. Brute-force blocks require repeated failed attempts, so a site owner working in wp-admin can never be swatted.

Temp Before Perm

First offense earns a temporary block on a rising TTL ladder. Permanent bans are earned by repeat offenses across days — one anomalous burst can't blackhole a shared IP.

Full Audit Trail

swatter why <ip> shows the exact evidence behind any decision. Report-only by default: watch it for a week before letting it act.

Nothing to Install, Really

Bash + awk on a cron. No daemon, no agent, no compiled dependencies, no phone-home. Optional free threat-intel (AbuseIPDB, Spamhaus, ipsum) and a nightly HTML digest of blocks and server errors — delivered via sendmail, SendGrid, or Brevo.

How It Works

  1. Ingest & Score

    Every few minutes Swatter reads your Apache domlogs and scores each IP on weighted signals — request rate, error bursts, path fanout, bad-path probes, threat-intel reputation.

  2. Classify the Plane

    Offenders above the threshold are classified direct-to-origin or via-Cloudflare — from the logs and from live TCP sockets, so a valid-Host origin bypass can't masquerade as proxied — then checked one last time against the never-block set: Cloudflare ranges, your allowlist, monitoring services, verified crawlers.

  3. Block, Expire, Report

    Blocks land on the right plane with a TTL and are swept when they expire. Repeat offenders escalate toward permanent. A nightly digest tells you everything it did and why.

Frequently Asked Questions

Why Can't fail2ban Block Attackers Behind Cloudflare?

Behind Cloudflare, your logs show the real visitor IP but the actual TCP socket is a Cloudflare edge IP. When fail2ban tells iptables to ban the logged address, the ban does nothing — the attacker isn't connecting to you, Cloudflare is. Worse, banning an IP that turns out to be a Cloudflare range firewalls Cloudflare itself and takes every site on the server down.

How Does Swatter Block Attackers Without Firewalling Cloudflare?

It classifies every offender as direct-to-origin or via-Cloudflare — from the logs and from live TCP sockets. Direct attackers are blocked at CSF; proxied attackers get a Cloudflare managed challenge by default via the IP Access Rules API, so a false positive means a human solves a challenge, not a lockout. Cloudflare's own ranges are a hardcoded never-block set checked before every block, and if the range list goes stale Swatter fails closed.

What About Attackers That Bypass Cloudflare and Hit My Origin Directly?

If someone discovers your server's real IP, they can connect straight to :443 with a valid Host header and look exactly like proxied traffic in your logs — and a naive blocker answers with a useless edge challenge while the flood keeps landing. Swatter also inspects the live TCP socket: a peer on your web ports that isn't a Cloudflare edge is provably direct, so it's sent to CSF where the block actually bites — even mid-flood.

Will It Block My Own Customers Logging into WordPress?

Brute-force detection requires failure evidence — error responses or POST floods — not mere visits to sensitive paths. A site owner logging in and working in wp-admin produces successful requests and can't trip it. You can also guarantee specific IPs with swatter allow, and it ships report-only so you review decisions before it acts.

What Does It Require?

A cPanel/Apache server with CSF (AlmaLinux, CentOS, RHEL), gawk, and flock. Optionally jq + curl for threat-intel and the Cloudflare API, and sqlite3 for the state store. Not behind Cloudflare? It works as a straightforward CSF auto-blocker too.

Is It Free?

Yes — MIT licensed. The code, docs, and issue tracker are on GitHub, with a full mirror on GitLab.

Get Swatter

Clone it, run it report-only for a week, then let it act. MIT licensed — issues and PRs welcome.