What it is
Fail2ban is an intrusion prevention software framework that protects computer servers from brute-force attacks by monitoring log files and banning IP addresses that show malicious signs.
Installation
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install fail2ban
Linux (CentOS/RHEL/Fedora)
sudo yum install epel-release
sudo yum install fail2ban
Mac (using Homebrew)
brew install fail2ban
Note: Fail2ban is primarily designed for Linux servers. While it can be installed on macOS, its effectiveness for protecting services typically running on servers is limited.
Windows
Fail2ban is not natively supported on Windows. For Windows server protection, consider Windows Firewall with Advanced Security and other dedicated security solutions.
Core Concepts
- Jail: A Fail2ban configuration that defines how to monitor logs for specific services and what actions to take when malicious activity is detected. Jails are defined in
.confand.localfiles. - Filter: A regular expression that Fail2ban uses to identify suspicious log entries. Filters are stored in
/etc/fail2ban/filter.d/. - Action: A script executed by Fail2ban when an IP address is banned. Actions typically involve modifying firewall rules to block the offending IP. Actions are stored in
/etc/fail2ban/action.d/. jail.local: The primary configuration file for customizing Fail2ban behavior. It overrides settings injail.conf. Always make your customizations here to avoid losing them during package updates.fail2ban-client: The command-line utility used to interact with the Fail2ban service (start, stop, restart, check status, unban IPs).
Commands / Usage
Managing the Fail2ban Service
-
Start Fail2ban:
sudo systemctl start fail2banStarts the Fail2ban service.
-
Stop Fail2ban:
sudo systemctl stop fail2banStops the Fail2ban service.
-
Restart Fail2ban:
sudo systemctl restart fail2banRestarts the Fail2ban service.
-
Check Fail2ban Status:
sudo systemctl status fail2banShows the current status of the Fail2ban service.
-
Enable Fail2ban on Boot:
sudo systemctl enable fail2banEnsures Fail2ban starts automatically when the system boots.
-
Disable Fail2ban on Boot:
sudo systemctl disable fail2banPrevents Fail2ban from starting automatically when the system boots.
Interacting with Jails (fail2ban-client)
-
Reload Configuration:
sudo fail2ban-client reloadReloads all jail configurations without restarting the service.
-
Check Status of All Jails:
sudo fail2ban-client statusDisplays the status of all active jails, including the number of currently banned IPs.
-
Check Status of a Specific Jail:
sudo fail2ban-client status sshdDisplays the status of the
sshdjail, showing banned IPs. -
Unban an IP Address:
sudo fail2ban-client set sshd unbanip 192.168.1.100Unbans the IP address
192.168.1.100from thesshdjail. -
Unban an IP Address from All Jails:
sudo fail2ban-client unban 192.168.1.100Unbans the IP address
192.168.1.100from all jails. -
Manually Ban an IP Address:
sudo fail2ban-client set sshd banip 192.168.1.100Manually bans the IP address
192.168.1.100for thesshdjail. This will also trigger the ban action. -
List All Enabled Jails:
sudo fail2ban-client get allLists all enabled jails and their current configurations.
-
Get a Specific Jail Setting:
sudo fail2ban-client get sshd portRetrieves the port number configured for the
sshdjail. -
Set a Specific Jail Setting:
sudo fail2ban-client set sshd port = 2222Changes the port number for the
sshdjail to2222. Note: This change is temporary and will be lost on reload/restart unless updated in.localfiles.
Configuration Files
/etc/fail2ban/jail.conf: The main configuration file. Do not edit directly./etc/fail2ban/jail.local: Your custom configuration file. Create this to overridejail.conf./etc/fail2ban/filter.d/: Directory containing filter definitions (regex for log parsing)./etc/fail2ban/action.d/: Directory containing action definitions (scripts to ban/unban IPs).
Common Configuration Options (in jail.local)
-
[DEFAULT]Section: Settings applied to all jails unless overridden.bantime = 10mSets the duration an IP is banned (e.g.,10mfor 10 minutes,1hfor 1 hour,1dfor 1 day).findtime = 10mThe time window during which Fail2ban counts failed attempts.maxretry = 5The number of failed attempts allowed withinfindtimebefore an IP is banned.backend = autoSpecifies how Fail2ban monitors log files (e.g.,auto,pyinotify,polling).autois usually sufficient.destemail = root@localhostThe email address to send notifications to.sendername = Fail2BanThe name used in the sender field of notification emails.sender = root@localhostThe sender email address for notifications.action = %(action_mw)sThe default action to take when an IP is banned. Common actions include:%(action_)s: Ban only.%(action_mw)s: Ban and send an email with whois report.%(action_mwl)s: Ban and send an email with whois report and relevant log lines.
ignoreip = 127.0.0.1/8 ::1A space-separated list of IP addresses or CIDR ranges to always ignore (never ban).
-
Service-Specific Jails (e.g.,
[sshd])enabled = trueEnables the jail. Set tofalseto disable.port = sshThe port number or service name to monitor. Can be a comma-separated list.filter = sshdThe name of the filter to use (corresponds to a file in/etc/fail2ban/filter.d/, e.g.,sshd.conf).logpath = /var/log/auth.logThe path to the log file to monitor.maxretry = 3Overrides the defaultmaxretryfor this specific jail.bantime = 1hOverrides the defaultbantimefor this specific jail.action = %(action_mwl)sOverrides the default action for this specific jail.
Common Patterns
-
Enable SSH protection with email notifications: Create
/etc/fail2ban/jail.localand add:[DEFAULT] # Use mail action for notifications action = %(action_mwl)s destemail = your_email@example.com sender = fail2ban@your_server.com [sshd] enabled = true port = ssh logpath = /var/log/auth.log maxretry = 3 bantime = 1dThen restart Fail2ban:
sudo systemctl restart fail2ban. -
Protecting multiple services (e.g., SSH, Apache, Postfix): In
/etc/fail2ban/jail.local:[DEFAULT] bantime = 1h findtime = 10m maxretry = 5 ignoreip = 127.0.0.1/8 192.168.0.0/24 [sshd] enabled = true port = ssh logpath = %(sshd_log)s maxretry = 3 [apache-auth] enabled = true port = http,https logpath = %(apache_error_log)s filter = apache-auth [postfix] enabled = true port = smtp,ssmtp logpath = %(postfix_mail_log)s filter = postfixNote:
%(sshd_log)s,%(apache_error_log)s, etc., are variables defined in/etc/fail2ban/paths-common.confand/etc/fail2ban/paths-*.conf. -
Customizing ban time and retries for a specific jail: In
/etc/fail2ban/jail.local:[nginx-http-auth] enabled = true port = http,https logpath = /var/log/nginx/error.log filter = nginx-http-auth maxretry = 2 bantime = 12h -
Viewing currently banned IPs for a jail:
sudo fail2ban-client status sshdLook for the "Currently banned" section.
-
Adding an IP to the ignore list permanently: Edit
/etc/fail2ban/jail.localand add the IP to theignoreipline in the[DEFAULT]section:[DEFAULT] ignoreip = 127.0.0.1/8 ::1 192.168.1.50Then reload Fail2ban:
sudo fail2ban-client reload. -
Using a custom filter:
- Create a filter file, e.g.,
/etc/fail2ban/filter.d/mycustomapp.local:[Definition] failregex = ^%(__prefix)s Failed login for user .* from <HOST>$ ignoreregex = - Enable it in
jail.local:[mycustomapp] enabled = true port = 8080 logpath = /var/log/mycustomapp.log filter = mycustomapp maxretry = 10 bantime = 1d - Reload Fail2ban:
sudo fail2ban-client reload.
- Create a filter file, e.g.,
-
Using a custom action:
- Create an action file, e.g.,
/etc/fail2ban/action.d/mycustomaction.local:[Definition] actionstart = echo "Starting custom action for <name> jail." >> /var/log/fail2ban_custom.log actionstop = echo "Stopping custom action for <name> jail." >> /var/log/fail2ban_custom.log actionban = echo "Banning <ip> for <name> jail." >> /var/log/fail2ban_custom.log actionunban = echo "Unbanning <ip> for <name> jail." >> /var/log/fail2ban_custom.log - Reference it in
jail.local:[sshd] enabled = true # ... other settings action = mycustomaction - Reload Fail2ban:
sudo fail2ban-client reload.
- Create an action file, e.g.,
Gotchas
- Editing
jail.confdirectly: Any changes made directly tojail.confwill be overwritten during package upgrades. Always usejail.localfor your customizations. - Log file locations: Ensure the
logpathin your jail configuration correctly points to the service’s log file. Different distributions or applications might use different paths. - Filter regex: The regular expressions in filters must accurately match the log entries you want to catch. Incorrect regex is the most common reason filters don’t work. Use
fail2ban-regexto test your filters.sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf - Firewall conflicts: Fail2ban relies on firewall rules (usually
iptables). If you have other firewall management tools or complex firewall configurations, they might interfere with Fail2ban’s actions. bantime = 0: Settingbantime = 0means IPs will be banned permanently until manually unbanned or Fail2ban is restarted. Use with caution.findtimeandmaxretryinteraction: Fail2ban countsmaxretryfailures within thefindtimewindow. Iffindtimeis very short, an attacker might be able to retry enough times to trigger a ban quickly. Iffindtimeis too long, it might not be aggressive enough.- IPv6 support: Ensure your firewall (e.g.,
iptables) is configured to handle IPv6 if you need to ban IPv6 addresses. Fail2ban actions often need specific IPv6 counterparts (e.g.,actionbanvsactionban6). Many default actions include IPv6 support. - Service restarts: After modifying
jail.local, you must either reload (sudo fail2ban-client reload) or restart (sudo systemctl restart fail2ban) the service for changes to take effect. Reload is generally preferred for applying configuration changes without interrupting active monitoring.