Fail2ban: ochrana SSH a nginx proti útokům hrubou silou
Nainstalujte fail2ban na Ubuntu, nastavte jail.local pro SSH a nginx, zvolte rozumné bantime a naučte se odblokovat IP a testovat filtry.
Fail2ban sleduje logy, hledá opakované neúspěšné pokusy (špatné heslo, skenování URL) a útočící IP adresy dočasně zablokuje ve firewallu. Není to náhrada za SSH klíče, ale výborně snižuje zátěž a šum v logech.
Instalace
sudo apt update
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
Nikdy neupravujte jail.conf
Výchozí nastavení je v /etc/fail2ban/jail.conf, ale ten se při aktualizaci balíčku přepíše. Vlastní konfigurace patří do /etc/fail2ban/jail.local nebo do souborů v /etc/fail2ban/jail.d/.
Vytvořte /etc/fail2ban/jail.local:
[DEFAULT]
# Vaše IP, které se nikdy nezablokují
ignoreip = 127.0.0.1/8 ::1 198.51.100.25
bantime = 1h
findtime = 10m
maxretry = 5
# Opakovaní útočníci dostanou delší ban
bantime.increment = true
bantime.maxtime = 1w
# Na Ubuntu čteme logy ze systemd journalu
backend = systemd
banaction = ufw
[sshd]
enabled = true
port = ssh
maxretry = 3
Co znamenají klíčové hodnoty:
| Volba | Význam |
|---|---|
findtime |
okno, ve kterém se počítají pokusy |
maxretry |
počet selhání v okně, po kterém přijde ban |
bantime |
délka blokace (-1 = trvale) |
bantime.increment |
každý další ban stejné IP je delší |
banaction = ufw |
blokace přes UFW místo přímých iptables pravidel |
Pokud UFW nepoužíváte, banaction vynechejte – výchozí akce pracuje přímo s iptables/nftables.
Pokud jste SSH přesunuli na jiný port, uveďte ho: port = 2222.
Načtěte změny:
sudo fail2ban-client reload
sudo fail2ban-client status
Ochrana nginx
Fail2ban obsahuje hotové filtry pro nginx. Užitečné jsou hlavně:
nginx-http-auth– neúspěšné přihlášení přes HTTP Basic Auth,nginx-botsearch– požadavky na neexistující admin cesty typické pro skenery,nginx-limit-req– klienti, které omezil modullimit_req.
Tyto filtry čtou soubory s logy, proto pro ně přepněte backend:
[nginx-http-auth]
enabled = true
backend = auto
logpath = /var/log/nginx/error.log
[nginx-botsearch]
enabled = true
backend = auto
logpath = /var/log/nginx/access.log
maxretry = 10
Vlastní filtr: skenování wp-login a .env
Pokud na serveru nemáte WordPress, každý požadavek na /wp-login.php je skoro jistě bot. Vytvořte /etc/fail2ban/filter.d/nginx-scan.conf:
[Definition]
failregex = ^<HOST> -.*"(GET|POST) /(wp-login\.php|xmlrpc\.php|\.env|\.git/config)
ignoreregex =
A jail:
[nginx-scan]
enabled = true
backend = auto
filter = nginx-scan
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 1d
Testování filtru
Než filtr zapnete, ověřte, že regulární výraz opravdu něco najde:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-scan.conf
Ve výstupu hledejte řádek Failregex: N total. Pokud je 0, výraz neodpovídá formátu vašeho logu.
Pro SSH s journalem:
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
Správa banů
Stav konkrétního jailu:
sudo fail2ban-client status sshd
Ručně zablokovat nebo odblokovat IP:
sudo fail2ban-client set sshd banip 192.0.2.66
sudo fail2ban-client set sshd unbanip 198.51.100.25
Pokud jste zablokovali sami sebe, přihlaste se přes webovou konzoli poskytovatele a použijte unbanip. Pak svou IP přidejte do ignoreip.
Fail2ban za Cloudflare
Pokud web běží za Cloudflare nebo jinou proxy, v access logu uvidíte IP proxy, ne návštěvníka. Fail2ban by pak blokoval Cloudflare. Nejdřív v nginx nastavte obnovu skutečné IP (modul real_ip). Ani pak ale blokace na vašem firewallu nepomůže, protože spojení k vám stále přichází z adres Cloudflare – pro webové jaily za proxy je lepší blokovat přímo na straně Cloudflare (WAF pravidla). Jail pro SSH tím dotčen není.
Kontrola logů
sudo journalctl -u fail2ban -n 50
sudo tail -f /var/log/fail2ban.log
V logu uvidíte řádky Ban a Unban s IP a názvem jailu – dobrý způsob, jak ověřit, že ochrana funguje.
Shrnutí
Fail2ban je levná a účinná vrstva navíc. Základ je jail sshd s bantime.increment, rozumný ignoreip a pro web pár filtrů na skenery. Každý nový filtr nejdřív otestujte přes fail2ban-regex.