How to Use Fail2Ban for Server Protection

| Categories security linux  | Tags Fail2Ban  Nginx  Anti-Crawler  Security 

✅ What is Fail2Ban?

Fail2Ban is a log-based intrusion prevention tool. It automatically scans log files (such as Nginx, SSH, etc.), detects suspicious behaviors like failed logins or 404 attacks, and blocks offending IPs via iptables or other firewall actions.


🔧 Install Fail2Ban

Ubuntu / Debian

sudo apt install fail2ban

CentOS / RHEL

sudo yum install epel-release
sudo yum install fail2ban

🧱 Core Components

Type Description
jail The service to monitor (e.g. sshd, nginx)
filter Regex rules to match malicious patterns
action How to respond to a match (ban IP, write file)

🧪 Example 1: Blocking Web Scanners (Multiple 404s)

Filter: /etc/fail2ban/filter.d/nginx-404.conf

[Definition]
failregex = ^<HOST> -.*"(GET|POST).*(HTTP|HTTPS)/1.[01]" 404
ignoreregex =

Jail: /etc/fail2ban/jail.d/nginx-404.conf

[nginx-404]
enabled  = true
filter   = nginx-404
logpath  = /var/log/nginx/access.log
maxretry = 10
findtime = 600
bantime  = 3600
action   = iptables[name=nginx-404, port=http, protocol=tcp]

🧪 Example 2: Prevent Brute-Force on Basic Auth (401)

Nginx configuration:

location /admin/ {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Filter: /etc/fail2ban/filter.d/nginx-http-auth.conf

[Definition]
failregex = ^<HOST> -.*"(GET|POST).*(HTTP|HTTPS)/1.[01]" 401
ignoreregex =

Jail: /etc/fail2ban/jail.d/nginx-http-auth.conf

[nginx-http-auth]
enabled  = true
filter   = nginx-http-auth
logpath  = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime  = 3600
action   = iptables[name=nginx-auth, port=http, protocol=tcp]

💡 Alternative: Use deny in Nginx (no iptables)

For containers or Kubernetes environments, you can write bans directly into an Nginx file:

[Definition]
actionban   = /bin/bash -c 'echo "deny <ip>;" >> /etc/nginx/denylist.conf && nginx -s reload'
actionunban = /bin/bash -c 'sed -i "/deny <ip>;/d" /etc/nginx/denylist.conf && nginx -s reload'

Nginx config:

include /etc/nginx/denylist.conf;

error_page 403 /403.html;
location = /403.html {
    root /usr/share/nginx/html;
    internal;
}

⏱ Remaining Ban Time Viewer

Fail2Ban doesn’t provide a direct command to view remaining ban time. The following script estimates it using the log and ban duration:

📄 Script: fail2ban-ban-remaining.sh

#!/bin/bash
# fail2ban-ban-remaining.sh
# Show remaining ban time for an IP

if [ $# -ne 2 ]; then
  echo "Usage: $0 <jail-name> <ip-address>"
  exit 1
fi

JAIL="$1"
IP="$2"
LOG="/var/log/fail2ban.log"
BANTIME=3600  # Update this to match your jail config

ban_time=$(grep "Ban $IP" "$LOG" | grep "\[$JAIL\]" | tail -1 | awk '{print $1" "$2}')
if [ -z "$ban_time" ]; then
  echo "No ban record found for $IP in jail $JAIL"
  exit 2
fi

ban_epoch=$(date -d "$ban_time" +%s 2>/dev/null)
now_epoch=$(date +%s)
elapsed=$(( now_epoch - ban_epoch ))
remaining=$(( BANTIME - elapsed ))

if [ $remaining -le 0 ]; then
  echo "Ban expired for $IP"
else
  echo "IP $IP was banned at $ban_time"
  echo "Remaining ban time: $remaining seconds ($((remaining/60)) min)"
fi

Usage:

chmod +x fail2ban-ban-remaining.sh
./fail2ban-ban-remaining.sh nginx-http-auth 1.2.3.4

🧼 Permanent Ban and Manual Unban

  • Permanent ban: bantime = -1
  • Unban manually:
fail2ban-client set nginx-http-auth unbanip 1.2.3.4

📁 References


You can integrate Fail2Ban with firewalls like iptables, nftables, or Kubernetes ingress controllers to form a layered defense strategy.