Every public-facing Linux server is subjected to continuous automated dictionary and brute-force attacks against its SSH daemon and web services. While changing your default SSH port helps reduce noise, installing Fail2Ban provides active, automated intrusion prevention.
Fail2Ban monitors log files (such as /var/log/auth.log or systemd journal) for repeated failed login attempts and dynamically updates your firewall (UFW / iptables / nftables) to drop packets from the attacker's IP address.
1. Installing Fail2Ban
Install Fail2Ban from standard distribution repositories:
sudo apt update
sudo apt install fail2ban -y
Verify that the Fail2Ban service is running and enabled on boot:
sudo systemctl status fail2ban
2. Creating a Custom jail.local Configuration
Fail2Ban includes a default configuration file located at /etc/fail2ban/jail.conf. You should never edit jail.conf directly, as future package updates will overwrite your modifications. Instead, copy it to jail.local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Essential Global Settings in [DEFAULT]
Scroll to the [DEFAULT] section to adjust parameters:
[DEFAULT]
# Whitelist your own static IP or VPN subnet (never ban yourself)
ignoreip = 127.0.0.1/8 ::1 203.0.113.45
# Time (in seconds or human format) an IP is banned
bantime = 1h
# Window of time in which failed attempts are counted
findtime = 10m
# Maximum failed attempts before triggering a ban
maxretry = 5
3. Configuring the SSH Jail
Scroll down to the [sshd] section in /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
maxretry = 3
bantime = 24h
[!TIP] If you changed your SSH port (for example to
2222), updateport = 2222inside the[sshd]section so Fail2Ban monitors the correct socket.
Save and close the file (Ctrl + O, Enter, Ctrl + X), then restart Fail2Ban:
sudo systemctl restart fail2ban
4. Monitoring and Managing Banned IPs
Fail2Ban provides the fail2ban-client CLI utility to interact with running jails.
Check Overall Fail2Ban Status
sudo fail2ban-client status
Output:
Status
|- Number of jail: 1
`- Jail list: sshd
Inspect Banned IPs in the SSH Jail
sudo fail2ban-client status sshd
Output:
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 48
| `- Journal matches: _SYSTEMD_UNIT=sshd.service
`- Actions
|- Currently banned: 3
|- Total banned: 12
`- Banned IP list: 198.51.100.22 203.0.113.99 192.0.2.77
Manually Unbanning an IP Address
If you or a colleague accidentally triggers a ban:
sudo fail2ban-client set sshd unbanip 203.0.113.99
Manually Banning an IP Address
sudo fail2ban-client set sshd banip 198.51.100.55
Common Mistakes
- Editing
jail.confdirectly: Package upgrades overwritejail.conf. Always createjail.local. - Forgetting to set
ignoreip: Lockout risk! Always whitelist your local static IP address or office VPN. - Mismatched SSH Port: Failing to change
portin[sshd]after changing the SSH listening port insshd_config.
Troubleshooting
- Fail2Ban not banning attackers: Verify
backend = systemdis set if running modern Ubuntu 22.04/24.04 where/var/log/auth.logis replaced by systemd journal. - Fail2Ban fails to start: Run
sudo fail2ban-client -dto check for syntax errors in your.localfiles.
Best Practices
- Enable progressive banning (
bantime.increment = true) injail.localso repeat offenders receive exponential ban durations (e.g., 1 day -> 1 week -> 1 month). - Pair Fail2Ban with SSH key-only authentication for airtight perimeter defense.
Frequently Asked Questions
Does Fail2Ban use UFW or iptables?
By default, Fail2Ban integrates directly with iptables or nftables via reject/drop chains, working harmoniously alongside UFW.
Can Fail2Ban protect Nginx and WordPress?
Yes! Fail2Ban includes built-in filters for nginx-http-auth, nginx-botsearch, nginx-limit-req, and WordPress XML-RPC brute forcing.
Conclusion
Installing Fail2Ban takes less than ten minutes and eliminates thousands of automated attacks against your RivinCloud VPS. Harden your server with Fail2Ban today!