How to Install Fail2ban on Rocky Linux (10, 9, 8)

Fail2Ban protects Rocky Linux servers from brute-force attacks by monitoring log files and automatically banning IP addresses that show malicious behavior. When an attacker attempts repeated failed SSH logins, password guessing, or exploit scanning, Fail2Ban blocks their IP address through firewalld rules, preventing further access attempts. For internet-facing servers, this automated response stops most automated attacks before they succeed.

This guide covers installing and configuring Fail2Ban on Rocky Linux 10, 9, and 8. You will set up the EPEL repository, install Fail2Ban with firewalld integration, configure jails for SSH and web server protection, and learn commands to monitor bans and troubleshoot issues. By the end, your server will have automated intrusion prevention running alongside the firewalld rules you already use.

Fail2Ban installation steps are identical across Rocky Linux 10, 9, and 8. Version 10 and 9 include Fail2Ban 1.1.0 from EPEL, while version 8 provides Fail2Ban 1.0.2. Both versions support the configurations in this guide.

Update Rocky Linux Before Installation

Before installing Fail2Ban, update your system packages to ensure you have the latest security patches and avoid dependency conflicts. Run the following command to refresh package metadata and upgrade all installed packages:

sudo dnf upgrade --refresh

Install the EPEL Repository

Fail2Ban is not available in the default Rocky Linux repositories. The EPEL (Extra Packages for Enterprise Linux) repository provides Fail2Ban and thousands of other production-ready packages maintained by the Fedora Project.

Install the EPEL release package:

sudo dnf install -y epel-release

Verify EPEL is enabled:

dnf repolist | grep epel

Expected output on Rocky Linux 10:

epel                 Extra Packages for Enterprise Linux 10 - x86_64

Install Fail2Ban on Rocky Linux

With EPEL enabled, install Fail2Ban. The installation automatically includes the fail2ban-firewalld package, which configures Fail2Ban to work with Rocky Linux’s default firewall:

sudo dnf install -y fail2ban

This command installs Fail2Ban along with its firewalld integration and the sendmail action for email notifications. The package dependencies include firewalld itself, so the firewall will be available even on minimal installations.

Verify Installation

Confirm Fail2Ban installed correctly by checking the version:

fail2ban-client --version

Expected output on Rocky Linux 10:

Fail2Ban v1.1.0

Rocky Linux 8 shows version 1.0.2. Both versions work with all configurations in this guide.

Enable and Start Fail2Ban Service

Unlike some packages, Fail2Ban does not start automatically after installation. Enable the service to start at boot and launch it immediately:

sudo systemctl enable --now fail2ban

Verify the service is running:

systemctl status fail2ban

When running correctly, the output shows an active status:

● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: disabled)
     Active: active (running) since Wed 2026-01-15 10:30:00 UTC; 5s ago
       Docs: man:fail2ban(1)
    Process: 12345 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
   Main PID: 12346 (fail2ban-server)
      Tasks: 3 (limit: 4915)
     Memory: 12.0M
        CPU: 123ms
     CGroup: /system.slice/fail2ban.service
             └─12346 /usr/bin/python3 -s /usr/bin/fail2ban-server -xf start

Understand Fail2Ban Configuration Structure

Fail2Ban uses a layered configuration system where local files override defaults without being overwritten during package updates. Understanding this structure prevents common configuration mistakes.

Configuration File Hierarchy

Fail2Ban reads configuration files in a specific order, with later files overriding earlier ones:

  • /etc/fail2ban/jail.conf contains default jail definitions and settings (never edit this file directly)
  • /etc/fail2ban/jail.d/*.conf provides distribution-specific overrides, including 00-firewalld.conf for firewalld integration
  • /etc/fail2ban/jail.local holds your custom settings (create this file for overrides)
  • /etc/fail2ban/jail.d/*.local provides additional local customizations

The fail2ban-firewalld package creates /etc/fail2ban/jail.d/00-firewalld.conf, which sets the default ban action to use firewalld’s rich rules:

cat /etc/fail2ban/jail.d/00-firewalld.conf
# This file is part of the fail2ban-firewalld package to configure the use of
# the firewalld actions as the default actions.  You can remove this package
# (along with the empty fail2ban meta-package) if you do not use firewalld
[DEFAULT]
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

This configuration ensures Fail2Ban bans work correctly with firewalld without additional setup.

Create a Local Configuration File

Create jail.local for your custom settings. This file persists through package updates while jail.conf may be overwritten:

sudo nano /etc/fail2ban/jail.local

Start with a basic configuration that enables SSH protection:

[DEFAULT]
# Fail2Ban reads logs from systemd journal on Rocky Linux
backend = systemd

# IPs that should never be banned (add your admin IPs here)
ignoreip = 127.0.0.1/8 ::1

# Ban duration (10 minutes default)
bantime = 10m

# Time window for counting failures
findtime = 10m

# Number of failures before ban
maxretry = 5

[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 1h
findtime = 10m

This configuration protects SSH with stricter settings than the defaults: banning IPs for 1 hour after 3 failed login attempts within 10 minutes. The backend = systemd setting ensures Fail2Ban reads logs from the systemd journal, which Rocky Linux uses by default.

Save the file and restart Fail2Ban to apply changes:

sudo systemctl restart fail2ban

Configure Ban Time Settings

Fail2Ban offers several ways to configure ban durations, from simple fixed times to progressive escalation for repeat offenders.

Fixed Ban Times

The simplest approach sets a fixed ban duration for all offenses. Adjust the bantime value in your jail configuration:

# Examples of ban time formats
bantime = 10m      # 10 minutes
bantime = 1h       # 1 hour
bantime = 1d       # 1 day
bantime = -1       # Permanent ban (until manual unban)

Incremental Ban Times for Repeat Offenders

Fail2Ban can increase ban duration each time an IP triggers another offense. Add these settings to the [DEFAULT] section in jail.local:

# Enable incremental bans
bantime.increment = true

# Multiplier values for each subsequent ban
bantime.multipliers = 1 2 4 8 16 32 64

With a base bantime = 10m and these multipliers, an IP is banned for 10 minutes on first offense, 20 minutes on second, 40 minutes on third, and so on up to 640 minutes (about 10.5 hours) for persistent attackers.

Allowlist Trusted IP Addresses

Prevent specific IP addresses or networks from being banned by adding them to the ignoreip setting. This is essential for admin workstations and monitoring systems:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.50

This example allowlists localhost, IPv6 loopback, an entire local network (192.168.1.0/24), and a specific external IP. Always include your own IP address when working on remote servers to prevent accidental lockout.

Configure Additional Service Jails

Beyond SSH protection, Fail2Ban includes pre-configured filters for web servers, mail services, and other common attack vectors. Enable only the jails that match services running on your server to avoid unnecessary log monitoring overhead.

Apache Web Server Protection

If you run Apache on Rocky Linux, add these jails to jail.local:

# Protect against authentication failures
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 3
bantime = 1h

# Block malicious bot scanning
[apache-badbots]
enabled = true
port = http,https
logpath = %(apache_access_log)s
maxretry = 2
bantime = 48h

The apache-auth jail catches failed basic authentication attempts, while apache-badbots blocks automated scanners looking for vulnerabilities. Apache log paths on Rocky Linux default to /var/log/httpd/*error_log and /var/log/httpd/*access_log.

Nginx Web Server Protection

For Nginx servers, enable these jails:

# Protect against HTTP authentication failures
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
maxretry = 3
bantime = 1h

# Block bots scanning for exploits
[nginx-botsearch]
enabled = true
port = http,https
logpath = %(nginx_access_log)s
maxretry = 2
bantime = 2h

Web server jails use file-based logging because Apache and Nginx write to /var/log/httpd/ and /var/log/nginx/ by default. These log directories only exist after the respective web server is installed. Enabling a web server jail before installing the web server causes Fail2Ban to report log file not found errors.

Mail Server Protection

For Postfix and Dovecot mail servers, add authentication protection:

# Protect Postfix SMTP authentication
[postfix-sasl]
enabled = true
port = smtp,submission,smtps
backend = systemd
maxretry = 3
bantime = 1h

# Protect Dovecot IMAP/POP3
[dovecot]
enabled = true
port = imap,imaps,pop3,pop3s
backend = systemd
maxretry = 5
bantime = 1h

Apply Configuration Changes

After modifying jail.local, validate the syntax before restarting:

sudo fail2ban-client -t

When the configuration passes validation:

OK: configuration test is successful

Restart Fail2Ban to apply the new configuration:

sudo systemctl restart fail2ban

Manage Bans with Fail2Ban-Client

The fail2ban-client command provides tools to view jail status, manually ban or unban IPs, and reload configuration without restarting the service.

View Active Jails

Check which jails are currently running and their status:

sudo fail2ban-client status

Example output with SSH jail enabled:

Status
|- Number of jail:      1
`- Jail list:   sshd

View Jail Details and Banned IPs

Get detailed information about a specific jail, including currently banned IP addresses:

sudo fail2ban-client status sshd

Example output showing active bans:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     15
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     2
   `- Banned IP list:   203.0.113.7

The output shows that 15 failed attempts have been logged, 2 IPs have been banned in total, and 1 IP (203.0.113.7) is currently banned. The “Journal matches” line confirms Fail2Ban is reading from the systemd journal.

Ban an IP Address Manually

Block an IP address in a specific jail immediately without waiting for failed attempts:

sudo fail2ban-client set sshd banip 203.0.113.7

Manual bans follow the same duration as automatic bans unless you specify otherwise.

Unban an IP Address

Remove a ban from a specific IP address when you need to restore access:

sudo fail2ban-client set sshd unbanip 203.0.113.7

Use this when a legitimate user or service has been accidentally banned.

Reload Configuration Without Restart

Apply configuration changes without losing current ban states:

sudo fail2ban-client reload

A full restart with systemctl restart fail2ban clears all active bans, while reload preserves them while applying new jail configurations.

Verify Firewalld Integration

Fail2Ban on Rocky Linux uses firewalld’s rich rules to implement bans. Verify this integration is working correctly.

Test Ban Functionality

Confirm firewalld is running before testing bans:

sudo firewall-cmd --state
running

Ban a test IP address and verify the firewall rule is created:

sudo fail2ban-client set sshd banip 203.0.113.7
sudo firewall-cmd --list-rich-rules

Expected output showing the Fail2Ban-created rich rule:

rule family="ipv4" source address="203.0.113.7" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"

Unban the test IP to clean up:

sudo fail2ban-client set sshd unbanip 203.0.113.7

Check Firewalld Active Zones

View your current firewalld configuration to ensure SSH is allowed:

sudo firewall-cmd --list-all

Sample output on a Rocky Linux server:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

The services: ssh entry confirms SSH traffic is allowed through the firewall. When Fail2Ban adds a ban, the rich rules section shows the blocked IP addresses.

Monitor Fail2Ban Logs

Fail2Ban logs activity to /var/log/fail2ban.log by default. Use these logs to verify jails are working and investigate ban activity. The tail command provides several ways to view log files in real-time or review recent entries.

View Recent Log Activity

Check the last 20 lines of the Fail2Ban log:

sudo tail -20 /var/log/fail2ban.log

Monitor Log Activity in Real Time

Watch for ban and unban events as they happen:

sudo tail -f /var/log/fail2ban.log

Press Ctrl+C to stop following the log.

Search Logs for Specific Information

Use grep to search for specific IP addresses, jail names, or events:

# Find all ban events
grep "Ban" /var/log/fail2ban.log

# Search for a specific IP address
grep "203.0.113.7" /var/log/fail2ban.log

# Find SSH-related entries
grep "sshd" /var/log/fail2ban.log

Configure Email Notifications

Fail2Ban can send email notifications when bans occur. This requires a mail transfer agent capable of sending outbound email.

Install Mail Support

Install Postfix as a local mail relay and the s-nail utility for sending mail from the command line:

sudo dnf install -y postfix s-nail
sudo systemctl enable --now postfix

The s-nail package provides the mail command on Rocky Linux 9 and 10. On Rocky Linux 8, this package was called mailx, but s-nail works across all versions because it provides the same command interface.

Configure Email Alerts

Add email notification settings to the [DEFAULT] section in jail.local:

[DEFAULT]
destemail = admin@example.com
sender = fail2ban@example.com
# Send email with whois data and relevant log lines
action = %(action_mwl)s

The action_mwl action sends email alerts with whois information about the banned IP and the log lines that triggered the ban. Test email delivery before relying on it for critical alerts:

echo "Test email from Fail2Ban server" | mail -s "Fail2Ban Test" admin@example.com

Troubleshoot Common Issues

This section covers common problems encountered when setting up or running Fail2Ban on Rocky Linux.

Jails Not Starting or No Bans Occurring

If a jail is not working, check if it is enabled and running:

sudo fail2ban-client status

If the jail is not listed, verify the configuration syntax:

sudo fail2ban-client -t

Check the Fail2Ban log for startup errors:

sudo journalctl -xeu fail2ban

Filter Not Matching Log Entries

If a jail is running but not catching attacks, test the filter regex against actual log data. Rocky Linux uses the systemd journal for SSH logs by default, so use the systemd-journal source:

sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf

Add the -v flag for verbose output that shows exactly which regex patterns matched and what IP addresses were captured:

sudo fail2ban-regex -v systemd-journal /etc/fail2ban/filter.d/sshd.conf

The verbose output reveals whether the filter captured the HOST value (the attacker IP) from each log line. If you see None instead of an IP address, the filter pattern is matching but not extracting the IP correctly, and no bans will occur.

The /var/log/secure file only exists if you have rsyslog installed and configured. Default Rocky Linux installations write SSH logs to the systemd journal only. Use systemd-journal as the log source unless you have specifically configured rsyslog.

Firewalld Connection Problems

If bans are occurring in Fail2Ban but not blocking traffic, check firewalld status:

sudo systemctl status firewalld

If firewalld is not running, start and enable it:

sudo systemctl enable --now firewalld

Restart Fail2Ban after starting firewalld to reinitialize the ban action:

sudo systemctl restart fail2ban

Backend Configuration Errors

Rocky Linux uses the systemd journal for most service logs instead of traditional text files. If Fail2Ban reports log file not found errors for SSH or similar services, your jail configuration needs the systemd backend:

[DEFAULT]
backend = systemd

[sshd]
enabled = true

Setting backend = systemd in the [DEFAULT] section applies it to all jails. Jails for services that write to traditional log files (Apache, Nginx) automatically fall back to backend = auto when you specify a logpath instead of relying on the systemd journal.

The default backend = auto works well in most cases. It detects systemd and reads from the journal when appropriate, falling back to file monitoring when a logpath is specified. The explicit backend = systemd configuration guarantees journal-based monitoring even if auto-detection fails.

Remove Fail2Ban

If you no longer need Fail2Ban on your Rocky Linux system, follow these steps to remove it completely.

Stop and disable the service:

sudo systemctl stop fail2ban
sudo systemctl disable fail2ban

Remove the packages:

sudo dnf remove fail2ban fail2ban-firewalld fail2ban-sendmail fail2ban-server

DNF removes unused dependencies automatically. Configuration files in /etc/fail2ban/ remain after package removal by default.

The following command permanently deletes all Fail2Ban configuration files, including your custom jail settings in jail.local. If you might reinstall Fail2Ban later, skip this step to preserve your configurations.

sudo rm -rf /etc/fail2ban/

Remove the Fail2Ban log file and database:

sudo rm -f /var/log/fail2ban.log*
sudo rm -rf /var/lib/fail2ban/

Verify removal by checking for the package:

rpm -qa | grep fail2ban

No output confirms successful removal.

Conclusion

Your Rocky Linux server now has Fail2Ban protecting against brute-force attacks, with firewalld integration handling the actual traffic blocking. The SSH jail provides immediate protection, and you can extend coverage to web servers and mail services by enabling additional jails. For servers exposed to the public internet, consider combining Fail2Ban with SSH key-based authentication and disabling password login entirely for comprehensive protection. Regular log review with fail2ban-client status and tail -f /var/log/fail2ban.log helps identify attack patterns and tune ban thresholds to match your environment.

Leave a Comment

Let us know you are human: