Comment Spam → Cloudflare Block
Block spam-comment IPs at Cloudflare's edge for Cloudflare-proxied WordPress sites. Complements WP fail2ban.
by Duelling Pixels · github.com/duellingpixels/dp-cloudflare-spam-block · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/duellingpixels/dp-cloudflare-spam-block/archive/refs/heads/main.zipReadme
Comment Spam → Cloudflare Block
Automatically block spam-comment IPs at Cloudflare's edge — where they can actually be stopped — instead of at the server firewall, which is ineffective on Cloudflare-proxied WordPress sites.
When a comment is marked as spam (by Akismet or by hand), this plugin adds the commenter's real IP to a Cloudflare IP Access Rule (Block) via the Cloudflare API. The bot is stopped at Cloudflare before it reaches WordPress again.
- Requires: WordPress 5.6+, PHP 7.4+, a site proxied through Cloudflare
- License: GPL-2.0-or-later
- Stable version: 1.0.0
Why this exists
On a site behind Cloudflare, every request reaches your origin server from
Cloudflare's edge IPs — not from the visitor's real IP. So a server-level ban
(iptables, and by extension a stock fail2ban jail) never sees the attacker's
traffic and does nothing to stop it.
WordPress, however, still knows the real visitor IP (assuming your origin restores it — GridPane and most hosts do this automatically). This plugin uses that real IP and pushes the block to the one layer that works: Cloudflare itself.
It is designed to complement WP fail2ban, not replace it.
[!IMPORTANT] This plugin covers comment spam only. WP fail2ban still detects login brute-force, user enumeration, pingbacks, etc., but behind Cloudflare those bans are enforced with iptables and remain ineffective at the edge. Closing that gap for the other categories requires routing fail2ban's ban action to Cloudflare at the server level — a separate piece of work this plugin does not do.
Features
- Blocks spam-comment IPs at Cloudflare automatically (IPv4 and IPv6).
- Choose the trigger: any spam, or auto-detected spam only (e.g. Akismet).
- Blocks auto-expire after a configurable number of days (default 90) via a
daily task, so the block list never grows without bound. Set to
0to keep them forever. - "Blocked IPs" admin screen with one-click unblock.
- "Test connection" button that verifies the token, the zone, and that
block rules can actually be created (it creates and immediately deletes a rule
for the reserved test IP
192.0.2.1). - Safety guard: refuses to block any address inside Cloudflare's own IP ranges, so a mis-configured origin can never blackhole Cloudflare's edge.
- Duplicate reconciliation: if an IP is already blocked in Cloudflare (e.g. a leftover rule), the plugin adopts the existing rule instead of erroring.
- API token can live in
wp-config.php(DPCSB_CF_API_TOKEN) instead of the database.
Installation
- Download the latest
dp-cloudflare-spam-block-x.y.z.zip. - In WordPress: Plugins → Add New → Upload Plugin → choose the zip → Install Now → Activate.
(Or copy the dp-cloudflare-spam-block folder into wp-content/plugins/.)
Configuration
1. Create a scoped Cloudflare API token
Cloudflare dashboard → My Profile → API Tokens → Create Token → Custom token:
| Permission | Level | Access |
|---|---|---|
| Firewall Services | Zone | Edit |
| Zone | Zone | Read |
Scope it to the zone (domain) for this site under Zone Resources.
2. Find your Zone ID
Cloudflare dashboard → your domain → Overview → the API box in the right-hand sidebar → Zone ID.
3. Enter and test
Settings → "Spam → Cloudflare": paste the token and Zone ID, save, then click Test Cloudflare connection. A result of "Connected, and block permissions confirmed" means you're done — there is nothing to configure on the Cloudflare side; the plugin manages the block rules itself.
Optional: store the token in wp-config.php
define( 'DPCSB_CF_API_TOKEN', 'your-cloudflare-api-token' );
When this constant is set, the token field in the settings screen is disabled and the constant is used instead.
Usage
Once configured, it runs automatically. Any comment that becomes spam results
in its IP being blocked at Cloudflare.
- View / remove blocks: Tools → Blocked IPs — lists every IP this plugin has blocked, with a one-click Unblock action.
- In Cloudflare: blocks appear under Security → WAF → Tools (IP Access Rules).
How it works
- Hooks the same comment events WP fail2ban uses:
comment_post(born-spam, e.g. Akismet at submission) andtransition_comment_status(manual "mark as spam" / Akismet recheck). - Reads the real commenter IP from
comment_author_IP, validates it (skips private/reserved ranges, the server's own IP, and Cloudflare's ranges), and de-duplicates against a local table. - Calls the Cloudflare API to create a block IP Access Rule for the zone.
- Records the rule locally so it can be listed, unblocked, and pruned.
- A daily task removes rules older than the retention window.
Developer notes
Filters and actions:
| Hook | Type | Purpose |
|---|---|---|
dpcsb_should_block |
filter | Return false to veto a block. Receives ( bool $should, string $ip, WP_Comment $comment ). |
dpcsb_cloudflare_ranges |
filter | Override the Cloudflare CIDR list used by the safety guard. |
dpcsb_ip_blocked |
action | Fires after a successful block. Receives ( string $ip, string $rule_id, int $comment_id ). |
Uninstalling removes the plugin's option and database table but intentionally leaves existing Cloudflare rules in place, so an accidental removal doesn't silently unblock everyone.
FAQ
Does this replace WP fail2ban? No. See the note above — it fixes comment-spam blocking at the edge; the other attack categories still need the server-side fail2ban→Cloudflare action.
Will it block legitimate visitors? Only IPs attached to comments that WordPress/Akismet classified as spam. It also refuses to block Cloudflare's own IPs as a safety net.
What if I'm not behind Cloudflare? Then blocks won't take effect (and the origin may not have real visitor IPs). This plugin is specifically for Cloudflare-proxied sites.
Changelog
1.0.0
- Initial release.
License
GPL-2.0-or-later. See LICENSE.
Built by Duelling Pixels.