Even with SSH key-based authentication enabled, your server’s SSH port is still probed constantly by automated scanners. Fail2Ban monitors log files for repeated authentication failures and bans offending IP addresses by inserting temporary rules into the firewall. On RHEL 8, Fail2Ban integrates natively with firewalld, making it the right tool to complement the hardening steps from earlier guides. This tutorial covers installing Fail2Ban from the EPEL 8 repository, creating a local jail configuration for SSH, adjusting ban parameters, checking ban status, manually unbanning IPs, and configuring a custom firewalld action for richer integration.

Prerequisites

  • A RHEL 8 server with the Initial Server Setup complete, firewalld active, and SSH key-based authentication configured
  • Root or sudo access
  • Internet access to reach the EPEL repository

Step 1 — Install EPEL and Fail2Ban

Fail2Ban is not in the default RHEL 8 AppStream repositories; it is available from the Extra Packages for Enterprise Linux (EPEL) repository. Install EPEL first, then install Fail2Ban.

dnf install -y epel-release
dnf install -y fail2ban
systemctl enable --now fail2ban
systemctl status fail2ban

Step 2 — Create a Local Jail Configuration

Fail2Ban ships a default configuration at /etc/fail2ban/jail.conf. You should never edit this file directly because package updates will overwrite your changes. Instead, create a jail.local override file. Settings in jail.local take precedence over jail.conf.

cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# Ban duration in seconds (600 = 10 minutes)
bantime  = 600

# Time window in seconds to count failures
findtime  = 300

# Number of failures before a ban is issued
maxretry = 5

# Use firewalld for banning (RHEL 8 default backend)
banaction = firewallcmd-ipset
banaction_allports = firewallcmd-allports

[sshd]
enabled  = true
port     = ssh
logpath  = /var/log/secure
maxretry = 3
bantime  = 3600
EOF

Restart Fail2Ban to load the new configuration:

systemctl restart fail2ban

Step 3 — Understand the Key Parameters

Three parameters control how aggressively Fail2Ban responds to brute-force attempts:

  • maxretry — number of failed attempts allowed within findtime before a ban; lower values ban faster
  • findtime — the sliding time window (in seconds) during which failures are counted
  • bantime — how long the IP stays banned; use -1 for a permanent ban
# View the active jail configuration after restart
fail2ban-client get sshd maxretry
fail2ban-client get sshd bantime
fail2ban-client get sshd findtime

Step 4 — Monitor Jail Status and Banned IPs

Use fail2ban-client to inspect which jails are active and which IPs are currently banned.

# List all active jails
fail2ban-client status

# Show status of the sshd jail including banned IPs
fail2ban-client status sshd

# Follow the Fail2Ban log in real time
tail -f /var/log/fail2ban.log

You can also check the firewalld ipset that Fail2Ban manages:

firewall-cmd --direct --get-all-rules

Step 5 — Unban an IP Address

If a legitimate user or your own IP gets banned, you can remove the ban manually without waiting for bantime to expire. Always verify the IP before unbanning to avoid accidentally whitelisting an attacker.

# Unban a specific IP from the sshd jail
fail2ban-client set sshd unbanip 203.0.113.42

# Verify the IP is no longer in the banned list
fail2ban-client status sshd

To prevent a trusted IP from ever being banned, add it to the ignoreip list in jail.local:

# Add to [DEFAULT] section in /etc/fail2ban/jail.local
# ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 your.office.ip.here

Step 6 — Configure a Custom firewalld Action

By default, Fail2Ban uses firewallcmd-ipset which efficiently manages large ban lists. If you prefer individual firewall-cmd rules (simpler to inspect but less scalable), create a custom action file. This is optional for most setups but useful when you need finer control over the firewall zone bans are applied to.

# Check which action is active
fail2ban-client get sshd action

# To use the standard rich-rule based action instead of ipset,
# edit jail.local and set:
#   banaction = firewallcmd-rich-rules

# Apply the change
sed -i 's/banaction = firewallcmd-ipset/banaction = firewallcmd-rich-rules/' /etc/fail2ban/jail.local
systemctl restart fail2ban
fail2ban-client status sshd

Conclusion

Fail2Ban is now protecting your RHEL 8 server’s SSH service. You installed it from EPEL, configured a jail.local override with sensible maxretry, findtime, and bantime values, confirmed the firewalld backend is in use, and learned how to inspect bans and unban legitimate users. Combined with SSH key-based authentication and a properly configured firewall, your server is well-defended against automated brute-force attacks.

Next steps: Initial Server Setup with RHEL 8, How to Configure the Firewall on RHEL 8, and How to Set Up SSH Key-Based Authentication on RHEL 8.