The Best Price for IPv4/IPv6 Lease – Any RIR & Any Geo-LocationOrder Now
Hostperl

Configure Fail2Ban on AlmaLinux VPS: Step-by-Step

By Raman Kumar

Share:

Updated on Jun 28, 2026

Configure Fail2Ban on AlmaLinux VPS: Step-by-Step

Why Fail2Ban Belongs on Every AlmaLinux VPS

A freshly provisioned AlmaLinux VPS starts collecting failed SSH login attempts within minutes of going live. That's not an exaggeration — automated scanners probe every public IP continuously. Fail2Ban watches your log files and bans offending IPs at the firewall level after a configurable number of failures. It's not a replacement for good SSH key hygiene, but it meaningfully reduces noise and stops low-effort credential attacks in their tracks.

This tutorial walks through a complete Fail2Ban setup on AlmaLinux 8 or 9, covering SSH protection, Apache and mail service jails, email alerting, and a few tuning decisions that matter in practice. If you're hosting client sites or running any public-facing service on a Hostperl VPS, this is a baseline security step you shouldn't skip.

Step 1: Install Fail2Ban on AlmaLinux

Fail2Ban isn't in the default AlmaLinux repos, but it's available through EPEL. Enable EPEL first, then install:

sudo dnf install -y epel-release
sudo dnf install -y fail2ban

Once installed, enable and start the service:

sudo systemctl enable --now fail2ban

Confirm it's running:

sudo systemctl status fail2ban

You should see active (running). If it fails to start, check /var/log/fail2ban.log — a common early issue is a missing firewalld or iptables backend.

Step 2: Create Your Local Configuration File

Never edit /etc/fail2ban/jail.conf directly. Upstream updates overwrite it. Instead, create a local override:

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

Then open jail.local for editing:

sudo nano /etc/fail2ban/jail.local

Find the [DEFAULT] section near the top. These are the values that matter most for a typical VPS:

[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5
backend  = systemd
banaction = firewallcmd-ipset

What these mean:

  • bantime — how long (in seconds) an IP stays banned. 3600 = 1 hour. Raise it to 86400 for persistent offenders.
  • findtime — the window in which failures are counted. 600 seconds = 10 minutes.
  • maxretry — failures within findtime before a ban triggers.
  • backend = systemd — tells Fail2Ban to read from journald rather than flat log files. Essential on AlmaLinux 8/9.
  • banaction = firewallcmd-ipset — uses firewalld with ipset for efficient banning. Works cleanly with AlmaLinux's default firewall.

Step 3: Enable the SSH Jail

SSH protection is the most important jail on any internet-facing server. In jail.local, find or add this block:

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 4
bantime  = 7200

A stricter maxretry = 4 and longer bantime = 7200 (2 hours) makes sense for SSH specifically. If you've moved SSH to a non-standard port, update the port value accordingly — for example, port = 2222.

After any change to jail.local, reload Fail2Ban:

sudo systemctl reload fail2ban

Check that the jail is active:

sudo fail2ban-client status sshd

You'll see current banned IPs and a running failure count. If the jail shows as inactive, double-check that enabled = true is set and that the backend matches your log source.

Step 4: Protect Apache and Mail Services

If you're running Apache and a mail stack, those deserve their own jails too. Add these blocks to jail.local:

[apache-auth]
enabled  = true
port     = http,https
logpath  = %(apache_error_log)s
maxretry = 6

[apache-badbots]
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
maxretry = 2

[postfix]
enabled  = true
port     = smtp,465,submission
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

[dovecot]
enabled  = true
port     = pop3,pop3s,imap,imaps
logpath  = %(dovecot_log)s

The apache-badbots jail catches known scraper and vulnerability scanner signatures. A maxretry = 2 is appropriate — legitimate browsers don't trigger bad-bot filter rules repeatedly. For a deeper look at managing email security alongside Fail2Ban, the email deliverability checklist for VPS hosting covers SPF, DKIM, and DMARC alongside firewall hygiene.

Reload after adding jails:

sudo systemctl reload fail2ban

Step 5: Configure Email Alerts for Bans

Fail2Ban can send you an email whenever it bans an IP — useful for staying aware of attack patterns without watching logs manually. In the [DEFAULT] section of jail.local:

destemail = you@yourdomain.com
sender    = fail2ban@yourhostname
mta       = sendmail
action    = %(action_mwl)s

The %(action_mwl)s action bans the IP, sends an email with the offending log lines, and includes a WHOIS lookup. This requires a working mail transfer agent on the server. If you're using Postfix, ensure it's installed and can relay outbound mail. The Postfix mail relay setup guide covers the relay configuration — the same steps apply on AlmaLinux with minor package name differences.

If email alerts aren't critical for your setup, use the simpler %(action_)s action, which bans without sending notifications.

Step 6: Whitelist Your Own IPs

Before anything else bans you from your own server, whitelist your management IPs. In the [DEFAULT] section:

ignoreip = 127.0.0.1/8 ::1 YOUR.OFFICE.IP.HERE

Separate multiple IPs or CIDR ranges with spaces. If you connect from a dynamic IP, consider using SSH key authentication exclusively rather than relying on a whitelist that may become stale. Locking yourself out of a VPS is a support ticket no one enjoys — Hostperl's support team can help restore access, but it's avoidable with a brief whitelist check upfront.

Step 7: Monitor Bans and Unban IPs

Check all active jails at once:

sudo fail2ban-client status

Check a specific jail:

sudo fail2ban-client status sshd

To unban a specific IP from the sshd jail:

sudo fail2ban-client set sshd unbanip 203.0.113.45

Bans are stored in memory by default, so they reset on a service restart. To make bans persistent across reboots, enable the dbpurgeage option in jail.local:

dbpurgeage = 86400

This keeps the ban database for 24 hours after the ban expires, which also survives restarts within that window. For heavier attack traffic, consider increasing bantime to several days or using a blocklist alongside Fail2Ban.

Tuning Fail2Ban for Shared and Reseller Hosting

If your AlmaLinux VPS hosts multiple client sites — either directly or through a control panel like DirectAdmin or cPanel — a few adjustments are worth making.

First, confirm that your jails use the correct log paths for your control panel stack. cPanel uses its own Apache log layout under /usr/local/apache/logs/. Update your apache_error_log and apache_access_log paths accordingly if you're on a cPanel server.

Second, consider lower maxretry thresholds for mail authentication jails. A client's customer trying five different passwords is still likely a legitimate user, but automated credential stuffing attempts typically exceed 20 tries per minute. A maxretry = 10 on Dovecot and Postfix jails with a short findtime = 120 catches the automated pattern without locking out legitimate forgetful users.

If your VPS is handling heavier hosting workloads, it may also be a good time to review your VPS sizing for your current workloads — Fail2Ban itself is lightweight, but aggressive scanning can spike CPU briefly during log parsing under high load.

Verifying Your Setup End to End

Run a quick end-to-end check once all jails are live:

  1. From a separate IP (not your whitelisted one), trigger a few failed SSH logins.
  2. Watch the Fail2Ban log: sudo tail -f /var/log/fail2ban.log
  3. Confirm a ban appears after your configured maxretry count.
  4. Check sudo fail2ban-client status sshd to see the IP listed as banned.
  5. Verify the IP is blocked at the firewall: sudo firewall-cmd --list-all

If bans appear in the Fail2Ban log but the IP still reaches the server, the firewall backend may not be applying rules correctly. Confirm firewalld is active with sudo systemctl status firewalld and that your banaction matches. The firewallcmd-ipset backend requires ipset support — install it with sudo dnf install -y ipset if it's missing.

For broader server hardening alongside Fail2Ban, the VPS security checklist for hosting customers covers UFW configuration, SSH hardening, and access controls that complement what Fail2Ban handles.

Running a public-facing VPS without brute-force protection is an unnecessary risk. Hostperl's VPS hosting plans give you full root access to configure Fail2Ban and the rest of your security stack exactly as this guide covers. Need a higher-spec server for multiple client sites or heavier traffic? Hostperl dedicated servers offer the same hands-on control with dedicated resources and no noisy neighbours affecting your firewall performance.

Frequently Asked Questions

Does Fail2Ban work with firewalld on AlmaLinux 9?

Yes. Set banaction = firewallcmd-ipset in your [DEFAULT] block and ensure firewalld is running. The firewallcmd-ipset action is more efficient than firewallcmd-new when banning large numbers of IPs because it groups them into an ipset rather than creating individual firewall rules.

Will Fail2Ban slow down my server?

Not meaningfully under normal conditions. Fail2Ban uses inotify to watch log files rather than polling them on a timer, so CPU use stays low. The main overhead comes during log parsing after a burst of failed attempts — typically a fraction of a second on any modern VPS.

What's the difference between bantime and findtime?

findtime is the observation window — how far back Fail2Ban looks when counting failures. bantime is how long a ban lasts once triggered. A findtime = 600 with maxretry = 5 means five failures within any 10-minute window triggers a ban lasting bantime seconds.

Can I use Fail2Ban with a non-standard SSH port?

Yes. In your [sshd] jail block, change port = ssh to port = 2222 (or whatever port you've configured). Fail2Ban still reads the same SSH logs — the port value is used to construct the correct firewall rule for the ban.

How do I check which IPs are currently banned?

Run sudo fail2ban-client status sshd (replace sshd with any jail name) to list currently banned IPs for that jail. For a full view across all jails, run sudo fail2ban-client status first to list active jails, then check each one individually.