Skip to content

Instantly share code, notes, and snippets.

@jaeyson
Created October 7, 2025 04:36
Show Gist options
  • Save jaeyson/1acc09d3a32aca94145fcfa8079dd3cf to your computer and use it in GitHub Desktop.
Save jaeyson/1acc09d3a32aca94145fcfa8079dd3cf to your computer and use it in GitHub Desktop.
Fail2ban configs

Fail2ban configs, your main configuration file that you should create and use is called jail.local within your /etc/fail2ban directory. We do use ipset (iptables-ipset-proto6-allports) instead of iptable for better performance.
We also use custom Fail2ban filters (should be put inside the filter.d folder), see examples below...

Custom Action per Jail

Moreover, you can configure another action for each jail separately, like: action = %(action_)s, which will stop sending emails to you.

Also add abuseipdb action per Jail

You can also set the abuseipdb[abuseipdb_apikey=.., abuseipdb_category=...] action for each jail, which is actually advised to report better stats to the abuse ip DB (assuming you report the correct category IDs, comma separated)!

[DEFAULT]
destemail = [email protected]
sendername = Fail2Ban
# We use ipset instead of iptable for performance reasons!
# By default ban on all ports
banaction_allports = iptables-ipset-proto6-allports
banaction = %(banaction_allports)s
# By default sent mail with whois report + relevant log lines to email
# Add configure abuseIPDB
action = %(action_mwl)s
abuseipdb[abuseipdb_apikey="secret", abuseipdb_category="18,21"]
# Only log critical issues
loglevel = ERROR
# Ignore the following ip addresses (whitelisted)
# Those are local IP ranges (LAN)
# And Docker default subnet for container networking
ignoreip = 127.0.0.1/8 ::1 192.168.2.0/24 192.168.1.0/24 172.17.0.0/16
# Perma ban (time a host is banned)
bantime = -1
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 60m
# "maxretry" is the number of failures before a host get banned.
maxretry = 2
[sshd]
enabled = true
port = ssh
mode = ddos
maxretry = 1
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
# Rate limit exceeded.
# Disable email notification
[nginx-limit-req]
enabled = true
port = http,https
action = %(action_)s
logpath = %(nginx_error_log)s
findtime = 10m
maxretry = 16
# 2 weeks
bantime = 2w
# The generic access log
[nginx-4xx]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
findtime = 10m
maxretry = 20
bantime = 1w
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 3
[manual]
enabled = true
port = http,https
action = %(banaction_allports)s
bantime = -1
[Definition]
failregex=
ignoreregex=
[Definition]
failregex = ^<HOST>.*"(GET|POST|PUT|HEAD).*" (404|444|403|400) .*$
ignoreregex = ^<HOST>.* (Googlebot|FeedFetcher-Google|DuplexWeb-Google|bingbot|Yahoo!|DuckDuckGo|Ask|AOL|YandexBot).*$
[Definition]
# Specify following expression to define exact zones, if you want to ban IPs limited
# from specified zones only.
# Example:
#
# ngx_limit_req_zones = lr_zone|lr_zone2
#
ngx_limit_req_zones = [^"]+
# Use following full expression if you should range limit request to specified
# servers, requests, referrers etc. only :
#
# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
# Shortly, much faster and stable version of regexp:
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
ignoreregex =
datepattern = {^LN-BEG}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment