Fail2Ban Configuration: SSH Brute-Force Protection Guide
Protect your server against SSH brute-force attacks with Fail2Ban. Installation, jail.local configuration, Nginx/Apache jails, IP whitelisting, ban monitoring, and email alerts.
Table of Contents
Fail2Ban Configuration: SSH Brute-Force Protection Guide
SSH brute-force attacks are among the most common threats faced by every internet-facing server. Fail2Ban is a powerful tool that monitors failed login attempts and automatically blocks attacker IP addresses. This guide walks you through setting up Fail2Ban with comprehensive protection for SSH, Nginx, and Apache.
What is Fail2Ban?
Fail2Ban is a security tool that monitors log files and blocks IP addresses that make too many failed login attempts within a given time window using iptables/nftables rules. Written in Python, it includes ready-made filters for many services.
Installation
# Ubuntu/Debian
sudo apt update
sudo apt install fail2ban -y
# CentOS/AlmaLinux/Rocky Linux
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
# Start Fail2Ban service
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# Check status
sudo systemctl status fail2ban
jail.local Configuration
Fail2Ban's main configuration file is jail.conf. However, don't edit this file directly — it may be overwritten during updates. Instead, create a jail.local file:
# Copy jail.conf
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit configuration
sudo nano /etc/fail2ban/jail.local
# /etc/fail2ban/jail.local
[DEFAULT]
# Ban duration (seconds) — 1 hour
bantime = 3600
# Detection window (seconds) — 10 minutes
findtime = 600
# Maximum failed attempts
maxretry = 5
# Backend (auto, pyinotify, gamin, polling, systemd)
backend = auto
# DNS resolution (warn, no, yes)
usedns = warn
# Log level (CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG)
loglevel = INFO
# Log target
logtarget = /var/log/fail2ban.log
# Email notification
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail
# Action — ban and send email
action = %(action_mwl)s
# Ban only (no email):
# action = %(action_)s
# Whitelist — these IPs are never banned
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
SSH Jail Configuration
# Inside /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
# For Ubuntu 20.04+:
# logpath = %(sshd_log)s
maxretry = 3
bantime = 86400 # 24 hours
findtime = 600
# If using systemd journal:
# backend = systemd
For SSH, maxretry = 3 and bantime = 86400 (24 hours) are recommended. This allows attackers only 3 attempts per day.
Nginx Jail Configuration
# Nginx HTTP authentication failure
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
# Nginx rate limiting violation
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 600
# Nginx bad bot blocking
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
# Nginx 404 flood protection
[nginx-404]
enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 60
bantime = 3600
Creating a Custom Nginx 404 Filter
sudo nano /etc/fail2ban/filter.d/nginx-404.conf
[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) .* HTTP/.*" 404
ignoreregex =
Apache Jail Configuration
# Apache authentication failure
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
bantime = 3600
# Apache bad bots
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
bantime = 86400
# Apache nuke/scan
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/error.log
maxretry = 6
bantime = 3600
IP Whitelisting
# Add to DEFAULT section in jail.local
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# You can add multiple IPs or subnets
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16 203.0.113.1
# Reload configuration
sudo fail2ban-client reload
# Verify whitelist
sudo fail2ban-client get sshd ignoreip
Monitoring Banned IPs
# View status of all jails
sudo fail2ban-client status
# View status of a specific jail
sudo fail2ban-client status sshd
# List banned IPs
sudo fail2ban-client status sshd | grep "Banned IP"
# Show all banned IPs
sudo iptables -L f2b-sshd -n --line-numbers
# Monitor log file
sudo tail -f /var/log/fail2ban.log
# Filter recent ban events
sudo grep "Ban" /var/log/fail2ban.log | tail -20
Banning and Unbanning IPs
# Manually ban an IP
sudo fail2ban-client set sshd banip 1.2.3.4
# Unban an IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
# Remove all bans (use with caution!)
sudo fail2ban-client unban --all
# Restart a specific jail
sudo fail2ban-client restart sshd
Email Notifications
# Install Postfix or sendmail
sudo apt install postfix -y
[DEFAULT]
destemail = admin@example.com
sender = fail2ban@yourdomain.com
mta = sendmail
# Action options:
# action_ = ban only
# action_mw = ban + email
# action_mwl = ban + email + whois + log lines
action = %(action_mwl)s
Checking Fail2Ban Status
# Service status
sudo systemctl status fail2ban
# Test configuration
sudo fail2ban-client -t
# List all jails
sudo fail2ban-client status
# Restart Fail2Ban
sudo systemctl restart fail2ban
# Reload configuration (without restarting service)
sudo fail2ban-client reload
Advanced: Persistent Banning
By default, Fail2Ban resets bans when the server restarts. For persistent banning:
[DEFAULT]
# Permanent ban (-1 = forever)
bantime = -1
# Or very long duration:
bantime = 604800 # 7 days
Very aggressive settings (low maxretry, long bantime) can also block legitimate users. For SSH, maxretry=3-5 and bantime=3600-86400 is a balanced approach.
Conclusion
Fail2Ban is an indispensable part of server security. When properly configured for SSH, Nginx, and Apache, it significantly reduces brute-force attacks. Regularly monitor log files and whitelist any false-positive blocks.
Related Articles
Malware & Rootkit Scanning: rkhunter and ClamAV Guide
Protect your Linux server against malware and rootkits. rkhunter and ClamAV installation, scan configuration, result interpretation, scheduled scans, and incident response guide.
WireGuard VPN Server Setup: Step-by-Step Guide
Set up a WireGuard VPN server: key generation, server and client configuration, IP forwarding, firewall rules, and Windows/Linux/Android client setup guide.
Zero Trust Network Security: Basic Configuration Guide
Zero Trust network security principles and practical implementation: never trust always verify, micro-segmentation, identity-based access, and implementation with existing Linux tools.