Fail2Ban Guide
For Laravel, WordPress, # Node.js, and Sensitive Files
August 29, 2025
ValentaizarHitsukaya
ValentaizarHitsukaya
1. Install Fail2Ban
On a CentOS / AlmaLinux / RHEL system:
sudo dnf install fail2ban -ysudo systemctl enable --now fail2ban2. Create the Fail2Ban Filter
Create a custom filter for scanning attacks:
sudo nano /etc/fail2ban/filter.d/web-scan.confAdd the failregex content
[Definition]
failregex = ^<HOST> -.*"(GET|POST) .*\.env.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.git.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.htaccess.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.htpasswd.*HTTP.*"
^<HOST> -.*"(GET|POST) .*wp-admin.*HTTP.*"
^<HOST> -.*"(GET|POST) .*wp-login\.php.*HTTP.*"
^<HOST> -.*"(GET|POST) .*setup-config\.php.*HTTP.*"
^<HOST> -.*"(GET|POST) .*artisan.*HTTP.*"
^<HOST> -.*"(GET|POST) .*vendor/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*storage/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*bootstrap/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*config/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*uploads/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*package\.json.*HTTP.*"
^<HOST> -.*"(GET|POST) .*package-lock\.json.*HTTP.*"
^<HOST> -.*"(GET|POST) .*yarn\.lock.*HTTP.*"
^<HOST> -.*"(GET|POST) .*next\.config\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*nuxt\.config\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*tsconfig\.json.*HTTP.*"
^<HOST> -.*"(GET|POST) .*vue\.config\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*server\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*app\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.next/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.nuxt/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*Dockerfile.*HTTP.*"
^<HOST> -.*"(GET|POST) .*docker-compose\.yml.*HTTP.*"
^<HOST> -.*"(GET|POST) .*webpack\.config\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*vite\.config\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*gulpfile\.js.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.bak.*HTTP.*"
^<HOST> -.*"(GET|POST) .*\.old.*HTTP.*"
^<HOST> -.*"(GET|POST) .*backup/.*HTTP.*"
^<HOST> -.*"(GET|POST) .*api(/private|/admin)?.*HTTP.*"
ignoreregex =Explanation:
failregexmatches requests to sensitive files, configuration files, Laravel/WordPress endpoints, and API admin paths.ignoreregexis empty, meaning no exceptions are ignored.
3. Create the Jail
Create a jail configuration:
sudo nano /etc/fail2ban/jail.d/web-scan.local[web-scan]
enabled = true
filter = wen-scan
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 600
bantime = 14400Parameters Explained:
maxretry = 3→ Ban after 3 failed attempts.findtime = 600→ Track failed attempts within 10 minutes.bantime = 14400→ Ban duration is 4 hour.
4. Reload Fail2Ban
sudo fail2ban-client reload
sudo fail2ban-client status web-scanVerify that the jail is active and monitoring your logs.
5. Testing Your Filter
Simulate an attack:
curl http://yourdomain.com/.env
curl http://yourdomain.com/wp-login.phpCheck Fail2Ban logs:
sudo tail -f /var/log/fail2ban.logYou should see your IP being banned after maxretry attempts.
6. Monitoring and Managing Banned IPs
Check currently banned IPs:
sudo fail2ban-client status web-scanUnban an IP:
sudo fail2ban-client set web-scan unbanip <IP>7. Summary
This Fail2Ban setup protects your web server from:
Brute-force attacks on WordPress and Laravel
Unauthorized access attempts to
.env,.git,.htaccess, and config filesAPI endpoint scans
Node.js/Next.js/Nuxt.js sensitive file access attempts
Section | Details |
|---|---|
Filter | |
Currently failed: 0 | |
Total failed: 0 | |
Journal matches: | |
Actions | |
Currently banned: 0 | |
Total banned: 0 | |
Banned IP list: |