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:
Enable and start the service:
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:
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:
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.
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:
| Parameter | Description | Default |
|---|---|---|
bantime | Ban duration in seconds (negative = permanent) | 600 |
findtime | Observation window for counting failed attempts | 600 |
maxretry | Failed attempts before ban | 5 |
A typical production configuration:
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>.
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:
On RHEL/CentOS, logpath is typically /var/log/secure. Verify the log path on your distribution.
Restart fail2ban and check the status:
The output of fail2ban-client status sshd shows the current number of banned IPs and active filters.
Manual block and unblock:
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.