diff --git a/fail2ban/filter.d/nginx-badbots.conf b/fail2ban/filter.d/nginx-badbots.conf index 77865a4..d57fd76 100644 --- a/fail2ban/filter.d/nginx-badbots.conf +++ b/fail2ban/filter.d/nginx-badbots.conf @@ -2,11 +2,14 @@ # JSON logs with ISO-8601 timestamps datepattern = {^LN-BEG}%%Y-%%m-%%dT%%H:%%M:%%S(?:[.,]\\d+)?(?:Z|[+\\-]\\d{2}:\\d{2})? -# Catch typical scanners and CLI/automation libraries (case-insensitive via (?i)) -# Prefer x_forwarded_for (real client IP) if present; fall back to remote_addr. -# NOTE: One "failregex =" key, multiple indented lines. No backslashes for wrapping. +# Define a custom IP regex for +hostname = (?:\d{1,3}\.){3}\d{1,3} + +# Detect scanners in user-agent failregex = (?i)^.*"x_forwarded_for":"(?:, [^"]+)?".*"http_user_agent":"[^"]*(?:sqlmap|nikto|acunetix|wpscan|dirbuster|gobuster|masscan|zgrab|ZmEu|nessus|openvas|libwww-perl|mechanize|lwp-trivial|python-requests|python-urllib|urllib|aiohttp|httpx|scrapy|curl|wget|Go-http-client|okhttp|httpclient|jakarta|java)[^"]*".*$ (?i)^.*"remote_addr":"".*"http_user_agent":"[^"]*(?:sqlmap|nikto|acunetix|wpscan|dirbuster|gobuster|masscan|zgrab|ZmEu|nessus|openvas|libwww-perl|mechanize|lwp-trivial|python-requests|python-urllib|urllib|aiohttp|httpx|scrapy|curl|wget|Go-http-client|okhttp|httpclient|jakarta|java)[^"]*".*$ -# Ignore your health/status endpoints -ignoreregex = ^.*"request_uri":"\/(?:stub_status|health\/system|health\/worker|pgadmin4(?:\/|$)|\.well-known\/acme-challenge\/|.*\.(?:css|js|png|jpg|jpeg|gif|svg|ico|webp|woff2?))".*$ \ No newline at end of file +# Ignore internal/harmless endpoints and broken IPs +ignoreregex = ^.*"request_uri":"\/(?:stub_status|health\/system|health\/worker|pgadmin4(?:\/|$)|\.well-known\/acme-challenge\/|.*\.(?:css|js|png|jpg|jpeg|gif|svg|ico|webp|woff2?))".*$ + ^.*"x_forwarded_for":"\:?".*$ + ^.*"remote_addr":"\:?".*$ \ No newline at end of file