Fail2Ban Configuration and Usage Guide
Fail2Ban monitors log files and bans IPs exhibiting malicious behavior, protecting your server from brute-force attacks. This guide covers installation, jail and filter configuration, and best security practices.
Table of Contents
- Introduction
- What is Fail2ban?
- Installation
- Basic Configuration
- Common Jails
- Advanced Configuration
- Fail2ban CLI
- Security Hardening
- Troubleshooting
- Best Practices
- Further Resources
Introduction
Server security is a critical concern for system administrators. Unauthorized access attempts and brute force attacks are common threats that can compromise system integrity. Fail2ban is a powerful tool designed to mitigate these risks by monitoring log files and automatically blocking malicious IP addresses.
This guide provides comprehensive instructions for installing, configuring, and managing Fail2ban to enhance server security across various services.
What is Fail2ban?
Fail2ban is an intrusion prevention framework written in Python that protects servers from brute force attacks and other malicious activity. It works by:
- Monitoring log files for suspicious activity
- Detecting authentication failures and abuse patterns
- Temporarily or permanently banning offending IP addresses
- Supporting multiple services including SSH, HTTP, FTP, and mail servers
Unlike a firewall that blocks specific ports, Fail2ban dynamically updates firewall rules based on observed behavior, providing an additional layer of security.
Installation
Debian/Ubuntu
1
2
3
4
5
6
7
8
9
10
11
# Update package lists
sudo apt update
# Install Fail2ban
sudo apt install fail2ban -y
# Enable service to start on boot
sudo systemctl enable fail2ban
# Start the service
sudo systemctl start fail2ban
Example: On Ubuntu 22.04, you might want to install additional dependencies:
1 sudo apt install fail2ban python3-systemd whois -y
CentOS/RHEL/Fedora
1
2
3
4
5
6
7
8
9
10
11
12
13
# For CentOS/RHEL 7 and 8, enable EPEL repository first
sudo dnf install epel-release -y
# OR for older versions
# sudo yum install epel-release -y
# Install Fail2ban
sudo dnf install fail2ban -y
# OR
# sudo yum install fail2ban -y
# Enable and start the service
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
From Source
For the latest version or custom installation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Install prerequisites
sudo apt install git python3 python3-pip -y
# OR
# sudo dnf install git python3 python3-pip -y
# Clone repository
git clone https://github.com/fail2ban/fail2ban.git
# Navigate to directory
cd fail2ban
# Install
sudo python3 setup.py install
# Create service file
sudo cp files/fail2ban.service /etc/systemd/system/
# Reload systemd, enable and start service
sudo systemctl daemon-reload
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Basic Configuration
Configuration Files
Fail2ban uses a hierarchy of configuration files located in:
/etc/fail2ban/
- Main configuration directory/etc/fail2ban/fail2ban.conf
- Default configuration/etc/fail2ban/jail.conf
- Default jail configurations/etc/fail2ban/filter.d/
- Filter definitions/etc/fail2ban/action.d/
- Action definitions
Important: Never modify the
.conf
files directly. Instead, create.local
files that override default settings:
fail2ban.local
overridesfail2ban.conf
jail.local
overridesjail.conf
Create a basic jail.local file:
1
2
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Jail Configuration
The jail.local
file defines which services to monitor and how to respond to attacks. Here’s a basic configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[DEFAULT]
# Ban IP for 1 hour (3600 seconds)
bantime = 3600
# Check log files every 10 seconds
findtime = 600
# Ban after 5 failures
maxretry = 5
# Email notifications
destemail = [email protected]
sender = [email protected]
mta = sendmail
# Action to take when banning
action = %(action_mw)s
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
Example: Stricter settings for a production server:
1 2 3 4 5 6 7 [DEFAULT] bantime = 86400 # 24 hours findtime = 3600 # Look back 1 hour maxretry = 3 # Ban after 3 failures # Ban IP on all ports (more secure) banaction = iptables-allports
Filter Configuration
Filters define patterns to detect intrusion attempts in log files. Fail2ban comes with predefined filters in /etc/fail2ban/filter.d/
. Each filter contains regular expressions that match malicious activity patterns.
Example of the SSH filter (/etc/fail2ban/filter.d/sshd.conf
):
1
2
3
4
5
6
7
[Definition]
failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>
^%(__prefix_line)sFailed (?:password|publickey) for .* from <HOST>
^%(__prefix_line)sFailed password for invalid user .* from <HOST>
ignoreregex =
The <HOST>
pattern is automatically replaced with a regex that matches IP addresses.
Action Configuration
Actions define what happens when a ban is triggered. Default actions are in /etc/fail2ban/action.d/
:
iptables
: Blocks an IP on a specific portiptables-multiport
: Blocks an IP on multiple portsiptables-allports
: Blocks an IP on all portssendmail-whois
: Sends email notification with WHOIS information
Example of a custom action file (/etc/fail2ban/action.d/custom-action.conf
):
1
2
3
4
5
6
7
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = iptables -I INPUT -s <ip> -j DROP
echo "Banned IP <ip> at `date`" >> /var/log/fail2ban-bans.log
actionunban = iptables -D INPUT -s <ip> -j DROP
Common Jails
SSH
The SSH jail protects against brute force login attempts:
1
2
3
4
5
6
7
[sshd]
enabled = true
port = ssh,22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
For SSH on non-standard ports:
1
2
3
4
5
6
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
Apache/Nginx
Protect web servers from various attacks:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
FTP
Protect FTP services:
1
2
3
4
5
6
7
8
9
10
11
12
13
[vsftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
filter = vsftpd
logpath = /var/log/vsftpd.log
maxretry = 3
[proftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
filter = proftpd
logpath = /var/log/proftpd/proftpd.log
maxretry = 3
Mail Services
Protect mail servers:
1
2
3
4
5
6
7
8
9
10
11
12
13
[postfix]
enabled = true
port = smtp,ssmtp,submission
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
Advanced Configuration
Custom Jails
Create custom jails for specific applications by defining a new section in jail.local
:
1
2
3
4
5
6
7
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/apache2/access.log
maxretry = 3
bantime = 86400
Custom Filters
Create a custom filter for applications without predefined filters:
- Create a new filter file in
/etc/fail2ban/filter.d/
:
1
sudo nano /etc/fail2ban/filter.d/wordpress-login.conf
- Define the filter:
1
2
3
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =
Custom Actions
For advanced response actions:
- Create a new action file in
/etc/fail2ban/action.d/
:
1
sudo nano /etc/fail2ban/action.d/slack-notification.conf
- Define the action:
1
2
3
4
5
6
7
8
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -X POST -H 'Content-type: application/json' --data '{"text":"Fail2Ban: IP <ip> banned for <name>"}' https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
actionunban =
[Init]
Fail2ban CLI
Basic Commands
Check Fail2ban status:
1
2
3
4
5
6
7
8
# Check service status
sudo systemctl status fail2ban
# Check all jails status
sudo fail2ban-client status
# Check specific jail status
sudo fail2ban-client status sshd
Reload configuration:
1
2
3
4
5
# Reload all configuration
sudo fail2ban-client reload
# Reload specific jail
sudo fail2ban-client reload sshd
Start/stop jails:
1
2
3
4
5
# Start a jail
sudo fail2ban-client start sshd
# Stop a jail
sudo fail2ban-client stop sshd
Monitoring
View currently banned IPs:
1
2
3
4
5
# All jails
sudo fail2ban-client banned
# Specific jail
sudo fail2ban-client banned sshd
Check log files for Fail2ban activity:
1
sudo tail -f /var/log/fail2ban.log
Unban IP Addresses
Manually unban an IP address:
1
sudo fail2ban-client set sshd unbanip 123.45.67.89
Security Hardening
Whitelist Configuration
Prevent specific IPs from being banned by adding them to the ignoreip
parameter:
1
2
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.1.0/24 10.0.0.5
Create dedicated file for whitelisted IPs:
1
sudo nano /etc/fail2ban/ip.whitelist
Add each IP on a separate line, then reference it in jail.local
:
1
2
[DEFAULT]
ignoreip = 127.0.0.1/8 <file:>/etc/fail2ban/ip.whitelist</file:>
Persistent Bans
Configure permanent or longer bans for repeat offenders:
1
2
3
4
5
6
7
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800 # 1 week
findtime = 86400 # 1 day
maxretry = 3
Email Notifications
Configure email alerts for ban actions:
1
2
3
4
5
[DEFAULT]
destemail = [email protected]
sender = [email protected]
mta = sendmail
action = %(action_mwl)s
Available action types:
action_
: ban onlyaction_mw
: ban and send an email with WHOIS infoaction_mwl
: ban and send an email with WHOIS info and relevant log entries
Troubleshooting
Common Issues
- Service not starting:
1
sudo journalctl -u fail2ban.service
- Configuration syntax errors:
1
sudo fail2ban-client -d
- Jail not working:
1 2
sudo fail2ban-client -d sudo tail -f /var/log/fail2ban.log
Debugging
Enable verbose logging:
1
2
3
# In /etc/fail2ban/fail2ban.local
[Definition]
loglevel = DEBUG
Test filters against log files:
1
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Log Analysis
Check if IPs are correctly banned:
1
sudo iptables -L -n
Monitor ban/unban actions:
1
sudo grep "Ban\|Unban" /var/log/fail2ban.log
Best Practices
- Always use .local files - Never edit .conf files directly
- Start with conservative settings - Begin with longer findtime and higher maxretry
- Whitelist your own IPs - Prevent accidental lockouts
- Set up email notifications - Stay informed about attacks
- Regular updates - Keep Fail2ban and its dependencies up to date
- Monitor regularly - Check logs and stats to adjust configurations
- Use persistent bans - Implement recidive jail for repeat offenders
- Backup configurations - Store your custom configurations safely