VPS Series · Post 4 of 5

Securing Your VPS with Fail2Ban

Every public VPS gets hit with SSH brute-force attempts within minutes of going live. Fail2Ban monitors your logs and automatically bans IPs after repeated failures. We'll set up jails for SSH, WordPress login, and Nginx bots.

1 Install Fail2Ban

bash
apt install fail2ban -y
systemctl enable fail2ban
systemctl start fail2ban

# Check status
fail2ban-client status

2 Create jail.local

Never edit jail.conf directly — create a local override that survives updates:

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

In the [DEFAULT] section of jail.local, set global defaults:

ini
bantime  = 1h
findtime  = 10m
maxretry = 5

3 Enable SSH Jail

Find the existing [sshd] section in jail.local and add enabled = true:

ini
[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 24h

Do not add a duplicate [sshd] block. The error "section 'sshd' already exists" means you added a second one — edit the existing one instead.

4 Create WordPress Filter

bash
nano /etc/fail2ban/filter.d/wordpress.conf
ini
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =

Then add the WordPress jail at the bottom of jail.local:

ini
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 10m
bantime = 1h
port = http,https

5 Enable Nginx Jails

Find these existing sections in jail.local and add enabled = true:

ini
[nginx-http-auth]
enabled = true
port    = http,https
logpath = %(nginx_error_log)s

[nginx-botsearch]
enabled = true
port    = http,https
logpath = %(nginx_error_log)s

6 Restart & Verify

bash
systemctl restart fail2ban
fail2ban-client status

You should see all 4 jails listed: sshd, wordpress, nginx-http-auth, nginx-botsearch.

7 Useful Commands

bash
# Check banned IPs per jail
fail2ban-client status sshd
fail2ban-client status wordpress

# Unban an IP
fail2ban-client set sshd unbanip 1.2.3.4

# Watch live log
tail -f /var/log/fail2ban.log