Home/Engineer/Security Hardening/Blocking SSH brute-force att…
Security HardeningIntermediateUbuntuDebianCentOSRHELfail2bansshSecurity

Blocking SSH brute-force attacks with fail2ban — jail setup and monitoring

Automatically detect and block SSH brute-force attacks with fail2ban. Covers jail.local core parameters, recidive long-term bans, email alerts, Cloudflare and ipset integration, and day-to-day commands. See the separate guide for baseline S

Contents
  1. Scope of this guide
  2. Installation and jail.local
  3. Core parameters — bantime · findtime · maxretry
  4. Permanently banning repeat offenders — recidive jail
  5. Email notification integration
  6. Cloudflare and ipset integration — block at the edge
  7. Operations — status checks and manual ban/unban
  8. Monitoring login attempts

Scope of this guide

This article focuses on automatically blocking SSH brute-force attacks with fail2ban. Finish baseline setup first—switching to SSH key authentication and hardening sshd_config—using the Complete SSH Configuration and Access Control Guide.

Assumption: the SSH port has been changed to 2222 and only key authentication is allowed.


Installation and jail.local

The default jail.conf is overwritten on package updates, so always override in jail.local.

Bash
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
INI
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h # when
findtime = 10m # when failed
maxretry = 5 # when
ignoreip = 127.0.0.1/8 ::1 203.0.113.10 # IP
backend = systemd # journald when using

[sshd]
enabled  = true
port = 2222 # sshd_config when
maxretry = 3
bantime  = 1d
Bash
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd # jail check

Watch for port mismatch: If you changed the SSH port, set port under [sshd] to the same value so logs match. If they don't match, bans will not fire at all.


Core parameters — bantime · findtime · maxretry

ParameterMeaningRecommended
findtimeObservation window for counting failures10m
maxretryBan after this many failuresSSH 3
bantimeHow long a single ban lasts1d (escalate on repeats)

bantime = -1 makes a permanent ban, but a false positive can lock you out, so incremental bans via the recidive jail below are safer.


Permanently banning repeat offenders — recidive jail

IPs that start hammering again as soon as a short ban expires get a long-term ban. This works by watching fail2ban's own logs.

INI
# /etc/fail2ban/jail.local
[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s #
bantime  = 1w
findtime = 1d
maxretry = 5

Email notification integration

To get mail when a ban occurs, switch action to a version that includes email.

INI
[DEFAULT]
destemail = admin@example.com
sender    = fail2ban@example.com
mta       = sendmail
# + whois + to
action    = %(action_mwl)s

Cloudflare and ipset integration — block at the edge

Blocking at the front (Cloudflare) or in the kernel with ipset reduces load and makes bans faster.

INI
# Cloudflare API
[sshd]
action = cloudflare[cfuser="me@example.com", cftoken="API_TOKEN"]
INI
# or ipset + iptables ( IP O(1) )
[DEFAULT]
banaction = iptables-ipset-proto6-allports

Operations — status checks and manual ban/unban

Bash
# jail IP
sudo fail2ban-client status sshd

# IP /
sudo fail2ban-client set sshd banip 1.2.3.4
sudo fail2ban-client set sshd unbanip 1.2.3.4

# jail (settings after)
sudo fail2ban-client reload

Monitoring login attempts

Verify that ban rules are working and which IPs are knocking.

Bash
# failed when
journalctl -u ssh | grep "Failed password" | tail -20

# IP failed
journalctl -u ssh | grep "Failed password" \
  | grep -oE "from [0-9.]+" | awk '{print $2}' | sort | uniq -c | sort -rn | head

# fail2ban
sudo zgrep "Ban " /var/log/fail2ban.log* | tail -20

Avoid banning yourself: Always put your work static IP in ignoreip. If you omit it and ban yourself, you can only recover via console (web KVM). For baseline SSH hardening, see the Complete SSH Configuration and Access Control Guide.

#fail2ban#ssh#Security#brute-force
Editorial note

AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us

Topic-related official docs (auto-linked · not per-claim sources)Linux man pages ↗OWASP documentation ↗

Questions & answers

Ask a question about this guide. We'll review and reply.