diff --git a/fail2ban/filter.d/badbot.conf b/fail2ban/filter.d/badbot.conf index 2d6ff08..f5198dd 100644 --- a/fail2ban/filter.d/badbot.conf +++ b/fail2ban/filter.d/badbot.conf @@ -1,15 +1,18 @@ [Definition] -# ── NPM access log format ───────────────────────────────────────────────────── -# PROXY_IP - - [DD/Mon/YYYY:HH:MM:SS +0000] "METHOD PATH HTTP/VER" STATUS BYTES "REFERER" "UA" [Client REAL_IP] +# ── NPM access log format (current) ────────────────────────────────────────── +# [DD/Mon/YYYY:HH:MM:SS +0000] - STATUS STATUS - METHOD SCHEME HOST "PATH" +# [Client REAL_IP] [Length N] [Gzip N] [Sent-to IP] "UA" "REFERER" # -# is placed at the [Client REAL_IP] position — this is the IP that gets -# banned, which is the real client IP forwarded by Cloudflare/CDN via X-Forwarded-For. +# fail2ban strips the timestamp before applying failregex, leaving: +# " - STATUS STATUS - METHOD SCHEME HOST "PATH" [Client IP] ... "UA" ..." +# +# UA appears after [Sent-to ...] so .* is used between and the UA match. # # Test against your logs: # fail2ban-regex /nginx-logs/proxy-host-1_access.log /etc/fail2ban/filter.d/badbot.conf # ───────────────────────────────────────────────────────────────────────────── -failregex = ^\S+ - - \[[^\]]+\] "\S+ [^"]*" \d{3} \d+ "[^"]*" "(?i:masscan|zgrab|python-requests|go-http-client/1\.1|nuclei|sqlmap|dirbuster|gobuster|nikto|wfuzz|metasploit|libwww-perl|wpscan|nmap|zmeu|jorgee|shodan\.com|censys|binaryedge|internet-measurement|netcraft|strikeready|dataforseo|semrushbot|ahrefsbot|mj12bot|dotbot)[^"]*" \[Client \] +failregex = - \d+ \d+ - \S+ \S+ \S+ "[^"]*" \[Client \].*"(?i:masscan|zgrab|python-requests|go-http-client/1\.1|nuclei|sqlmap|dirbuster|gobuster|nikto|wfuzz|metasploit|libwww-perl|wpscan|nmap|zmeu|jorgee|shodan\.com|censys|binaryedge|internet-measurement|netcraft|strikeready|dataforseo|semrushbot|ahrefsbot|mj12bot|dotbot)[^"]*" ignoreregex = diff --git a/fail2ban/filter.d/http-errors.conf b/fail2ban/filter.d/http-errors.conf index 5a8ef73..65cc478 100644 --- a/fail2ban/filter.d/http-errors.conf +++ b/fail2ban/filter.d/http-errors.conf @@ -1,14 +1,20 @@ [Definition] -# ── NPM access log format ───────────────────────────────────────────────────── +# ── NPM access log format (current) ────────────────────────────────────────── +# [DD/Mon/YYYY:HH:MM:SS +0000] - STATUS STATUS - METHOD SCHEME HOST "PATH" +# [Client REAL_IP] [Length N] [Gzip N] [Sent-to IP] "UA" "REFERER" +# +# fail2ban strips the timestamp before applying failregex, leaving: +# " - STATUS STATUS - METHOD SCHEME HOST "PATH" [Client IP] ..." +# # Bans IPs generating excessive 4xx/5xx errors. # Default jail: 15 errors in 5 minutes (tunable in jail.local). # -# PROXY_IP - - [date] "METHOD PATH HTTP/VER" STATUS BYTES "REFERER" "UA" [Client REAL_IP] +# Test against your logs: +# fail2ban-regex /nginx-logs/proxy-host-1_access.log /etc/fail2ban/filter.d/http-errors.conf # ───────────────────────────────────────────────────────────────────────────── -failregex = ^\S+ - - \[[^\]]+\] "\S+ [^"]*" [45]\d\d \d+ "[^"]*" "[^"]*" \[Client \] +failregex = - [45]\d\d \d+ - \S+ \S+ \S+ "[^"]*" \[Client \] -# Exclude very common benign 404s to reduce noise. -# Remove these if you want to count ALL error responses. -ignoreregex = ^\S+ - - \[[^\]]+\] "\S+ /(?:favicon\.ico|robots\.txt|sitemap\.xml|apple-touch-icon[^"]*|\.well-known/[^"]*)[^"]*" 404 \d+ "[^"]*" "[^"]*" \[Client \] +# Exclude common benign 404s to reduce noise. +ignoreregex = - 404 \d+ - \S+ \S+ \S+ "/(?:favicon\.ico|robots\.txt|sitemap\.xml|apple-touch-icon[^"]*|\.well-known/[^"]*)" \[Client \] diff --git a/fail2ban/filter.d/npm-probe.conf b/fail2ban/filter.d/npm-probe.conf index 15c481a..931e81c 100644 --- a/fail2ban/filter.d/npm-probe.conf +++ b/fail2ban/filter.d/npm-probe.conf @@ -1,12 +1,19 @@ [Definition] -# ── NPM access log format ───────────────────────────────────────────────────── +# ── NPM access log format (current) ────────────────────────────────────────── +# [DD/Mon/YYYY:HH:MM:SS +0000] - STATUS STATUS - METHOD SCHEME HOST "PATH" +# [Client REAL_IP] [Length N] [Gzip N] [Sent-to IP] "UA" "REFERER" +# +# fail2ban strips the timestamp before applying failregex, leaving: +# " - STATUS STATUS - METHOD SCHEME HOST "PATH" [Client IP] ..." +# # Bans IPs probing for well-known vulnerable paths. # Default jail: 3 hits in 30 minutes → 48h ban (very aggressive, intentionally). # -# PROXY_IP - - [date] "METHOD PATH HTTP/VER" STATUS BYTES "REFERER" "UA" [Client REAL_IP] +# Test against your logs: +# fail2ban-regex /nginx-logs/proxy-host-1_access.log /etc/fail2ban/filter.d/npm-probe.conf # ───────────────────────────────────────────────────────────────────────────── -failregex = ^\S+ - - \[[^\]]+\] "[A-Z]+ /(?:\.env[^"]*|\.git[^"]*|wp-login\.php[^"]*|wp-admin[^"]*|xmlrpc\.php[^"]*|phpmyadmin[^"]*|pma/[^"]*|adminer[^"]*|admin\.php[^"]*|config\.php[^"]*|setup\.php[^"]*|install\.php[^"]*|actuator[^"]*|console[^"]*|manager/html[^"]*|invoker/[^"]*|solr/[^"]*|geoserver/[^"]*|boaform/[^"]*|HNAP1[^"]*|cgi-bin/[^"]*|shell\.php[^"]*|cmd\.php[^"]*|eval-stdin\.php[^"]*)[^"]*" \d{3} \d+ "[^"]*" "[^"]*" \[Client \] +failregex = - \d+ \d+ - \S+ \S+ \S+ "/(?:\.env[^"]*|\.git[^"]*|wp-login\.php[^"]*|wp-admin[^"]*|xmlrpc\.php[^"]*|phpmyadmin[^"]*|pma/[^"]*|adminer[^"]*|admin\.php[^"]*|config\.php[^"]*|setup\.php[^"]*|install\.php[^"]*|actuator[^"]*|console[^"]*|manager/html[^"]*|invoker/[^"]*|solr/[^"]*|geoserver/[^"]*|boaform/[^"]*|HNAP1[^"]*|cgi-bin/[^"]*|shell\.php[^"]*|cmd\.php[^"]*|eval-stdin\.php[^"]*)[^"]*" \[Client \] ignoreregex =