Every public-facing Linux server is hit by automated brute-force attacks within minutes of coming online — bots cycle through thousands of username and password combinations against SSH, mail, cPanel, and WordPress login forms. Fail2Ban is the simplest, most effective defence: it watches your log files, spots repeated failures from the same IP, and temporarily blocks that IP with a firewall rule. This guide explains how Fail2Ban works and how to configure it to protect SSH, cPanel, and WordPress.
How Fail2Ban Works
Fail2Ban is built from three concepts:
- Filters — regular expressions that match a failed-login line in a log file.
- Jails — a pairing of a filter with a log path, thresholds, and an action.
- Actions — what happens on a match, usually adding a firewall ban via
iptables,nftables, orfirewalld.
When the number of matches from one IP exceeds maxretry within findtime, that IP is banned for bantime.
Installation
# Debian / Ubuntu
sudo apt install fail2ban
# RHEL / AlmaLinux / Rocky (needs EPEL)
sudo dnf install epel-release && sudo dnf install fail2ban
sudo systemctl enable --now fail2ban
Never edit jail.conf directly — it is overwritten on upgrade. Put all your settings in /etc/fail2ban/jail.local, which takes precedence.
Global Defaults
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
# Never lock yourself out — whitelist your own IPs
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
Consider bantime = -1 for permanent bans on the most-attacked services, or use incremental banning so repeat offenders are blocked progressively longer:
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w
Protecting SSH
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 1d
This is the single most valuable jail. Combined with key-based authentication and disabling password logins, it eliminates the vast majority of SSH attack noise.
Protecting cPanel & WHM
cPanel logs failed logins to /usr/local/cpanel/logs/login_log. Create a custom filter and jail:
# /etc/fail2ban/filter.d/cpanel.conf
[Definition]
failregex = ^.*FAILED LOGIN.*\s+from\s+<HOST>.*$
ignoreregex =
# /etc/fail2ban/jail.local
[cpanel]
enabled = true
filter = cpanel
port = 2082,2083,2086,2087
logpath = /usr/local/cpanel/logs/login_log
maxretry = 4
Note that cPanel also ships cPHulk, its own brute-force protection. Run one or the other for a given service to avoid double-banning — many admins use cPHulk for cPanel services and Fail2Ban for SSH and web apps.
Protecting WordPress Logins
WordPress failures don’t appear in a log by default. The cleanest approach is to install the WP Fail2Ban plugin, which writes auth events to syslog, then add a jail:
[wordpress]
enabled = true
filter = wordpress-hard
logpath = /var/log/auth.log
port = http,https
maxretry = 3
Alternatively, point a jail at your Apache/Nginx access log and match repeated POST /wp-login.php requests that return 200/401.
Managing & Monitoring Bans
| Command | What It Does |
|---|---|
fail2ban-client status | List all active jails |
fail2ban-client status sshd | Show banned IPs for a jail |
fail2ban-client set sshd unbanip 1.2.3.4 | Manually unban an IP |
fail2ban-regex /var/log/auth.log filter.d/sshd.conf | Test a filter against a log |
Conclusion
Fail2Ban turns noisy, relentless brute-force attacks into a non-event. Start with the sshd jail, whitelist your own IP so you never get locked out, then layer on jails for cPanel and WordPress. Test every filter with fail2ban-regex before trusting it, and within a day you’ll see attacker IPs piling up in the ban list instead of in your logs.
