Fail2ban is a free and open-source intrusion prevention software solution that protects servers from brute-force login attacks. It monitors various log files of SSH and other web applications, and whenever any failed authentication is detected and reaches the max numbers, Fail2Ban will automatically block the IP address using the iptables of Firewalld. Fail2Ban is simple, handy, easy to configure, and flexible.

In this guide, we will show you how to install Fail2Ban with firewalld on Rocky Linux 10.

Step 1 – Configure Firewalld

By default, Firewalld comes pre-installed in Rocky Linux 10. You can check whether it is installed by using the following command:

dnf update -y
dnf info firewalld

If the is installed, you will get the following output:

Last metadata expiration check: 0:04:44 ago on Sun 19 Oct 2025 11:44:30 PM EDT.
Installed Packages
Name         : firewalld
Version      : 2.3.0
Release      : 2.el10
Architecture : noarch
Size         : 2.0 M
Source       : firewalld-2.3.0-2.el10.src.rpm
Repository   : @System
From repo    : baseos
Summary      : A firewall daemon with D-Bus interface providing a dynamic firewall
URL          : http://www.firewalld.org
License      : GPL-2.0-or-later
Description  : firewalld is a firewall service daemon that provides a dynamic customizable
             : firewall with a D-Bus interface.

Available Packages
Name         : firewalld
Version      : 2.3.1
Release      : 1.el10_0
Architecture : noarch
Size         : 548 k
Source       : firewalld-2.3.1-1.el10_0.src.rpm
Repository   : baseos
Summary      : A firewall daemon with D-Bus interface providing a dynamic firewall
URL          : http://www.firewalld.org
License      : GPL-2.0-or-later
Description  : firewalld is a firewall service daemon that provides a dynamic customizable
             : firewall with a D-Bus interface.

Next, verify whether the Firewalld is running or not.

systemctl status firewalld

You should see that the Firewalld service is inactive:

○ firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
Active: inactive (dead) since Sun 2025-10-19 23:50:12 EDT; 1s ago
Duration: 6min 9.710s

So you will need to activate the Firewalld service. You can start it using the following command:

systemctl start firewalld
systemctl enable firewalld

At this point, Firewalld is installed and running in your system. You can now proceed to the next step.

Step 2 – Install Fail2Ban

By default, the Fail2Ban package is not included in the Rocky Linux 10 default repo, so you will need to add EPEL repo to your system. Run the following command to install the EPEL repo:

dnf install epel-release -y

Next, install the Fail2Ban package with the following command:

dnf install fail2ban fail2ban-firewalld -y

Once Fail2Ban is installed, start and enable the Fail2Ban service using the following command:

systemctl start fail2ban
systemctl enable fail2ban

You can verify the Fail2Ban version using the following command:

fail2ban-client --version

Sample output:

Fail2Ban v1.1.0

Step 3 – Configure Fail2Ban

By default, Fail2Ban is configured to use the iptables firewall, so you will need to configure Fail2Ban to work with Firewalld.

First, rename the Firewalld configuration file for Fail2Ban using the following command:

mv /etc/fail2ban/jail.d/00-firewalld.conf /etc/fail2ban/jail.d/00-firewalld.local

Next, copy the Fail2Ban default configuration file:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Next, edit the jail.local file:

nano /etc/fail2ban/jail.local

Find the following lines:

banaction = iptables-multiport
banaction_allports = iptables-allports

And replace them with the following lines:

banaction = firewallcmd-rich-rules[actiontype=]
banaction_allports = firewallcmd-rich-rules[actiontype=]

Save and close the file, then restart the Fail2Ban to apply the changes:

systemctl restart fail2ban

At this point, Fail2Ban is configured to work with Firewalld.

Step 4 – Secure SSH Service with Fail2Ban

By default, Fail2Ban is not configured to block any IP addresses. You will need to enable the specific jail for each service you want to protect.

To protect the SSHD service, edit the jail.local file:

nano /etc/fail2ban/jail.local

Find the [sshd] section and enable it by adding the following lines:

[sshd]

enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 10m
findtime = 10m
maxretry = 5

Save and close the file, then restart Fail2Ban to apply the changes:

systemctl restart fail2ban

You can now verify the status of Fail2Ban using the following command:

systemctl status fail2ban

You will get the following output:

fail2ban.service - Fail2Ban Service
     Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; disabled; preset: disabled)
     Active: active (running) since Sun 2025-10-19 23:47:48 EDT; 2s ago
 Invocation: bf7b50d6f60346e68c05b090c2c4d1d6
       Docs: man:fail2ban(1)
    Process: 44741 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
   Main PID: 44743 (fail2ban-server)
      Tasks: 5 (limit: 24809)
     Memory: 13.3M (peak: 36M)
        CPU: 807ms
     CGroup: /system.slice/fail2ban.service
             └─44743 /usr/bin/python3 -sP /usr/bin/fail2ban-server -xf start

2025-10-19 23:47:48,488 fail2ban.filter         [44743]: INFO    [sshd] Found 69.164.245.208 - 2025-10-19 23:47:36
2025-10-19 23:47:48,488 fail2ban.filtersystemd  [44743]: INFO    [sshd] Jail is in operation now (process new journal entries)
2025-10-19 23:47:48,575 fail2ban.actions        [44743]: NOTICE  [sshd] Ban 69.164.245.208
2025-10-19 23:47:48,825 fail2ban.actions        [44743]: NOTICE  [sshd] Ban 193.46.255.103
2025-10-19 23:47:49,077 fail2ban.actions        [44743]: WARNING [sshd] 69.164.245.208 already banne

Step 5 – Verify Fail2Ban Firewall

At this point, Fail2Ban is configured to protect the SSH service. Now, it’s time to check whether Fail2Ban is working.

First, verify the jail configuration using the following command:

fail2ban-client status

You should see the following output:

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

Now, go to the remote machine and try to connect to the SSH server with an incorrect password. After reaching the max number of retries (5 times), your IP address will be blocked by Fail2Ban.

Now, check the IP address blocked by Fail2Ban using the following command:

fail2ban-client status sshd

You should get the following output:

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

You can check the rules added by Firewalld with the following command:

firewall-cmd --list-rich-rules

You will get the following output:

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

You can also check the Fail2Ban logs for more information:

tail -f /var/log/fail2ban.log

Sample output:

2025-10-19 23:47:48,488 fail2ban.filter         [44743]: INFO    [sshd] Found 69.164.245.208 - 2025-10-19 23:47:36
2025-10-19 23:47:48,488 fail2ban.filtersystemd  [44743]: INFO    [sshd] Jail is in operation now (process new journal entries)
2025-10-19 23:47:48,575 fail2ban.actions        [44743]: NOTICE  [sshd] Ban 69.164.245.208
2025-10-19 23:47:48,825 fail2ban.actions        [44743]: NOTICE  [sshd] Ban 193.46.255.103
2025-10-19 23:47:49,077 fail2ban.actions        [44743]: WARNING [sshd] 69.164.245.208 already banned

Conclusion

Congratulations! You have successfully installed Fail2Ban with Firewalld. You can now implement Fail2Ban on your server to protect it against brute-force login attacks. Try it out on your VPS hosting account from Atlantic.Net!