Post

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.

Fail2Ban Configuration and Usage Guide

Table of Contents

  1. Introduction
  2. What is Fail2ban?
  3. Installation
  4. Basic Configuration
  5. Common Jails
  6. Advanced Configuration
  7. Fail2ban CLI
  8. Security Hardening
  9. Troubleshooting
  10. Best Practices
  11. 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 overrides fail2ban.conf
  • jail.local overrides jail.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 port
  • iptables-multiport: Blocks an IP on multiple ports
  • iptables-allports: Blocks an IP on all ports
  • sendmail-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:

  1. Create a new filter file in /etc/fail2ban/filter.d/:
1
sudo nano /etc/fail2ban/filter.d/wordpress-login.conf
  1. Define the filter:
1
2
3
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =

Custom Actions

For advanced response actions:

  1. Create a new action file in /etc/fail2ban/action.d/:
1
sudo nano /etc/fail2ban/action.d/slack-notification.conf
  1. 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 only
  • action_mw: ban and send an email with WHOIS info
  • action_mwl: ban and send an email with WHOIS info and relevant log entries

Troubleshooting

Common Issues

  1. Service not starting:
    1
    
    sudo journalctl -u fail2ban.service
    
  2. Configuration syntax errors:
    1
    
    sudo fail2ban-client -d
    
  3. 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

  1. Always use .local files - Never edit .conf files directly
  2. Start with conservative settings - Begin with longer findtime and higher maxretry
  3. Whitelist your own IPs - Prevent accidental lockouts
  4. Set up email notifications - Stay informed about attacks
  5. Regular updates - Keep Fail2ban and its dependencies up to date
  6. Monitor regularly - Check logs and stats to adjust configurations
  7. Use persistent bans - Implement recidive jail for repeat offenders
  8. Backup configurations - Store your custom configurations safely

Further Resources

This post is licensed under CC BY 4.0 by the author.