Auto-Ban WordPress Scanners with NGINX and Fail2ban (With Nested Path Detection)

April 30, 2025
fail2bannginxsecuritybotsregexipv6self-hosting

Auto-Ban WordPress Scanners with NGINX and Fail2ban (With Nested Path Detection)

After seeing repeated bot scans for WordPress paths on my static site, I created a honeypot trap using NGINX and Fail2ban. This guide now includes support for nested paths like /wordpress/wp-admin/..., which many bots use.

๐Ÿ”ง Step 1: NGINX Honeypot Logging

Update your server block (e.g. /etc/nginx/sites-available/shanahjr.com):

location ~* /(wp-admin|wp-login|wp-includes|xmlrpc\.php|wlwmanifest\.xml|setup-config\.php) {
    access_log /var/log/nginx/wp-honeypot.log;
    return 404;
}

Reload NGINX:

sudo nginx -t && sudo systemctl reload nginx

๐Ÿ” Step 2: Fail2ban Jail Configuration

Jail file: /etc/fail2ban/jail.d/nginx-wp-scanner.local

[nginx-wp-scanner]
enabled  = true
filter   = nginx-wp-scanner
logpath  = /var/log/nginx/wp-honeypot.log
backend  = auto
bantime  = 86400
findtime = 600
maxretry = 1
action   = iptables-multiport[name=WPScanner, port="http", protocol=tcp]

๐Ÿง  Step 3: Filter for Nested Paths

Filter file: /etc/fail2ban/filter.d/nginx-wp-scanner.conf

[Definition]
failregex = ^<HOST> - - \[.*?\] "GET .*/(wp-admin|wp-login|wp-includes|xmlrpc\.php|wlwmanifest\.xml|setup-config\.php).*" 404
ignoreregex =

This pattern matches:

  • /wp-admin/...
  • /wordpress/wp-admin/...
  • /blog/wp-includes/...
  • And any prefix variation

๐Ÿšฆ Step 4: Restart and Test

sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-wp-scanner

Try a simulated attack:

curl -A "Mozilla/5.0" http://yourdomain.com/wordpress/wp-admin/setup-config.php

Or manually inject a line to test:

echo '1.2.3.4 - - [30/Apr/2025:06:45:00 +0000] "GET /wordpress/wp-admin/setup-config.php HTTP/1.1" 404 0 "-" "Mozilla/5.0"' | sudo tee -a /var/log/nginx/wp-honeypot.log
sudo fail2ban-client reload

Check ban list:

sudo fail2ban-client status nginx-wp-scanner

๐Ÿงช Debug Tips

Check logpath is monitored

sudo fail2ban-client get nginx-wp-scanner logpath

You should see: /var/log/nginx/wp-honeypot.log

Test regex manually

sudo fail2ban-regex /tmp/fb-test.log /etc/fail2ban/filter.d/nginx-wp-scanner.conf

Force NGINX to flush logs

sudo kill -USR1 $(pidof nginx)

โœ… Result

You're now auto-banning both IPv4 and IPv6 scanners attempting WordPress entry points, no matter how deep they're nested.

Want to build a dashboard or notifications? I've got that queued up next.