Skip to content

fail2ban: SSH Jail Configuration

Securing SSH against brute-force attacks is one of the first steps in hardening any server. fail2ban scans logs, detects repeated failed login attempts, and blocks the source via iptables or nftables. This note covers the sshd jail — from installation to fine-tuning ban durations.

Installation and Basic Configuration

Install from the standard repository:

# Debian/Ubuntu
apt install fail2ban

# RHEL/CentOS
yum install fail2ban

Enable and start the service:

systemctl enable --now fail2ban
systemctl status fail2ban
Warning

Do not edit /etc/fail2ban/jail.conf directly — package updates will overwrite your changes. All local overrides go in jail.local.

Create a local overrides file:

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

Or, preferably, create a minimal jail.local with only the parameters you need — fail2ban stacks jail.local on top of jail.conf, so overriding specific keys is sufficient.

Filter for sshd

A ready-made filter ships with the package: /etc/fail2ban/filter.d/sshd.conf. It scans /var/log/auth.log (or /var/log/secure on RHEL) for patterns like Failed password for invalid user and Connection closed by authenticating user.

Verify the filter parses your logs correctly:

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

If the output shows a high match rate, the filter works. If not, check the logpath parameter in the jail and the logpath value inside the [Definition] section of the filter.

Tip

For additional protection against brute-force via ddos-style attacks, there is a separate filter sshd-ddos. It catches rapid repeated connections from a single IP. Enable it by adding mode = ddos to the jail parameters.

bantime and findtime Parameters

Three keys define the blocking logic:

ParameterDescriptionDefault
bantimeBan duration in seconds (negative = permanent)600
findtimeObservation window for counting failed attempts600
maxretryFailed attempts before ban5

A typical production configuration:

[sshd]
bantime  = 3600
findtime = 600
maxretry = 3

This means: three failed logins within ten minutes triggers a one-hour ban. For critical servers, set bantime = -1 (permanent ban) and unblock manually with fail2ban-client set sshd unbanip <IP>.

Note

bantime and findtime accept suffixes: d (days), h (hours), m (minutes), s (seconds). For example, bantime = 1d.

Activating the Jail

By default, the [sshd] section is commented out in jail.local. Enable it:

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime  = 3600
findtime = 600

On RHEL/CentOS, logpath is typically /var/log/secure. Verify the log path on your distribution.

Restart fail2ban and check the status:

systemctl restart fail2ban
fail2ban-client status
fail2ban-client status sshd

The output of fail2ban-client status sshd shows the current number of banned IPs and active filters.

Manual block and unblock:

fail2ban-client set sshd banip 203.0.113.50
fail2ban-client set sshd unbanip 203.0.113.50
Warning

fail2ban is not a WAF and not a replacement for key-based authentication. Use keys instead of passwords, restrict access with AllowUsers, and change the port where feasible. fail2ban complements these measures — it does not replace them.

Check fail2ban logs (/var/log/fail2ban.log) on first startup — they show whether the jail picked up the log file and whether filters are firing.