After setting up SSH key authentication, I used to think brute-force attacks weren't a concern anymore — if password auth is off, what does it matter?
Turns out it still matters. The constant connection attempts in the auth log generate noise, and some attacks are sophisticated enough to probe for other weaknesses. More practically, allowing endless failed login attempts from the same IP wastes server resources.
Fail2ban monitors the auth logs and bans IPs after repeated failures. Five failed attempts in 10 minutes? Banned for an hour. It works without any ongoing maintenance and dramatically reduces the noise in your logs.
This guide installs Fail2ban on Ubuntu 22.04, configures SSH protection, and extends it to protect web services like Nginx.
I run Fail2ban on every Tencent Cloud Lighthouse instance I manage. It takes 15 minutes to set up and dramatically reduces brute-force risk. Fail2ban works at the OS level, and Lighthouse adds a console-level firewall that operates independently at the infrastructure layer — two complementary systems that handle the same threat from different positions. The combination means even if Fail2ban has a gap (like a rule that doesn't cover a specific attack pattern), the Lighthouse console firewall provides a fallback.
- Key Takeaways
Failed SSH login attempt from 1.2.3.4
Failed SSH login attempt from 1.2.3.4
Failed SSH login attempt from 1.2.3.4 ← 3rd failure within 10 minutes
→ Fail2ban bans 1.2.3.4 for 1 hour (iptables DROP rule added)
→ All traffic from 1.2.3.4 is silently dropped
Fail2ban doesn't prevent every attack — a very slow, distributed brute-force can still get through. But it stops the vast majority of automated scanning bots that hammer servers with thousands of attempts per minute.
| Requirement | Notes |
|---|---|
| Cloud server | Tencent Cloud Lighthouse Ubuntu 22.04 |
| Root/sudo access | Required for iptables management |
sudo apt update
sudo apt install -y fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo systemctl status fail2ban
Fail2ban's configuration structure:
/etc/fail2ban/fail2ban.conf — global settings (don't edit directly)/etc/fail2ban/jail.conf — jail definitions (don't edit directly)/etc/fail2ban/jail.local — your custom overrides (this is what you edit)/etc/fail2ban/filter.d/ — log parsing patternsThe convention: create .local files that override .conf defaults. Your customizations survive package updates.
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Ban IPs for 1 hour
bantime = 3600
# Look for failures in the last 10 minutes
findtime = 600
# Ban after 5 failures
maxretry = 5
# Email notifications (configure in Part 5)
# destemail = your@email.com
# action = %(action_mwl)s
# Ignore local traffic and known safe IPs
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 86400 # Ban for 24 hours for SSH (stricter than default)
Apply the configuration:
sudo systemctl restart fail2ban
Verify the SSH jail is active:
sudo fail2ban-client status
# Shows: Jail list: sshd
sudo fail2ban-client status sshd
# Shows: Jail: sshd
# Currently failed: X
# Total failed: Y
# Banned IP list:
If you use HTTP Basic Auth on any Nginx endpoints:
# Add to /etc/fail2ban/jail.local
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
sudo nano /etc/fail2ban/filter.d/nginx-req-limit.conf
[Definition]
failregex = limiting requests, excess:.* by zone.*client: <HOST>
ignoreregex =
# In jail.local:
[nginx-req-limit]
enabled = true
port = http,https
filter = nginx-req-limit
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 7200
sudo nano /etc/fail2ban/filter.d/nginx-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*" 404
ignoreregex =
# In jail.local:
[nginx-404]
enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 30
findtime = 120
bantime = 3600
Restart after any config change:
sudo fail2ban-client reload
# All jails
sudo fail2ban-client status
# Specific jail
sudo fail2ban-client status sshd
# Show IPs banned by iptables (alternative view)
sudo iptables -L f2b-sshd -n --line-numbers
sudo fail2ban-client set sshd banip 1.2.3.4
sudo fail2ban-client set sshd unbanip 1.2.3.4
Useful if you accidentally get yourself banned.
sudo cat /var/log/fail2ban.log | grep "Ban"
sudo tail -f /var/log/fail2ban.log
sudo grep "Failed password" /var/log/auth.log | \
awk '{print $11}' | sort | uniq -c | sort -rn | head -20
Get an email when Fail2ban bans an IP:
sudo apt install -y mailutils
Update /etc/fail2ban/jail.local:
[DEFAULT]
destemail = your@email.com
sendername = Fail2Ban Alert
mta = sendmail
# action_mwl = ban + email with whois info + log lines
action = %(action_mwl)s
Test the email action:
sudo fail2ban-client set sshd banip 10.0.0.1
# Should trigger an email
sudo fail2ban-client set sshd unbanip 10.0.0.1
Whitelisting your IP prevents you from accidentally locking yourself out:
[DEFAULT]
# Add your home IP and any other trusted IPs
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP/32
sudo fail2ban-client reload
Verify your IP is in the ignore list:
sudo fail2ban-client get sshd ignoreip
For dynamic home IPs (that change): consider adding your IP to the whitelist each time it changes, or use a fixed IP service.
The most common Fail2ban issue: you forget your password or typo it several times and get banned from SSH.
Recovery options:
sudo fail2ban-client set sshd unbanip YOUR_IP
curl ifconfig.me
Prevention: whitelist your IP in ignoreip (Part 6) before you're in a situation where you need it.
sudo nano /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^<HOST> -.* "POST .*wp-login.php
ignoreregex =
# In jail.local:
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 3600
Any application that logs failed authentication to a file can be protected by writing a custom filter that matches the log pattern.
# Test your filter against a log file
sudo fail2ban-regex /var/log/myapp.log /etc/fail2ban/filter.d/myapp.conf
| Issue | Likely Cause | Fix |
|---|---|---|
| Connection refused | Service not running or wrong port | Check systemctl status SERVICE and verify firewall rules |
| Permission denied | Wrong file ownership or permissions | Check file ownership with ls -la and use chown/chmod to fix |
| 502 Bad Gateway | Backend service not running | Restart the backend service; check logs with journalctl -u SERVICE |
| SSL certificate error | Certificate expired or domain mismatch | Run sudo certbot renew and verify domain DNS points to server IP |
| Service not starting | Config error or missing dependency | Check logs with journalctl -u SERVICE -n 50 for specific error |
| Out of disk space | Logs or data accumulation | Run df -h to identify usage; clean logs or attach CBS storage |
| High memory usage | Too many processes or memory leak | Check with htop; consider upgrading instance plan if consistently high |
| Firewall blocking traffic | Port not open in UFW or Lighthouse console | Open port in Lighthouse console firewall AND sudo ufw allow PORT |
Does Fail2ban conflict with Lighthouse's console-level firewall?
No — they operate at different layers. Lighthouse's console firewall blocks at the network infrastructure level. Fail2ban operates at the OS level. Both provide independent protection layers.
How do I check if Fail2ban is working correctly?
Check the service status with sudo systemctl status fail2ban. Review logs for recent activity. Most security tools have a test or dry-run mode to verify configuration.
What should I do if Fail2ban blocks a legitimate user or IP?
Most security tools have a whitelist mechanism. Add trusted IPs to the whitelist/ignore list. For Fail2ban, use fail2ban-client set JAIL unbanip IP_ADDRESS.
How often should I review security logs?
For personal servers, a weekly review of auth logs and firewall logs is reasonable. For production or sensitive servers, set up log monitoring with alerts for suspicious patterns (unusually high fail rates, unusual hours).
Secure your server with Fail2ban:
👉 Tencent Cloud Lighthouse — Ubuntu VPS with console-level firewall backup
👉 View current pricing and promotions
👉 Explore all active deals and offers