Table of Contents#
- Prerequisites
- Installing Fail2ban
- Understanding Fail2ban’s Configuration Structure
- Basic Configuration: Securing SSH
- Setting Up Custom Jails for Web Servers
- Advanced Fail2ban Features
- Testing Fail2ban
- Troubleshooting Common Issues
- Best Practices for Fail2ban
- Conclusion
- References
Prerequisites#
Before you start, ensure you have:
- A Linux server (Debian/Ubuntu, RHEL/CentOS, Fedora, or any other supported distribution).
- Sudo or root access to the server.
- A enabled firewall (UFW for Debian/Ubuntu, firewalld for RHEL/CentOS/Fedora).
- Basic familiarity with the command line and log file formats.
Installing Fail2ban#
Fail2ban is available in the default repositories of most Linux distributions. Installation steps vary slightly depending on your system:
Debian/Ubuntu-Based Systems#
Use apt to install Fail2ban:
# Update package list
sudo apt update
# Install Fail2ban
sudo apt install fail2ban -y
# Enable and start the Fail2ban service
sudo systemctl enable --now fail2banRHEL/CentOS/Fedora-Based Systems#
For RHEL/CentOS 7+, use yum; for Fedora 22+, use dnf:
# Install Fail2ban (RHEL/CentOS 7)
sudo yum install epel-release fail2ban -y
# Install Fail2ban (Fedora)
sudo dnf install fail2ban -y
# Enable and start the service
sudo systemctl enable --now fail2banVerify the installation by checking the service status:
sudo systemctl status fail2banYou should see an "active (running)" message if everything is working correctly.
Understanding Fail2ban’s Configuration Structure#
Fail2ban stores its configuration files in /etc/fail2ban/. The key directories and files are:
| Path | Purpose |
|---|---|
/etc/fail2ban/jail.conf | Default global configuration (do not edit this file—use jail.local instead to avoid overwrites during updates). |
/etc/fail2ban/jail.local | User-specific configuration (overrides settings from jail.conf). |
/etc/fail2ban/filter.d/ | Contains regex filters to detect malicious activity in log files. |
/etc/fail2ban/action.d/ | Defines actions to take when a ban is triggered (e.g., firewall ban, email alert). |
/var/log/fail2ban.log | Fail2ban’s own log file for monitoring its activity. |
Critical Note: Always use jail.local instead of modifying jail.conf. When you update Fail2ban, jail.conf may be overwritten, but jail.local will remain intact.
To create your jail.local file, copy the default jail.conf:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localBasic Configuration: Securing SSH#
SSH is one of the most targeted services on Linux servers. Fail2ban includes a default SSH jail, but it may not be enabled by default. Let’s configure it properly.
- Open the
jail.localfile in your favorite editor (e.g., nano):
sudo nano /etc/fail2ban/jail.local- Locate the
[sshd]section (usually near the top). Enable the jail by settingenabled = true:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s- Adjust key parameters to fit your security needs. Here’s what each parameter means:
- bantime: How long an IP is banned (default: 10m). Use
1dfor 1 day,1wfor 1 week, or-1for a permanent ban. - findtime: The window of time during which failed attempts are counted (default: 10m).
- maxretry: Number of failed attempts before an IP is banned (default: 5).
- ignoreip: List of trusted IPs that should never be banned (e.g., your home IP address).
- bantime: How long an IP is banned (default: 10m). Use
Example configuration with stricter settings:
[DEFAULT]
bantime = 1d
findtime = 10m
maxretry = 3
ignoreip = 192.168.1.0/24 127.0.0.1/8 your_home_ip_address- Save and exit the file. Restart Fail2ban to apply changes:
sudo systemctl restart fail2banCheck the status of the SSH jail to confirm it’s enabled:
sudo fail2ban-client status sshdSetting Up Custom Jails for Web Servers#
Fail2ban isn’t limited to SSH—you can create custom jails to protect web servers like Nginx or Apache. Let’s create a jail for Nginx to ban IPs that repeatedly fail HTTP authentication.
Example: Nginx HTTP Authentication Failures#
-
Create a Filter: First, define a regex filter to detect failed login attempts in Nginx logs.
sudo nano /etc/fail2ban/filter.d/nginx-auth.confAdd the following content (it matches Nginx’s "401 Unauthorized" log entries):
[Definition] failregex = ^<HOST> - .* "(GET|POST) /.*" 401 ignoreregex =<HOST>is a Fail2ban placeholder that captures the attacker’s IP address.- The regex matches log lines where an IP tried to access a page and received a 401 (unauthorized) status code.
-
Configure the Jail: Open
jail.localand add a new section for the Nginx auth jail:[nginx-auth] enabled = true port = http,https filter = nginx-auth logpath = /var/log/nginx/access.log bantime = 24h maxretry = 5filter: Links to the filter file we created (nginx-auth.conf).logpath: Path to your Nginx access log.- Adjust
bantimeandmaxretryto your preference.
-
Restart Fail2ban:
sudo systemctl restart fail2ban -
Verify the Jail:
sudo fail2ban-client status nginx-auth
Advanced Fail2ban Features#
Whitelisting Trusted IPs#
To prevent banning trusted IPs (like your office or home network), add them to the ignoreip parameter in jail.local:
[DEFAULT]
ignoreip = 192.168.0.0/24 10.0.0.0/8 your_public_ipFor per-jail whitelisting, add ignoreip to the specific jail section:
[sshd]
ignoreip = 192.168.1.5Configuring Email Alerts#
Fail2ban can send email notifications when an IP is banned. To set this up:
-
Install an MTA (Mail Transfer Agent) like Postfix:
# Debian/Ubuntu sudo apt install postfix -y # RHEL/CentOS/Fedora sudo dnf install postfix -y -
Update
jail.localto enable email alerts:[DEFAULT] destemail = [email protected] sender = [email protected] action = %(action_mwl)saction_mwl: Sends an email with whois information and log lines related to the ban.
-
Restart Fail2ban:
sudo systemctl restart fail2ban
Persistent Bans (Survive Reboots)#
By default, Fail2ban bans are not persistent across server reboots. To fix this:
-
For UFW (Debian/Ubuntu): Install
ufwand ensure it saves rules automatically:sudo apt install ufw -y sudo ufw enableUFW saves rules to
/etc/ufw/user.rulesautomatically. -
For firewalld (RHEL/CentOS/Fedora): Firewalld persists rules by default, so bans will survive reboots.
Alternatively, use Fail2ban’s built-in persistent feature by adding this to jail.local:
[DEFAULT]
banaction = iptables-multiport
banaction_allports = iptables-allportsCustom Actions (Slack Notifications)#
You can create custom actions to send notifications to Slack or other services. Here’s a quick example for Slack:
-
Create an action file:
sudo nano /etc/fail2ban/action.d/slack-notify.confAdd the following content (replace
SLACK_WEBHOOK_URLwith your Slack webhook):[Definition] actionstart = actionstop = actioncheck = actionban = curl -X POST -H 'Content-type: application/json' --data '{"text":"[Fail2ban] Banned IP <ip> for service <name> (failed attempts: <failures>)"}' SLACK_WEBHOOK_URL actionunban = -
Update your jail to use this action:
[sshd] action = %(action_mwl)s slack-notify -
Restart Fail2ban to apply changes.
Testing Fail2ban#
To ensure Fail2ban is working correctly, simulate a failed login attempt:
-
Test SSH Jail: From a different machine, try logging in to your server with the wrong password 3 times (or whatever
maxretryyou set):ssh wrong_user@your_server_ip -
Check if the IP is banned:
sudo fail2ban-client status sshdYou should see the test IP listed under "Banned IP list".
-
Unban the IP if needed:
sudo fail2ban-client set sshd unbanip test_ip_address
Troubleshooting Common Issues#
-
Fail2ban isn’t banning IPs:
- Verify the
logpathin your jail points to the correct log file. - Use
fail2ban-regexto test if your filter matches log entries:sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf - Ensure the firewall is enabled and running.
- Verify the
-
Accidentally banned your own IP:
- Unban yourself using:
sudo fail2ban-client set sshd unbanip your_ip_address - Add your IP to
ignoreipinjail.localto prevent future bans.
- Unban yourself using:
-
Email alerts not working:
- Check if your MTA (Postfix/Sendmail) is running:
sudo systemctl status postfix - Verify the
destemailandsendersettings injail.local.
- Check if your MTA (Postfix/Sendmail) is running:
Best Practices for Fail2ban#
- Never edit
jail.conf: Always usejail.localor custom files in/etc/fail2ban/jail.d/. - Whitelist first: Add trusted IPs to
ignoreipbefore enabling jails. - Use strong regex: Test your filters with
fail2ban-regexto avoid false positives or negatives. - Disable SSH password authentication: Combine Fail2ban with SSH key-based authentication for maximum security.
- Update regularly: Keep Fail2ban and your server’s packages up to date to patch vulnerabilities.
- Monitor logs: Check
/var/log/fail2ban.logregularly for suspicious activity.
Conclusion#
Fail2ban is a lightweight, powerful tool that adds an essential layer of security to your Linux server. By automatically banning malicious IPs, it significantly reduces the risk of brute force attacks and other automated threats.
In this guide, we covered installing Fail2ban, configuring basic SSH protection, creating custom jails for web servers, and implementing advanced features like email alerts and Slack notifications. By following these steps and best practices, you can secure your server against common attacks and rest easier knowing your system is protected.