IPv4 & IPv6 Leasing - Any RIR, Any LocationOrder Now
Hostperl

Configure Fail2Ban on cPanel VPS: Stop Brute-Force Attacks

By Raman Kumar

Share:

Updated on Jul 2, 2026

Configure Fail2Ban on cPanel VPS: Stop Brute-Force Attacks

Why cPanel Servers Need Fail2Ban

A cPanel VPS exposes more attack surface than a plain Linux box. SSH is running, WHM is typically accessible on port 2087, cPanel on 2083, and Exim or Dovecot handle email auth. Any of those services will attract automated login attempts within hours of going live — sometimes within minutes. Without rate-limiting or IP blocking, a determined scanner can try thousands of password combinations before your monitoring even notices.

Fail2Ban solves this by watching log files in real time and banning IPs that exceed a set threshold of failed attempts. It writes a temporary firewall rule via iptables, holds the ban for a configurable period, then removes it. No manual intervention needed. On a Hostperl VPS, this runs cleanly alongside cPanel's own firewall tooling.

This tutorial covers installation on AlmaLinux 8 or 9 (the standard cPanel-supported OS in 2026), custom jails for cPanel-specific services, and email alert configuration so you know when bans are firing.

Before You Start

Confirm the following before installing anything:

  • Root SSH access to your VPS
  • cPanel/WHM already installed and running
  • CSF (ConfigServer Security & Firewall) status — see note below
  • A working mail relay for alert emails (optional but useful)

CSF compatibility note: Many cPanel servers run CSF, which is a firewall wrapper that also does basic brute-force detection via its lfd daemon. You can run Fail2Ban alongside CSF, but make sure Fail2Ban uses the iptables-multiport action rather than trying to manage chains CSF already owns. We'll configure that explicitly below. If you're running CSF in aggressive mode, you may want to skip the Fail2Ban SSH jail entirely and only use it for services CSF doesn't cover well — like Dovecot SASL or custom applications.

Step 1 — Install Fail2Ban via EPEL

Fail2Ban isn't in the default AlmaLinux repos. Install it from EPEL:

dnf install epel-release -y
dnf install fail2ban fail2ban-sendmail -y

Enable and start the service:

systemctl enable fail2ban
systemctl start fail2ban

Verify it's running:

systemctl status fail2ban

You should see active (running). If Fail2Ban exits immediately after starting, there's usually a syntax error in a jail config — we'll get to that.

Step 2 — Create Your Local Configuration

Never edit /etc/fail2ban/jail.conf directly. That file gets overwritten on package updates. Create a local override instead:

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

Open /etc/fail2ban/jail.local and find the [DEFAULT] section. Set these values:

[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5
backend  = auto
usedns   = warn
action   = %(action_mwl)s

bantime holds each ban for one hour. findtime is the window over which failures are counted — 10 minutes here. maxretry is the threshold before a ban fires. action_mwl bans the IP and sends you a log excerpt by email.

Also add your email settings under [DEFAULT]:

destemail = you@yourdomain.com
sender    = fail2ban@yourvps.com
mta       = sendmail

Step 3 — Configure Jails for cPanel Services

Create a dedicated file for your cPanel-specific jails. This keeps things clean and easy to audit:

nano /etc/fail2ban/jail.d/cpanel.conf

Add the jails below. Adjust paths if your cPanel installation differs from the defaults.

SSH Jail

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/secure
maxretry = 4
bantime  = 7200

SSH gets a tighter threshold (4 attempts) and a longer ban (2 hours) because legitimate users rarely mistype their key more than once.

cPanel Login Jail

cPanel logs failed logins to /usr/local/cpanel/logs/login_log. There's no built-in Fail2Ban filter for this, so you'll create one in the next step.

[cpanel-login]
enabled  = true
port     = 2082,2083,2086,2087
filter   = cpanel-login
logpath  = /usr/local/cpanel/logs/login_log
maxretry = 5
bantime  = 3600

Dovecot IMAP/POP3 Jail

[dovecot]
enabled  = true
port     = pop3,pop3s,imap,imaps,submission,465,sieve
filter   = dovecot
logpath  = /var/log/maillog
maxretry = 6

Exim SMTP Auth Jail

[exim-auth]
enabled  = true
port     = smtp,465,587
filter   = exim
logpath  = /var/log/exim_mainlog
maxretry = 6

Locking down Fail2Ban on cPanel VPS is only part of the picture. If your Exim or Dovecot configuration isn't properly secured, the brute-force attempts will keep coming regardless. The email deliverability checklist for VPS hosting covers the broader job of locking down outbound mail as well.

Step 4 — Create the cPanel Login Filter

Fail2Ban needs a regex filter to identify failed logins in cPanel's log format. Create the filter file:

nano /etc/fail2ban/filter.d/cpanel-login.conf

Add this content:

[Definition]
failregex = .*cpaneld.*Failed login for .* from <HOST>
            .*whostmgrd.*Failed login for .* from <HOST>
            .*Failed login .* \[<HOST>\]
ignoreregex =

Save the file. Before enabling the jail, test the filter against real log entries:

fail2ban-regex /usr/local/cpanel/logs/login_log /etc/fail2ban/filter.d/cpanel-login.conf

The output shows how many lines matched. If your cPanel version logs things slightly differently, adjust the regex until you see real matches. The login log format hasn't changed significantly since cPanel v110, but verify it on your specific build anyway.

Step 5 — Whitelist Your Own IP

Before reloading Fail2Ban, add your IP to the ignore list. Locking yourself out of WHM is a painful way to test a new config.

In /etc/fail2ban/jail.local, add this under [DEFAULT]:

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

If you manage multiple client servers from a shared static IP, keep a record of this in your team's documentation. Resellers and agencies handling several cPanel accounts should also read the VPS access management guide for hosting teams for broader team-level controls.

Step 6 — Reload and Verify

Reload Fail2Ban to apply all changes:

fail2ban-client reload

Check which jails are now active:

fail2ban-client status

You should see all four jails listed. Inspect an individual jail like this:

fail2ban-client status sshd

This shows currently banned IPs, total failures tracked, and the full ban list. If a jail shows as inactive after reload, test your config for syntax errors:

fail2ban-client -t

That command validates your configuration without restarting the service. Fix any reported errors, then reload again.

Manually Ban and Unban IPs

To manually ban an IP in a specific jail:

fail2ban-client set sshd banip 198.51.100.42

To unban (useful if you accidentally trigger a ban on a known-good IP):

fail2ban-client set sshd unbanip 198.51.100.42

To clear a ban across all active jails, you'll need to run the unban command per jail or write a short loop. If you're fully locked out, you'll need console or KVM access — which is exactly why whitelisting your office IP in Step 5 matters.

Checking the Ban Log

Fail2Ban writes to /var/log/fail2ban.log. Tail it during a test to watch bans fire in real time:

tail -f /var/log/fail2ban.log

A successful ban entry looks like this:

2026-03-12 04:17:33,482 fail2ban.actions [1234]: NOTICE  [sshd] Ban 198.51.100.42

If you configured email alerts with action_mwl, you'll also get a message containing the offending IP, the log excerpt that triggered the ban, and a WHOIS result. That context is useful for spotting patterns — some IP ranges hit dozens of cPanel servers in quick succession.

Common Problems on cPanel Servers

Fail2Ban conflicts with CSF/lfd

If bans aren't sticking or iptables rules are disappearing, CSF may be flushing Fail2Ban's chains on restart. Set Fail2Ban to use the iptables-allports action for services CSF already manages, or configure CSF to preserve external chains. The simplest fix: use Fail2Ban only for cPanel login and application-level jails, and let CSF handle SSH if it's already doing so.

Log path not found

If Fail2Ban can't open a log file, the jail won't start. Check that /usr/local/cpanel/logs/login_log exists and is readable by root. On some cPanel versions the filename differs slightly — verify with ls /usr/local/cpanel/logs/ before enabling the jail.

Too many false positives

If legitimate users are getting banned — especially email clients with cached wrong passwords — raise maxretry for Dovecot to 10 or increase findtime to 1800. Both can be set as per-jail overrides without touching the global default.

If you're building a broader security baseline, pair Fail2Ban with a properly configured firewall. The UFW firewall setup guide covers the firewall layer, and the VPS security checklist for 2026 gives you a full picture of what else needs locking down.

Need a cPanel server that's ready to harden from day one? Hostperl VPS plans come with full root access and KVM console, so you can configure Fail2Ban, CSF, and cPanel security exactly as you need — no restrictions. For high-traffic sites or agencies managing multiple accounts, our dedicated server options give you more headroom and predictable performance.

Frequently Asked Questions

Can I run Fail2Ban and CSF at the same time on cPanel?

Yes, but carefully. CSF's lfd daemon does similar work for SSH and basic service auth. The safest approach is to use Fail2Ban only for services CSF doesn't cover — like the cPanel login page or custom apps — and leave SSH to CSF if it's already configured there.

Which cPanel log files does Fail2Ban monitor?

For this setup: /usr/local/cpanel/logs/login_log for cPanel/WHM logins, /var/log/maillog for Dovecot, /var/log/exim_mainlog for Exim SMTP, and /var/log/secure for SSH. Always verify these paths exist on your specific cPanel version before enabling a jail.

How do I increase the ban duration for repeat offenders?

Fail2Ban 0.11+ supports bantime.increment, which automatically extends bans for repeat offenders. Add bantime.increment = true and bantime.multiplier = 2 4 8 16 32 64 to your [DEFAULT] section. Each repeat ban doubles the duration.

What's a safe maxretry value for cPanel logins?

Five is a reasonable starting point. Real users rarely fail five logins in ten minutes. If your team shares an IP and occasionally mistype passwords, whitelist that IP rather than raising the threshold for everyone.