This article may contain affiliate links — we earn a commission when you purchase through our links at no extra cost to you.
Fail2ban Guide 2026: Protect Your VPS from SSH Brute Force Attacks

VPS Security · Linux

Fail2ban Guide 2026: Protect Your VPS from SSH Brute Force Attacks

By CloudPicked Review Team · Updated October 2026

Table of Contents

  1. What is Fail2ban?
  2. How Fail2ban Works
  3. Installing on Ubuntu/Debian
  4. Configuring jail.local
  5. Protecting SSH
  6. Protecting Nginx, Apache & WordPress
  7. Essential Commands
  8. Advanced: Recidive Jail
  9. Fail2ban vs CrowdSec
  10. FAQ

Every VPS on the internet faces constant SSH brute-force attacks — bots scanning port 22 around the clock, trying thousands of username/password combinations. Fail2ban is the industry-standard tool that detects and automatically blocks these attacks by banning offending IP addresses at the firewall level.

What is Fail2ban?

Fail2ban is an open-source, Python-based daemon that monitors log files for suspicious patterns — such as repeated failed login attempts — and responds by temporarily blocking the offending IP address using the system firewall (iptables, nftables, ufw, or firewalld).

The current stable release is v1.1.x, requiring Python ≥ 3.5. It ships with ready-made filters for dozens of services including SSH, Nginx, Apache, Postfix, and more. Fail2ban is licensed under GPLv2 and is completely free.

Verified Facts (GitHub fail2ban/fail2ban, October 2026)

Fail2ban v1.1.x · Python ≥ 3.5 required · GPLv2 license · IPv6 support since v0.10 · Compatible with iptables / nftables / ufw / firewalld

How Fail2ban Works

Fail2ban operates in three stages:

  1. Log monitoring — Continuously reads log files such as /var/log/auth.log or /var/log/nginx/access.log
  2. Pattern matching — Uses regular expressions (filters) to detect suspicious lines, e.g., "Failed password" or "Invalid user"
  3. Action execution — When an IP exceeds maxretry failures within findtime seconds, Fail2ban bans it for bantime

Fail2ban creates dedicated firewall chains (e.g., f2b-sshd) that don't interfere with your existing firewall rules.

# Example: SSH brute force detected in /var/log/auth.log
Oct 30 01:23:45 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
Oct 30 01:23:47 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
Oct 30 01:23:49 server sshd[1234]: Failed password for root from 45.142.212.10 port 54321 ssh2
# → maxretry=3 reached within findtime → IP is banned

Installing Fail2ban on Ubuntu/Debian

# Update package list and install
sudo apt update
sudo apt install fail2ban -y

# Verify the service is running
sudo systemctl status fail2ban

# Enable auto-start on reboot
sudo systemctl enable fail2ban

Fail2ban starts immediately after installation with a default configuration protecting SSH. However, you should customize it further for your environment.

For CentOS/AlmaLinux/Rocky Linux

sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable --now fail2ban

Configuring jail.local

Important: Never modify /etc/fail2ban/jail.conf directly — it gets overwritten during updates. Instead, create jail.local which overrides jail.conf:

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

Essential [DEFAULT] settings

[DEFAULT]
# Ban duration — 1h = ban for 1 hour
bantime  = 1h

# Detection window — find maxretry failures within this time
findtime = 10m

# Number of failures before ban
maxretry = 5

# IPs that are never banned — ALWAYS add your own IP!
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP/32

# Log backend (auto-detects the best option)
backend = auto

Need a VPS to Run Fail2ban On?

We recommend VPS providers with full root access, Ubuntu/Debian support, and data centers in Southeast Asia.

DigitalOcean Droplets Ruk-Com Cloud VPS

Protecting SSH — The Most Critical Jail

Add the following to your jail.local:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3
bantime  = 2h
findtime = 5m

If you've changed your SSH port (e.g., to 2222), set port = 2222. After editing, reload:

sudo systemctl reload fail2ban

Protecting Nginx, Apache, and WordPress

Nginx

[nginx-http-auth]
enabled  = true
port     = http,https
filter   = nginx-http-auth
logpath  = /var/log/nginx/error.log
maxretry = 3

[nginx-botsearch]
enabled  = true
port     = http,https
filter   = nginx-botsearch
logpath  = /var/log/nginx/access.log
maxretry = 2

Apache

[apache-auth]
enabled  = true
port     = http,https
filter   = apache-auth
logpath  = /var/log/apache2/error.log
maxretry = 5

[apache-badbots]
enabled  = true
port     = http,https
filter   = apache-badbots
logpath  = /var/log/apache2/access.log
maxretry = 2

WordPress Login Protection

Create a custom filter file:

sudo nano /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^<HOST>.*POST.*(wp-login\.php|xmlrpc\.php).* 200
ignoreregex =

Add to jail.local:

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

Essential Fail2ban Commands

CommandDescription
sudo fail2ban-client statusList all active jails
sudo fail2ban-client status sshdShow sshd jail status + currently banned IPs
sudo fail2ban-client set sshd unbanip 1.2.3.4Unban a specific IP from sshd jail
sudo fail2ban-client set sshd banip 1.2.3.4Manually ban an IP
sudo fail2ban-client reloadReload config without restart
sudo tail -f /var/log/fail2ban.logWatch Fail2ban log in real time
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.confTest a filter against a real log file

Advanced: Recidive Jail for Repeat Offenders

The recidive jail adds an extra layer of protection: if an IP gets banned multiple times across different jails, recidive applies a much longer ban (1 week or permanent). This stops attackers who simply wait out the regular bantime and try again.

[recidive]
enabled  = true
filter   = recidive
logpath  = /var/log/fail2ban.log
action   = iptables-allports[name=recidive]
bantime  = 1w
findtime = 1d
maxretry = 5

Whitelisting Important IPs

# In [DEFAULT] section of jail.local
ignoreip = 127.0.0.1/8 ::1 203.0.113.10/32 10.0.0.0/8

Always whitelist your own IP address to prevent accidentally locking yourself out.

Fail2ban vs CrowdSec: Which Should You Use?

FeatureFail2banCrowdSec
CostFree (GPLv2)Free (MIT)
Threat intelligenceLocal log-based onlyCrowdsourced + shared blocklists
Setup complexitySimple, quickMore complex (API, bouncers)
False positivesOccasionalFewer (community-verified)
RAM usage~10-20 MBSlightly more
DocumentationExtensive (10+ years)Growing (2020+)
Best forSingle VPS, simplicityMulti-server, enterprise

Recommendation: For a single VPS or small business server, start with Fail2ban. It's simpler, better documented, and widely understood by sysadmins worldwide. Consider CrowdSec if you manage multiple servers and want to share threat intelligence between them.

Frequently Asked Questions

Q: Does Fail2ban work with UFW?

A: Yes. Set banaction = ufw in jail.local, or use action = %(action_)s which auto-detects the firewall backend. Fail2ban supports iptables, nftables, and ufw.

Q: How much RAM does Fail2ban use?

A: Typically 10-20 MB RAM, depending on the number of active jails. It works comfortably on VPS instances with as little as 512 MB RAM.

Q: Does Fail2ban persist bans after a restart?

A: By default in recent versions, Fail2ban uses a SQLite database (/var/lib/fail2ban/fail2ban.sqlite3) to persist bans across restarts. Older versions may lose the ban list on restart.

Q: What should I set maxretry to for SSH?

A: We recommend maxretry = 3 for SSH. A legitimate user rarely mistype their password more than 3 times. Always whitelist your own IP to avoid accidental lockouts.

Q: I accidentally banned my own IP — how do I fix it?

A: Use the VPS provider's emergency console (KVM/IPMI access) to log in, then run: sudo fail2ban-client set sshd unbanip YOUR_IP

Q: Does Fail2ban support IPv6?

A: Yes, since version 0.10, Fail2ban has full IPv6 support. Ensure your firewall backend (iptables with ip6tables or nftables) also supports IPv6.

Information in this article is based on the official fail2ban/fail2ban GitHub repository as of October 2026. Verify the latest version at fail2ban.org.