1. Create the Filter
# Create a new filter file
sudo nano /etc/fail2ban/filter.d/myfilter.confBasic filter structure:
[Definition]
failregex = ^<HOST> .* "GET /bad-url.*" 4\d\d
^<HOST> .* "POST /login.*" 401
ignoreregex =<HOST>— placeholder that captures the IP addressfailregex— one or more regex patterns (one per line, indented)ignoreregex— patterns to whitelist/skip
2. Test the Filter Before Activating
# Test against your log file
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/myfilter.conf
# Verbose output — shows matched lines
fail2ban-regex -v /var/log/nginx/access.log /etc/fail2ban/filter.d/myfilter.confMake sure you see matches before proceeding.
3. Create the Jail
sudo nano /etc/fail2ban/jail.local[myfilter]
enabled = true
port = http,https
filter = myfilter
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600
| Option | Meaning |
|---|---|
filter | name of file in filter.d/ (no .conf) |
logpath | log file to watch |
maxretry | hits before ban |
findtime | time window in seconds |
bantime | ban duration in seconds (-1 = permanent) |
4. Activate It
# Reload fail2ban to pick up changes
sudo fail2ban-client reload
# Or restart fully
sudo systemctl restart fail2ban5. Verify It's Running
# Check jail is active
sudo fail2ban-client status
# Check your specific jail
sudo fail2ban-client status myfilter
# Watch the log for activity
sudo tail -f /var/log/fail2ban.logTips
# Always edit jail.local, not jail.conf (survives upgrades)
# jail.local overrides jail.conf
# For a permanent ban use:
bantime = -1
# To ban wider (e.g. whole /24 subnet):
bantime = 86400
action = iptables-allports[name=myfilter, bantime="86400", chain="INPUT"]