Configure Fail2Ban on AlmaLinux VPS: Step-by-Step

Why Fail2Ban Belongs on Every AlmaLinux VPS
A freshly provisioned VPS starts collecting SSH login attempts within minutes. That's not an exaggeration — automated scanners probe every publicly routable IP around the clock. On AlmaLinux, where many hosting customers run production workloads without a dedicated security team, Fail2Ban is the most practical first line of defence you can add in under an hour.
It works by monitoring log files and temporarily banning IPs that exceed a failure threshold. On AlmaLinux, that means writing rules to firewalld by default. It can protect SSH, cPanel, Postfix, Dovecot, and most other services that produce log output. Once it's tuned, it needs almost no ongoing attention.
This guide covers installation, jail configuration, and a handful of practical tweaks that matter in real hosting environments: sensible ban times, email alerts, and making sure the service survives a reboot. If you're running a Hostperl VPS on AlmaLinux 8 or 9, the steps below apply directly.
Step 1 — Install Fail2Ban on AlmaLinux
Fail2Ban isn't in the default AlmaLinux repositories, so you need EPEL first.
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
Enable and start the service:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Verify it's running:
sudo systemctl status fail2ban
You should see active (running). If AlmaLinux 9's SELinux is enforcing, Fail2Ban still works — it uses firewalld as its backend, which SELinux handles without issues.
Step 2 — Understand the Configuration Layout
Fail2Ban splits its configuration across two locations:
/etc/fail2ban/fail2ban.conf— core daemon settings/etc/fail2ban/jail.conf— all jail definitions (SSH, Apache, etc.)
Don't edit either of these directly. Package updates can overwrite them. Instead, put your changes in /etc/fail2ban/fail2ban.d/ and /etc/fail2ban/jail.d/ — these directories take priority and survive upgrades.
Start by creating a local jail configuration file:
sudo nano /etc/fail2ban/jail.d/local.conf
Step 3 — Configure Fail2Ban on AlmaLinux VPS: The SSH Jail
Paste the following into local.conf and adjust values to match your environment:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
backend = systemd
banaction = firewallcmd-ipset
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 3
bantime = 3600 bans an offending IP for one hour. findtime = 600 is the rolling window — if an IP fails maxretry times within 10 minutes, it gets banned. The SSH jail tightens the global maxretry down to 3, because SSH brute-force is both high-volume and high-risk.
The banaction = firewallcmd-ipset setting tells Fail2Ban to use firewalld with IP sets rather than individual rules. On a busy server, this matters — IP set rules don't slow down packet processing the way stacking individual iptables entries can.
Save the file and restart:
sudo systemctl restart fail2ban
Confirm the SSH jail is active:
sudo fail2ban-client status sshd
The output shows jail status, currently banned IPs, and total failures since the service started.
Step 4 — Protect cPanel or Web Services
If your server runs cPanel, jails for cPanel login attempts are worth adding. cPanel ships with its own cphulkd brute-force protection, but layering Fail2Ban on top of Apache or Nginx adds coverage for direct HTTP attacks on wp-login.php, xmlrpc.php, and similar targets.
For Apache authentication failures, add this to local.conf:
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/httpd/error_log
maxretry = 6
bantime = 7200
For Nginx:
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 6
Restart after any config change: sudo systemctl restart fail2ban. Then confirm both jails appear under sudo fail2ban-client status.
If your server also handles outbound mail, the cPanel SPF, DKIM and DMARC guide covers the complementary DNS-side protections.
Step 5 — Set Up Email Alerts for Bans
Knowing when Fail2Ban triggers is useful — an unusual spike in bans can signal a targeted attack rather than routine background scanning.
First, confirm sendmail or postfix is working on the server. Then add this to the [DEFAULT] block in local.conf:
destemail = you@yourdomain.com
sender = fail2ban@yourhostname
mta = sendmail
action = %(action_mwl)s
The %(action_mwl)s action bans the IP, sends an email, and includes the relevant log lines that triggered it. That context is what makes it useful — you can tell immediately whether it was a genuine attack or a misconfigured monitoring tool.
If you're seeing hundreds of bans per day from different IPs, also review your firewall rules. The UFW firewall setup guide covers a comparable approach on Ubuntu if you manage mixed-OS environments.
Step 6 — Whitelist Your Own IPs
Do this before anything else. Add your own IP — or your office's static IP — to the ignoreip list in [DEFAULT]:
ignoreip = 127.0.0.1/8 ::1 203.0.113.45
Replace 203.0.113.45 with your actual IP. Multiple addresses are separated by spaces. This is especially important for agencies managing client servers — a botched deployment script or a stalled SSH session can generate enough failures to lock out your own access if you skip this step.
If you manage multiple client VPS instances, VPS access management for hosting teams is worth reading to keep credentials and IP whitelists consistent across accounts.
Step 7 — Test the Configuration
Run a syntax check before trusting that everything is working:
sudo fail2ban-client -t
This validates all jail files without restarting the service. Fix any reported errors before moving on.
To verify a specific jail is reading logs correctly:
sudo fail2ban-client get sshd loglevel
Check the current jail status:
sudo fail2ban-client status sshd
The output shows total failures, currently failed IPs, and currently banned IPs. If you're seeing zero failures after a few minutes on a live server, double-check your logpath — pointing at the wrong log file is the most common cause.
Step 8 — Manage Bans Manually
Occasionally you'll need to unban a legitimate IP — a client who locked themselves out, or a monitoring service that tripped the threshold.
Unban a specific IP from the SSH jail:
sudo fail2ban-client set sshd unbanip 198.51.100.22
List all currently banned IPs across all jails:
sudo fail2ban-client banned
Fail2Ban doesn't do permanent bans by default — every ban expires after bantime. For persistent blocks on known bad actors, add them directly to firewalld as permanent rules rather than relying on Fail2Ban for that job.
To watch recent activity in real time:
sudo tail -f /var/log/fail2ban.log
This gives you a live feed of bans, unbans, and jail restarts — the fastest way to confirm everything is working after a config change.
Ongoing Maintenance
Once it's tuned, Fail2Ban needs very little attention. The main thing to watch is whether your ban counts stay reasonable. A spike in SSH jail bans often precedes a broader scanning campaign targeting your IP range.
After any AlmaLinux package update that touches Fail2Ban, run sudo systemctl status fail2ban to confirm the service is still running. Updates occasionally reset the service's enabled state on AlmaLinux 9 if the unit file changes.
For high-traffic servers, consider progressive ban times using the bantime.increment feature available in Fail2Ban 0.11+:
bantime.increment = true
bantime.multiplier = 2
bantime.maxtime = 86400
Add those three lines to your [DEFAULT] block. A first offence earns a one-hour ban, a second earns two hours, and so on — capped at 24 hours. This works particularly well against low-and-slow attackers who space out their attempts to stay under the findtime window.
For broader visibility into day-to-day server activity, the Logwatch email reports guide shows how to get daily summaries that include Fail2Ban activity alongside authentication logs and disk warnings.
Running AlmaLinux on a Hostperl VPS gives you a clean, production-ready environment where guides like this work without surprises. If your workload is outgrowing a VPS, Hostperl's dedicated server plans offer the same AlmaLinux-compatible stack with full root access and no resource contention. Our support team can help you migrate without downtime.
Frequently Asked Questions
Does Fail2Ban work with firewalld on AlmaLinux 9?
Yes. Set banaction = firewallcmd-ipset in your [DEFAULT] block and Fail2Ban will manage bans through firewalld's IP set interface. This is the recommended approach on both AlmaLinux 8 and 9.
How do I check which IPs are currently banned?
Run sudo fail2ban-client banned for a full list across all jails, or sudo fail2ban-client status sshd to see only SSH bans. You can also grep the log: grep 'Ban ' /var/log/fail2ban.log.
Can Fail2Ban ban legitimate users?
Yes — if someone repeatedly mistypes their password, or a script is running with stale credentials. Add any IPs you control to the ignoreip list in your [DEFAULT] block to prevent self-lockout. In managed hosting environments, also whitelist your monitoring system's IP.
What's the difference between bantime and findtime?
findtime is the rolling window during which failures are counted. bantime is how long a ban lasts once the threshold is hit. With findtime = 600 and maxretry = 3, an IP needs three failures within 10 minutes to get banned.
Will Fail2Ban survive a server reboot?
Yes, provided you ran sudo systemctl enable fail2ban. Active bans are stored in a persistent database at /var/lib/fail2ban/fail2ban.sqlite3 and restored on restart, so banned IPs don't get a free pass after a reboot.
