Apps

Fail2ban for WordPress Login & XML-RPC (custom filter)

4 min · updated June 14, 2026

WordPress has no built-in Fail2ban filter. The two reliable approaches:

Option A — custom access-log filter (no plugin)

Ban IPs that repeatedly POST to wp-login.php or xmlrpc.php.

Create /etc/fail2ban/filter.d/wordpress-hard.conf:

[Definition]
failregex = ^<HOST> .*"POST .*/wp-login\.php
            ^<HOST> .*"POST .*/xmlrpc\.php
ignoreregex =

Add the jail in /etc/fail2ban/jail.local (Nginx path shown; use the Apache access log if you run Apache):

[wordpress-hard]
enabled  = true
filter   = wordpress-hard
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 5
findtime = 5m
bantime  = 1d

This matches every login POST, not just failed ones, so a legitimate user who mistypes their password a few times can be banned. Keep maxretry reasonable (5), and whitelist your own IP.

Option B — WP fail2ban plugin (recommends, distinguishes pass/fail)

Install the WP fail2ban plugin; it logs auth events to syslog so Fail2ban bans only on failed logins. Then use its bundled filter:

[wordpress-soft]
enabled  = true
filter   = wordpress-soft
logpath  = /var/log/auth.log
maxretry = 5
bantime  = 1h

(The plugin ships wordpress-hard.conf / wordpress-soft.conf filters; copy them into /etc/fail2ban/filter.d/ as its docs describe.)

Reload and verify

sudo fail2ban-client reload
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-hard.conf
sudo fail2ban-client status wordpress-hard

Block xmlrpc entirely? If you don’t use the XML-RPC API (Jetpack, the mobile app, pingbacks), blocking /xmlrpc.php at the web server is even cheaper than banning — but the jail above is a good catch-all when you can’t.

← All recipes