Complete Fail2Ban Configuration Guide for Ubuntu/Debian
Introduction to Fail2Ban
Fail2Ban is an intrusion prevention software framework that protects computer servers from brute-force attacks. It monitors log files for malicious activity and bans IP addresses that show malicious signs.
Key Features:
- Monitors various services (SSH, Apache, Nginx, etc.)
- Automatically bans malicious IPs using firewall rules
- Configurable ban time and detection rules
- Email notifications for banned IPs
- Supports multiple jails (separate configurations for different services)
Step 1: Installation
Verify the installation:
You should see “active (running)” status.
Note: Fail2Ban requires Python to run. Modern Ubuntu/Debian versions include Python by default.
Step 2: Basic Configuration
Fail2Ban’s configuration files are located in:
- /etc/fail2ban/jail.conf – Main configuration (don’t edit this)
- /etc/fail2ban/jail.local – Your custom configuration
- /etc/fail2ban/filter.d/ – Contains filter definitions
- /etc/fail2ban/action.d/ – Contains action definitions
Create a Custom Configuration:
Essential Configuration Parameters:
Parameter | Description | Recommended Value |
---|---|---|
ignoreip |
IPs that should never be banned | 127.0.0.1/8 ::1 your_trusted_ip |
bantime |
Duration for IP to be banned | 1h or 86400 (24h) |
findtime |
Time window for failed attempts | 10m |
maxretry |
Maximum failed attempts before ban | 5 |
destemail |
Email for notifications | your_email@example.com |
banaction |
Firewall action to take | iptables-multiport (or ufw for Ubuntu) |
Example Jail Configuration:
[DEFAULT] ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 bantime = 1h findtime = 10m maxretry = 5 destemail = admin@example.com sender = root@example.com mta = sendmail action = %(action_mwl)s banaction = ufw
Step 3: Configuring Service Protection (Jails)
SSH Protection (Enabled by Default)
Verify SSH jail is enabled:
[sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s
Note: If you changed your SSH port, update the port
parameter.
Common Services to Protect:
1. Apache Web Server
[apache] enabled = true port = http,https logpath = /var/log/apache2/error.log
2. Nginx Web Server
[nginx-http-auth] enabled = true port = http,https logpath = %(nginx_error_log)s
3. MySQL/MariaDB
[mysqld-auth] enabled = true port = 3306 logpath = %(mysql_log)s
4. PHP-FPM
[php-fpm] enabled = true port = http,https logpath = /var/log/php-fpm.log
5. Postfix (Email Server)
[postfix] enabled = true port = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s logpath = %(postfix_log)s
6. Dovecot (IMAP/POP3)
[dovecot] enabled = true port = smtp,ssmtp,submission,imap2,imap3,imaps,pop3,pop3s logpath = %(dovecot_log)s
Step 4: Creating Custom Filters
For services not covered by default filters, you can create custom ones:
Example: Custom Filter for SSH with Different Port
[Definition] failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* fromvia \S+$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from $ ^%(__prefix_line)sFailed (?:password|publickey) for .* from (?: port \d+)?(?: ssh\d*)?$ ^%(__prefix_line)sReceived disconnect from : 11: (?:Bye Bye|Auth fail).*$ ^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers$ ^%(__prefix_line)sUser .+ from not allowed because none of user's groups are listed in AllowGroups$ ignoreregex =
Example: Custom Filter for WordPress Login
[Definition] failregex = ^.* "POST /wp-login.php HTTP.*" 200 ^ .* "POST /xmlrpc.php HTTP.*" 200 ignoreregex =
Then create a jail for it in jail.local:
[wordpress] enabled = true port = http,https filter = wordpress logpath = /var/log/apache2/access.log maxretry = 3 findtime = 3600 bantime = 86400
Step 5: Configuring Actions
Fail2Ban can perform various actions when banning IPs:
Common Action Types:
action_
– Basic banaction_mw
– Ban and send whois reportaction_mwl
– Ban, send whois report and relevant log linesaction_xarf
– Send abuse report to the ISP
Email Notifications
To receive email notifications:
[DEFAULT] destemail = your_email@example.com sender = fail2ban@yourdomain.com mta = sendmail action = %(action_mwl)s
Note: Ensure your server can send emails. You may need to install sendmail
or postfix
.
Custom Actions
Example: Add custom firewall rule:
[Definition] actionstart = actionstop = actioncheck = actionban = iptables -I INPUT -s-j DROP actionunban = iptables -D INPUT -s -j DROP
Step 6: UFW Integration (For Ubuntu)
For Ubuntu systems using UFW firewall:
1. Set UFW as default banaction:
[DEFAULT] banaction = ufw
2. Create UFW action file:
[Definition] actionstart = actionstop = actioncheck = actionban = ufw insert 1 deny fromto any actionunban = ufw delete deny from to any
3. Restart Fail2Ban:
Step 7: Managing Fail2Ban
Service Management Commands:
Fail2Ban Client Commands:
Viewing Banned IPs:
Step 8: Troubleshooting
Common Issues and Solutions:
1. Fail2Ban not banning IPs
- Check if the service is running:
sudo systemctl status fail2ban
- Verify jail is enabled in jail.local
- Check log path in jail configuration matches your system
- Test filter:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
2. False Positives
- Add trusted IPs to
ignoreip
- Adjust
maxretry
andfindtime
values - Modify filter regex patterns
3. Email Notifications Not Working
- Verify email configuration in jail.local
- Check if MTA (sendmail/postfix) is installed and working
- Inspect mail logs:
sudo tail -f /var/log/mail.log
4. Checking Fail2Ban Logs
Advanced Configuration
1. Multiple IP Detection
To detect and ban multiple IPs from the same subnet:
[DEFAULT] # Ban entire /24 subnet if 3 different IPs are banned maxmatches = 3 findtime = 86400 bantime = 604800 action = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] %(action_)s
2. Recidive Jail (Repeat Offenders)
Create a jail for frequently banned IPs:
[recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = 1w findtime = 1d maxretry = 3
3. Database Backend
For persistent bans across restarts:
[DEFAULT] dbpurgeage = 1d dbfile = /var/lib/fail2ban/fail2ban.sqlite3
Monitoring and Maintenance
1. Regular Log Rotation
Ensure Fail2Ban logs don’t grow too large:
/var/log/fail2ban.log { weekly missingok rotate 4 compress delaycompress notifempty postrotate /usr/bin/fail2ban-client flushlogs >/dev/null endscript }
2. Fail2Ban Statistics
3. Automated Reports
Create a daily report script:
#!/bin/bash echo "Fail2Ban Report - $(date)" echo "========================" echo "" echo "Currently banned IPs:" sudo fail2ban-client status | grep "Banned IP list" echo "" echo "Recent bans:" sudo zgrep 'Ban' /var/log/fail2ban.log* | tail -20
Add this line for daily reports at 8 AM:
0 8 * * * /usr/local/bin/fail2ban-report.sh | mail -s "Daily Fail2Ban Report" admin@example.com
Conclusion
Fail2Ban is a powerful tool for securing your Ubuntu/Debian server against brute force attacks. By following this guide, you’ve:
- Installed and configured Fail2Ban
- Set up protection for various services
- Configured email notifications
- Learned management and troubleshooting techniques
Final Recommendations:
- Regularly review your Fail2Ban logs
- Update your filters as you add new services
- Monitor for false positives and adjust configurations accordingly
- Combine Fail2Ban with other security measures (firewalls, SSH key authentication, etc.)
For more information, consult the official Fail2Ban documentation: https://www.fail2ban.org