fail2ban: block repeated failed logins
Install fail2ban, enable the sshd jail with sane ban times, whitelist your own address, read the ban list, unban someone, and add a jail for another service's log.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
fail2ban watches log files or the systemd journal for failed logins and adds a temporary firewall rule for any address that fails too often. It does not make a weak password strong, but it turns thousands of guesses per hour into a handful, keeps the logs readable and makes brute force against any service with a log unattractive.
Install
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
# Debian / Ubuntu
sudo apt install -y fail2ban
# RHEL / Rocky / Alma (from EPEL)
sudo dnf install -y epel-release
sudo dnf install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
On Debian 12 the service fails to start right after installation if rsyslog is not installed, because the default sshd jail looks for /var/log/auth.log, which does not exist on a journal-only system. The configuration below fixes that by reading the journal instead.
Configure: jail.local, never jail.conf
/etc/fail2ban/jail.conf is overwritten on updates. Put your settings in /etc/fail2ban/jail.local (or a file in jail.d/), which is read afterwards and overrides it.
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 203.0.113.10 198.51.100.0/24
bantime.increment = true
bantime.maxtime = 1w
[sshd]
enabled = true
backend = systemd
mode = aggressive
EOF
sudo fail2ban-client reload
sudo fail2ban-client status sshd
maxretryfailures withinfindtimelead to a ban ofbantime. Units:m,h,d,w.ignoreip: addresses that are never banned. Careful: put your own office, home or VPN address here before you start testing; a ban applies to you too, and from a banned address you cannot even log in to lift it.bantime.increment = true: an address that comes back after a ban is banned for longer each time, up tobantime.maxtime.backend = systemd: read the journal instead of a log file. Works everywhere systemd is used and avoids the Debian 12 problem above.mode = aggressivefor sshd also matches preauth disconnects and other noise that the default mode ignores.
See who is banned, and unban
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo fail2ban-client status # list of active jails
sudo fail2ban-client status sshd # counts and currently banned addresses
sudo fail2ban-client banned # every ban in every jail
sudo fail2ban-client set sshd unbanip 203.0.113.55
sudo fail2ban-client unban --all # lift every ban
sudo fail2ban-client set sshd banip 203.0.113.99 # ban by hand
sudo journalctl -u fail2ban -n 50 # what it did and why
The bans themselves are nftables or iptables rules in a chain named after the jail (f2b-sshd); sudo nft list ruleset | grep f2b shows them if you want to see the mechanism.
Protect another service
fail2ban ships filters for many programs in /etc/fail2ban/filter.d/ (nginx, Postfix, Dovecot, vsftpd and more). Enabling one is a section in jail.local that names the log file:
[nginx-http-auth]
enabled = true
logpath = /var/log/nginx/error.log
[nginx-botsearch]
enabled = true
logpath = /var/log/nginx/access.log
maxretry = 2
Before enabling a jail, confirm the filter actually matches your log lines:
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf
The output ends with how many lines matched. Zero matches means the jail will never ban anyone, usually because the log format differs; the filter files are small regular expressions you can adapt in a .local copy.
Does it replace other measures?
No. With SSH passwords disabled, fail2ban is mostly about log noise and load. Attackers with many addresses are barely slowed down. The order of importance is keys only, a firewall that exposes little, then fail2ban. For services behind a reverse proxy, make sure the real client address reaches the log (the X-Forwarded-For header and your proxy’s configuration), otherwise fail2ban bans the proxy itself.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0276 What is SSH? SSH is a secure way to open a command line on another computer over the network, with everything encrypted. Beginner · Explains an idea · Any system Article SSH 15 Oct 2026
- 0322 Fix: user is not in the sudoers file sudo refuses because your account is not allowed to use it. Add the user to the sudo group (Debian, Ubuntu) or wheel… Beginner · Fixes an error · Linux, macOS Article Server hardening · Users, sudo & hardening 15 Oct 2026
- 0345 SSH keys: create, copy and use them Generate an ed25519 key pair, install the public key on a server with ssh-copy-id, keep the private key protected with a passphrase… Beginner · Step by step · Linux, macOS, Windows Article Keys & config · SSH 15 Oct 2026
- 0346 The SSH config file: aliases, jump hosts and keys per server Reference for ~/.ssh/config: short names for servers, the right user, port and key per host, ProxyJump through a bastion, connection reuse and… Intermediate · Cheat sheet · Linux, macOS, Windows Article Keys & config · SSH 15 Oct 2026
- 0352 Harden a fresh Linux server in 30 minutes The baseline for any new Debian, Ubuntu or RHEL-family server: updates on, a non-root user with sudo, SSH keys only, a firewall… Beginner · Step by step · Linux Article Server hardening · Users, sudo & hardening 15 Oct 2026
- 0358 SSH server audit script: print risky sshd settings A read-only bash script that asks sshd for its effective configuration, compares the important settings with safe values, flags config.d files that… Intermediate · Cheat sheet · Linux Script Server hardening · SSH 15 Oct 2026
Repos in the wild
- fail2ban: ban hosts that fail to log in too often fail2ban/fail2ban The standard intrusion-prevention daemon on Linux servers: it watches logs or the journal for repeated failures and adds temporary firewall rules against the offending addresses. GitHub
- dev-sec ansible-collection-hardening: tested hardening roles for Linux, SSH and nginx dev-sec/ansible-collection-hardening An Ansible collection that applies a well-documented hardening baseline to Linux hosts, the SSH server and client, nginx and MySQL, with every setting adjustable through variables. GitHub
- Atomic Red Team: small tests that check whether your detections fire redcanaryco/atomic-red-team Atomic Red Team is a library of tiny, documented tests, each reproducing one attacker technique from MITRE ATT&CK, that defenders run in their own lab to confirm their monitoring notices it. GitHub
- Lynis: a security audit of a Linux or Unix host with hardening suggestions CISOfy/lynis Lynis is a shell script that inspects a Linux, BSD or macOS system you administer, tests hundreds of settings and services, and prints warnings and concrete hardening suggestions with a score. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +4,003 chars