If you run WordPress long enough, two things are guaranteed: constant probing and repeated credential abuse. The key is to automate response without creating brittle rules or drowning in noise.
A layered pattern that works
Our stack uses three linked layers:
- Fail2Ban jails to detect attack behavior from logs.
- ipset + iptables for fast local blocking at the network layer.
- AbuseIPDB reporting to share abusive IP intelligence with context.
What we detect for WordPress
- Repeated
POST /wp-login.phpattempts. POST /xmlrpc.phpabuse patterns.- User enumeration bursts such as
/wp-json/wp/v2/users/*. - Common scanner probes for secrets and backup artifacts.
Why local blocking still matters behind a proxy
Even with edge protection, origin-level blocking remains valuable. It reduces origin load immediately and gives you deterministic control during edge rule changes or cache/proxy transitions.
AbuseIPDB enrichment and redaction
When a jail bans an IP, we report it with:
- A jail-specific category and comment.
- Matched evidence from Fail2Ban.
- Redaction before comment submission to avoid leaking sensitive details.
This keeps reports useful while minimizing sensitive exposure.
Repeat offenders
Enable a recidive jail to escalate repeat offenders across jails. This catches actors that spread activity across multiple vectors (SSH, login abuse, scanner paths) and applies longer bans automatically.
Operational checks to keep it healthy
- Confirm every jail has both local block action and AbuseIPDB action.
- Verify no API key failures in reporting logs.
- Test filters against real logs with
fail2ban-regex. - Review false positives regularly and tune
maxretry/findtime.
Bottom line
Fail2Ban + ipset + AbuseIPDB gives WordPress operators a practical, production-safe response loop: detect quickly, block locally, share intelligence, and escalate repeat offenders automatically.
Further reading: WordPress XML-RPC Docs
Related posts: