Understanding the Fail2Ban Structure
CODE
/etc/fail2ban/
├── fail2ban.conf # Main configuration (do not modify)
├── jail.conf # Default jail configuration (do not modify)
├── fail2ban.local # Local overrides
├── jail.local # Local jail configuration (edit here)
├── filter.d/ # Filter definitions
└── action.d/ # Action definitionsBasic jail.local Configuration
INI
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24hWriting Custom Filters
A regex filter that finds failure patterns in application logs.
INI
# /etc/fail2ban/filter.d/myapp.conf
[Definition]
# Example failure log: 2025-05-27 10:23:45 LOGIN_FAILED from 203.0.113.45
failregex = ^%Y-%m-%d %H:%M:%S LOGIN_FAILED from <HOST>$
^.* authentication failure.* rhost=<HOST>.*$
# Patterns to ignore
ignoreregex = ^.* from 127\.0\.0\.1.*$Bash
# Test the filter
fail2ban-regex /var/log/myapp/auth.log /etc/fail2ban/filter.d/myapp.conf -v
# Add to jail
# /etc/fail2ban/jail.local
[myapp]
enabled = true
filter = myapp
logpath = /var/log/myapp/auth.log
maxretry = 5
bantime = 2hBlocking Nginx Login Failures
INI
# /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^<HOST> -.*"POST /api/login HTTP.*" (401|403) .*$
# /etc/fail2ban/jail.local
[nginx-auth]
enabled = true
filter = nginx-auth
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 5m
bantime = 1hCustom Action — Slack Notifications
INI
# /etc/fail2ban/action.d/slack-notify.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -X POST -H 'Content-type: application/json' \
--data '{"text":"🚫 Fail2Ban: <ip> banned in <name> (%(bantime)s)"}' \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
actionunban =
# Add to jail.local
[myapp]
action = iptables-multiport[name=myapp, port="80,443"]
slack-notifyWhitelist and Blacklist
Bash
# IP whitelist (permanently ignore)
# Add to ignoreip in jail.local [DEFAULT]
ignoreip = 127.0.0.1/8 1.2.3.4 10.0.0.0/8
# Immediately ban a specific IP (manual)
fail2ban-client set sshd banip 203.0.113.45
# Unban
fail2ban-client set sshd unbanip 203.0.113.45Status Check Commands
Bash
# Overall status
fail2ban-client status
# Status of a specific jail
fail2ban-client status sshd
# Currently banned IP list
fail2ban-client status sshd | grep "Banned IP"
# Live log
tail -f /var/log/fail2ban.log
# Reload (after configuration changes)
sudo systemctl reload fail2banEditorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)OWASP documentation ↗
Questions & answers
Ask a question about this guide. We'll review and reply.