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.