Fail2ban instaluje się jako pierwszy i zwykle na tym się kończy: pakiet jest, usługa działa, sshd wygląda na zabezpieczony. Pół roku później okazuje się, że więzienie czyta plik, którego w tym systemie nie ma, a wszystko pozostałe — poczta, panel, formularz logowania witryny — nigdy nie było chronione.
Zobaczmy, co naprawdę warto włączyć na zwykłym VPS-ie z witryną, jakie liczby tam wpisać i jak upewnić się, że więzienie działa, a nie tylko figuruje w konfiguracji.
Najpierw sprawdźmy, czy sshd w ogóle coś łapie
Jedno polecenie:
sudo fail2ban-client status sshd
W wyniku są wiersze Currently failed, Total failed i Total banned. Jeśli Total failed wynosi zero na serwerze stojącym w internecie co najmniej dobę — więzienie nie działa. Trzeba to zestawić z rzeczywistością:
sudo lastb | wc -l
Tysiące nieudanych prób w lastb przy zerach w Fail2ban oznaczają dokładnie jedno: filtr patrzy nie tam, gdzie trzeba.
Najczęstsza przyczyna to Debian 12. Nie instaluje już rsysloga domyślnie, plik /var/log/auth.log po prostu nie istnieje, a dostarczone więzienie sshd jest ustawione na czytanie tego pliku. Komunikatu o błędzie przy tym nie ma: usługa startuje, status się wyświetla, liczniki zostają na zerze. Leczy się to przełączeniem na dziennik systemd:
[sshd]
enabled = true
backend = systemd
Druga możliwość to przywrócić rsyslog jako pakiet, jeśli tekstowy auth.log jest potrzebny innym narzędziom. Ubuntu 24.04 zachowuje się tak samo.
Gdzie zapisywać ustawienia
Pliku /etc/fail2ban/jail.conf nie ruszamy: jest nadpisywany przy aktualizacji pakietu, a każda zmiana w nim kiedyś zniknie po cichu. Własne ustawienia trafiają do /etc/fail2ban/jail.local; ten plik czytany jest jako ostatni i ma pierwszeństwo nad wspólnym.
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.25
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
ignoreip z własnym adresem to nie luksus, lecz zabezpieczenie: zablokować samego siebie literówką jest łatwiej, niż się wydaje. Jeśli nie ma stałego adresu, warto mieć zapasowe wejście poza SSH — konsolę albo VNC u hostingodawcy.
Więzienie, które zmienia obraz: recidive
Zwykłe więzienie ma krótką pamięć: pięć prób w dziesięć minut, godzina blokady i po godzinie wszystko od nowa. Bot świetnie z tym żyje i wróci jutro oraz pojutrze. recidive zamyka dokładnie tę lukę: czyta nie dziennik systemu, lecz własny dziennik Fail2ban — czyli blokuje tych, których Fail2ban już blokował.
[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 5
Czyta się to tak: „zablokowany pięć razy w ciągu doby — znika na tydzień”. Więzienie potrzebuje pliku /var/log/fail2ban.log; jeśli logowanie samego Fail2ban przeniesiono do sysloga, recidive również będzie wymagać backend = systemd.
Praktyczny efekt tego jednego więzienia jest zwykle wyraźniejszy niż strojenie wszystkich pozostałych: stali bywalcy odpadają, a w dziennikach zostaje samo świeże tło.
Co jeszcze włączyć, jeśli na serwerze stoi witryna
Według malejącej przydatności:
nginx-http-authalboapache-auth— łamanie uwierzytelniania podstawowego. Potrzebne, jeśli panel administracyjny lub środowisko testowe chroni hasło serwera WWW;nginx-botsearch— skanowanie znanych ścieżek:/wp-login.php,/phpmyadmin,/.env. To nie włamanie, lecz rozpoznanie — i właśnie ono poprzedza całą resztę;nginx-limit-req— działa tylko wtedy, gdy w samym Nginksie zdefiniowanolimit_req_zone; bez tego więzienie jest włączone i bezużyteczne;postfix-saslidovecot— konieczne, jeśli poczta jest własna. Zgadywanie haseł do skrzynek trwa bez przerwy i zwykle nikt tego nie ogląda.
[nginx-botsearch]
enabled = true
logpath = /var/log/nginx/access.log
Osobna sprawa to formularz logowania samej witryny. Aplikacja nie ma własnego dziennika nieudanych logowań, a w access.log nieudana próba wygląda jak zwykły POST z kodem 200 albo 302 — żaden uniwersalny filtr nie odróżni jej od udanej. Są dwie drogi: zmusić aplikację do zapisywania niepowodzeń w syslogu (większość systemów zarządzania treścią ma do tego wtyczkę) albo ograniczyć częstotliwość żądań do strony logowania. To drugie jest ogranicznikiem, a nie detektorem, i lepiej wiedzieć to z góry.
Liczby
bantime = 10m to ustawienie domyślne, przez które Fail2ban uchodzi często za bezużyteczny: w dziesięć minut bot zdąży wrócić. Godzina przy pierwszej blokadzie plus recidive na tydzień działa znacznie lepiej niż blokady wieczne, które z czasem zamieniają się w kilometrową listę reguł.
maxretry = 3 dla SSH to pewny sposób, by zablokować samego siebie. Pięć prób w dziesięć minut odcina łamanie haseł równie dobrze.
Powolne zgadywanie — jedna próba na pięć minut — nigdy nie zmieści się w oknie findtime. To nie powód, by rozciągać okno do doby: pojawią się fałszywe trafienia na własnych współpracownikach. Przeciwko powolnemu zgadywaniu działa nie próg, lecz wyłączone logowanie hasłem.
Upewnijmy się, że blokada dociera do pakietów
Fail2ban jedynie wywołuje zewnętrzne polecenie. Jeśli banaction nie odpowiada temu, co rzeczywiście filtruje ruch, w dzienniku pojawią się rześkie wiersze Ban 198.51.100.7, a pakiety będą przychodzić dalej. Debian 12 domyślnie używa nftables, przy włączonym UFW właściwe jest banaction = ufw. Sprawdzenie:
sudo nft list ruleset | grep -c f2b
sudo iptables -S | grep f2b
Przynajmniej jedno z poleceń powinno pokazać reguły. A sam filtr można sprawdzić, nie czekając na atak:
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
Na dole wyniku widać, ile wierszy pasowało. Zero oznacza, że filtr i dziennik się nie spotykają, i dalsze konfigurowanie nie ma sensu.
Czego Fail2ban nie robi
Nie chroni przed rozproszonym łamaniem haseł: tysiąc adresów po jednej próbie nie osiągnie progu przy żadnych ustawieniach. Nie usuwa przyczyny — zablokowany adres nie poprawia słabego hasła. I nic nie wie o reputacji: adres, który wczoraj atakował cudze serwery, jest dla niego czysty, dopóki nie zabierze się za nasz. Stąd praktyczne połączenie: klucze zamiast haseł, Fail2ban jako ogranicznik szumu i wspólna lista blokad (CrowdSec) jako wiedza z cudzego doświadczenia.
Osobnym kłopotem jest to, że na to wszystko trzeba czasem spojrzeć. Nikt tygodniami nie wpisuje fail2ban-client status dla każdego więzienia osobno, a wzrost liczby blokad zauważa się wtedy, gdy już coś się zepsuło. Na stronach demonstracyjnych poniżej te same dane mieszczą się na jednej stronie: lista więzień, kto jest zablokowany w tej chwili i skąd przychodzą próby.