Home/Engineer/Security Hardening/Fail2Ban Advanced — Custom F…
Security HardeningAdvancedUbuntuDebianCentOSfail2banSecurity

Fail2Ban Advanced — Custom Filters, Actions, and Whitelists

This guide covers advanced Fail2Ban configuration: parsing application logs with custom filters, adding actions, and managing whitelists and blacklists.

Contents
  1. Understanding the Fail2Ban Structure
  2. Basic jail.local Configuration
  3. Writing Custom Filters
  4. Blocking Nginx Login Failures
  5. Custom Action — Slack Notifications
  6. Whitelist and Blacklist
  7. Status Check Commands

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 definitions

Basic 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  = 24h

Writing 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  = 2h

Blocking 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  = 1h

Custom 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-notify

Whitelist 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.45

Status 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 fail2ban
#fail2ban#Security
Editorial 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.