fail2ban scans log files and bans IP addresses that show malicious signs (multiple failed login attempts, vulnerability scans, etc.). It can automatically update firewall rules to reject IP addresses for a specified amount of time.
Service Management
- systemctl start fail2ban - Start fail2ban service
- systemctl stop fail2ban - Stop fail2ban service
- systemctl restart fail2ban - Restart fail2ban service
- systemctl status fail2ban - Check service status
- systemctl enable fail2ban - Enable fail2ban at boot
- systemctl reload fail2ban - Reload configuration without restart
Viewing Status
- fail2ban-client status - Show all active jails
- fail2ban-client status sshd - Show status of specific jail
- fail2ban-client status sshd -v - Verbose status output
- fail2ban-client get
logpath - Get log path for jail
- fail2ban-client get
findtime - Get findtime value
- fail2ban-client get
bantime - Get ban time value
- fail2ban-client get
maxretry - Get max retry value
Ban Management
- fail2ban-client set
banip - Manually ban an IP
- fail2ban-client set
unbanip - Unban an IP address
- fail2ban-client set
unbanip all - Unban all IPs in a jail
- fail2ban-client unban --all - Unban all IPs from all jails
- fail2ban-client set sshd getbanned - List banned IPs for jail
- fail2ban-client status sshd | grep "Banned IP" - List banned IPs
Configuration Files
- /etc/fail2ban/jail.conf - Main configuration (don't edit directly)
- /etc/fail2ban/jail.local - Local configuration (override jail.conf)
- /etc/fail2ban/jail.d/ - Additional jail configurations
- /etc/fail2ban/filter.d/ - Filter definitions
- /etc/fail2ban/action.d/ - Action scripts (ban/unban commands)
- /etc/fail2ban/fail2ban.local - fail2ban daemon configuration
- /var/log/fail2ban.log - fail2ban log file
Common Jails
- sshd - SSH server
- apache-auth - Apache authentication failures
- apache-badbots - Apache bad bots
- apache-noscript - Apache script injection attempts
- apache-overflows - Apache buffer overflow attempts
- nginx-http-auth - Nginx HTTP authentication
- nginx-limit-req - Nginx rate limiting
- postfix - Postfix mail server
- dovecot - Dovecot IMAP/POP3
- vsftpd - FTP server
- mysqld-auth - MySQL authentication
Jail Configuration Example
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables[name=SSH, port=ssh, protocol=tcp]
Configuration Options
- enabled - Enable/disable jail (true/false)
- port - Port(s) to ban (ssh, http, 22, 80,443, 22:25)
- filter - Filter name (in /etc/fail2ban/filter.d/)
- logpath - Log file path to monitor
- maxretry - Maximum number of failures before ban
- findtime - Time window in seconds to count failures
- bantime - Duration of ban in seconds (-1 = permanent)
- action - Action to take when banning (default: iptables)
- ignoreip - IP addresses/networks to never ban
- ignorecommand - Command to check if IP should be ignored
Creating Custom Jails
/etc/fail2ban/jail.local
[DEFAULT]
# Default ban time (10 minutes)
bantime = 600
# Time window to count failures (10 minutes)
findtime = 600
# Maximum failures before ban
maxretry = 5
# IPs/networks to never ban
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
# Email notifications (optional)
destemail = admin@example.com
sendername = Fail2Ban
action = %(action_mwl)s
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 7200
[custom-web]
enabled = true
port = http,https
filter = custom-web
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 300
bantime = 3600
Creating Custom Filters
/etc/fail2ban/filter.d/custom-web.conf
[Definition]
# Failregex - patterns that indicate a failed attempt
failregex = ^<HOST>.*"GET /wp-admin.*" 404
^<HOST>.*"POST /xmlrpc.php.*" 200
^<HOST>.*"GET /administrator.*" 404
# Ignore regex - patterns to ignore
ignoreregex =
Testing Filters
# Test filter against log file
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Test with verbose output
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf -v
# Test custom filter
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/custom-web.conf
Actions
- iptables - Use iptables for banning (default)
- iptables-multiport - Ban multiple ports
- iptables-allports - Ban all ports
- iptables-new - Use iptables with new chain (recommended)
- ipset - Use ipset for efficient IP management
- ipset-multiport - ipset with multiple ports
- nftables - Use nftables (new firewall backend)
- sendmail - Send email notifications
- mail-whois - Send email with whois information
- action_mwl - Mail with whois and log lines
- action_bspam - Ban and report to spamhaus
Advanced Configuration
Email Notifications
[DEFAULT]
destemail = admin@example.com
sendername = Fail2Ban-Alerts
sender = fail2ban@example.com
mta = sendmail
action = %(action_mwl)s
Using ipset (Better Performance)
[sshd]
action = iptables-ipset-proto6[name=SSH, port=ssh, protocol=tcp, chain=INPUT]
iptables-ipset-proto4[name=SSH, port=ssh, protocol=tcp, chain=INPUT]
Multiple Ports
[web-ports]
enabled = true
port = http,https,8080,8443
filter = apache-auth
logpath = /var/log/apache2/*error.log
maxretry = 5
Managing Jails
- fail2ban-client start - Start fail2ban
- fail2ban-client stop - Stop fail2ban
- fail2ban-client reload - Reload configuration
- fail2ban-client reload
- Reload specific jail
- fail2ban-client start
- Start specific jail
- fail2ban-client stop
- Stop specific jail
- fail2ban-client restart
- Restart specific jail
Logging and Monitoring
- tail -f /var/log/fail2ban.log - Monitor fail2ban log
- grep "Ban\|Unban" /var/log/fail2ban.log - View ban/unban events
- fail2ban-client get
logencoding - Check log encoding
- fail2ban-client -d - Debug mode (run in foreground)
Useful Commands
- fail2ban-client ping - Test if fail2ban is responding
- fail2ban-client version - Show version
- fail2ban-regex --help - Help for regex testing
- iptables -L -n | grep f2b- - List fail2ban iptables rules
- ipset list - List all ipsets (if using ipset)
Common Use Cases
Protect SSH
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
ignoreip = 192.168.1.0/24
Protect Web Server
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/*error.log
maxretry = 3
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/*access.log
maxretry = 2
Protect MySQL
[mysqld-auth]
enabled = true
port = 3306
filter = mysqld-auth
logpath = /var/log/mysqld.log
maxretry = 5
bantime = 7200
Tips
- Always use jail.local instead of editing jail.conf directly
- Test filters with fail2ban-regex before enabling jails
- Add your own IP to ignoreip to avoid getting locked out
- Use ipset action for better performance with many banned IPs
- Monitor /var/log/fail2ban.log for issues
- Set reasonable bantime to avoid permanent locks
- Adjust maxretry and findtime based on your needs
- Use action_mwl to get email notifications with context
- Check iptables rules regularly to ensure bans are working
- Combine with log monitoring tools for better visibility
- Document custom filters for future reference
- Regularly review banned IPs and unban false positives
- Use fail2ban-client reload to apply config changes without downtime
- Test configuration changes on a non-production system first
- Keep fail2ban updated to get latest filters and fixes