Firewall network security protection

Install Fail2ban on VPS to Block Brute Force Attacks

June 2026 · 6 min read

Fail2ban is a daemon that monitors log files and automatically bans IP addresses that attempt to log in with invalid credentials more than a specified number of times. You no longer need to monitor your server manually every day. It's ideal for any VPS that exposes SSH or web services to the internet.


Install Fail2ban

apt update
apt install fail2ban -y

Create a Local Config (Do Not Edit .conf Files Directly)

Fail2ban uses an override system — .local files override values from .conf files. When you update the package, your settings won't be lost:

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

Configure Default Settings in [DEFAULT]

[DEFAULT]
bantime  = 1h        # Ban for 1 hour
findtime = 10m       # Count attempts within 10 minutes
maxretry = 5         # Ban after 5 failed attempts
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP

Add your home or office IP to ignoreip to prevent locking yourself out.

Enable SSH Jail

[sshd]
enabled  = true
port     = 2222      # If you've changed the SSH port
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 3

Enable Nginx Jail (If Using Nginx)

[nginx-http-auth]
enabled = true

[nginx-limit-req]
enabled = true
logpath = /var/log/nginx/error.log

Start and Enable Fail2ban

systemctl enable fail2ban
systemctl start fail2ban

View Status and Banned IPs

# View all active jails
fail2ban-client status

# View IPs banned in SSH jail
fail2ban-client status sshd

# View log
tail -f /var/log/fail2ban.log

Unban an IP (If You Lock Yourself Out)

fail2ban-client set sshd unbanip 1.2.3.4

Test That Banning Works

# Try SSH login with wrong password multiple times from another machine
# Then check the log
grep "Ban" /var/log/fail2ban.log
bantime = -1: Set to -1 for permanent IP bans on highly suspicious activity. You can create a separate jail for repeat offenders.

Jail for WordPress Login

If you run WordPress, set up a jail to protect against brute force attacks on wp-login.php:

# /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^ .* "POST /wp-login.php
ignoreregex =

# /etc/fail2ban/jail.local — add this section
[wordpress]
enabled  = true
filter   = wordpress
logpath  = /var/log/nginx/access.log   # or apache2/access.log
maxretry = 5
bantime  = 1h
findtime = 10m
systemctl reload fail2ban
fail2ban-client status wordpress

Jail for Nginx 4xx Errors

Protect against scanners that probe random URLs:

[nginx-badbots]
enabled  = true
filter   = nginx-badbots
logpath  = /var/log/nginx/access.log
maxretry = 2
bantime  = 24h

[nginx-noscript]
enabled  = true
filter   = nginx-noscript
logpath  = /var/log/nginx/access.log
maxretry = 6

Recidive Jail: Increase Ban Time for Repeat Offenders

[recidive]
enabled  = true
filter   = recidive
logpath  = /var/log/fail2ban.log
action   = iptables-allports[name=recidive]
bantime  = 1w      # Ban for 1 week
findtime = 1d      # If banned 5 times within 1 day
maxretry = 5

Verify Fail2ban is Working Correctly

Confirm that the service is running and jails are actually monitoring logs before you trust that your server is protected:

# 1. Is the service running?
systemctl status fail2ban

# 2. View status of all enabled jails
fail2ban-client status

# 3. View detailed status of the sshd jail (number of banned IPs and log path)
fail2ban-client status sshd

# 4. Test filter regex against real logs
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 5. View iptables rules created by Fail2ban
iptables -L -n | grep -i f2b
Tip: fail2ban-regex will show the number of "matched lines" — if you get 0 even though there are failed logins in the log, the filter regex doesn't match the log format on your system. You need to adjust the logpath or filter for your Linux distribution.

Common Issues & Troubleshooting

Fail2ban fails to start: "ERROR NOK: ('Failed to start',)"

# View detailed error messages
journalctl -u fail2ban -n 50 --no-pager

# Usually caused by syntax error in jail.local
fail2ban-client -t   # Test config before starting

Your IP is banned and you can't SSH back in

Prevention: Always add your home or office IP to ignoreip in the [DEFAULT] section.

If it already happened, you must use your provider's console (KVM console) to access the server:

fail2ban-client set sshd unbanip YOUR.IP.HERE

# Or restart Fail2ban (clears all bans temporarily)
systemctl restart fail2ban

Fail2ban is not banning IPs even though login attempts are failing

# Verify that the log path is correct
fail2ban-client get sshd logpath

# Check if filter regex matches real logs
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# View jail status
fail2ban-client status sshd

iptables rules disappear after reboot

Fail2ban adds temporary iptables rules. If Fail2ban doesn't start before network rules load, they'll be lost. Verify:

systemctl enable fail2ban   # Start automatically on boot
systemctl status fail2ban

Frequently Asked Questions

Can Fail2ban and UFW work together?

Yes. Fail2ban adds iptables rules directly, not through UFW, so they don't conflict. UFW manages basic rules (open/close ports), while Fail2ban handles dynamic bans based on behavior. Both work well together.

How long should I set the ban time?

1 hour is sufficient for typical bots that rotate IPs frequently. For targeted attacks from the same IP, use a recidive jail to increase bantime each time the IP is banned again. Avoid permanent bans (-1) unless you have a comprehensive ignoreip list.

Does Fail2ban consume much CPU or RAM?

Very little. It typically uses 20–30 MB of RAM and near 0% CPU except during bursts of many log entries. It's safe to run on a 1 GB RAM VPS.


Summary

Fail2ban is easy to install and works automatically without manual oversight. It's the first layer of protection every VPS should have, alongside proper SSH hardening and a well-configured firewall. Always remember to add your own IP to ignoreip first.