Zajrzyj kiedyś do logów SSH na świeżo postawionym serwerze. Tak z ciekawości.

Setki prób logowania na root, admin, test, ubuntu, z adresów z drugiego końca świata, dzień i noc, bez przerwy. Boty nie śpią. Firewall w stylu UFW czy iptables niewiele tu pomoże, bo działa zero-jedynkowo: port jest otwarty albo nie, a co się na nim dzieje, zupełnie go nie interesuje.

Fail2ban patrzy właśnie na to. Czyta logi, a gdy zauważy, że jakiś adres uparcie zgaduje hasło, po prostu go banuje. Na jakiś czas, żeby nie było za dobrze.

Na Mikrusie#

W NOOBS-ie mamy gotowy skrypt, który instaluje fail2ban i od razu konfiguruje go pod SSH.

Jeśli nie masz jeszcze NOOBS-a:

curl -s https://noobs.mikr.us | bash

Skrypt przyjmuje port SSH jako parametr. Na Mikrusie to 22 - tak, nawet jeśli łączysz się z zewnątrz na 10000+ID, bo serwer SSH w kontenerze i tak nasłuchuje na 22:

sudo /opt/noobs/scripts/chce_fail2ban.sh -p 22

Domyślnie 5 nieudanych prób w ciągu 3 minut oznacza 30 minut bana. Za łagodnie? Za surowo? Wszystko da się przestawić flagami:

sudo /opt/noobs/scripts/chce_fail2ban.sh -p 22 -b 1h -f 5m -m 3

-b 1h to długość bana, -f 5m okno czasowe, w którym liczone są wpadki, a -m 3 - liczba prób, po której zapada wyrok.

Na koniec skrypt pokazuje status jaila SSH, więc od razu widać, czy wszystko gra.

Na dowolnym serwerze (Ubuntu/Debian)#

To samo, tylko ręcznie. Zadziała na Mikrusie i na każdym innym VPS-ie z Ubuntu lub Debianem.

sudo apt update
sudo apt install fail2ban

Teraz ważne: pliku /etc/fail2ban/jail.conf nie ruszasz. Może zostać nadpisany przy aktualizacji pakietu i Twoje zmiany pójdą w niebyt. Własne ustawienia wpisujesz do /etc/fail2ban/jail.local, który ma pierwszeństwo:

sudo nano /etc/fail2ban/jail.local

Podstawowa konfiguracja pod SSH:

[DEFAULT]
bantime  = 30m
findtime = 10m
maxretry = 5

[sshd]
enabled = true

bantime to długość bana. findtime - okno czasowe, w którym zliczane są nieudane próby. maxretry to z kolei liczba takich prób w tym oknie, po której adres ląduje za kratkami.

Włączasz usługę:

sudo systemctl enable --now fail2ban

I sprawdzasz, czy jail SSH wystartował:

sudo fail2ban-client status sshd

Na nowszych Ubuntu i Debianie fail2ban czyta logi SSH prosto z journald (w statusie zobaczysz to w polu Journal matches), więc ścieżki do pliku z logami nigdzie nie podajesz.

Dodanie jaila dla Apache#

Na tym samym serwerze kręci się Apache? Dopisz do /etc/fail2ban/jail.local:

[apache-auth]
enabled = true
port    = http,https

Ten jail śledzi logi błędów Apache i wyłapuje nieudane logowania, na przykład do katalogu zabezpieczonego .htpasswd.

Dodanie jaila dla Nginx#

Z Nginx jest niemal identycznie:

[nginx-http-auth]
enabled = true
port    = http,https

Po dopisaniu któregokolwiek z nich restartujesz fail2ban:

sudo systemctl restart fail2ban

Tu muszę jednak ostudzić entuzjazm. apache-auth i nginx-http-auth pilnują wyłącznie logowania przez HTTP Basic Auth, czyli tego szarego okienka z przeglądarki, które wyskakuje przy katalogach chronionych hasłem albo przy phpMyAdminie schowanym za dodatkową bramką. Jeśli Twoja aplikacja ma własny formularz logowania - WordPress, jakiś panel w PHP - te jaile nie złapią absolutnie nic. Potrzebny jest wtedy osobny filtr, skrojony pod logi konkretnej aplikacji, ale to materiał na zupełnie inny wpis.

Sprawdzanie zablokowanych adresów#

sudo fail2ban-client status sshd

Aktualnie zbanowanych znajdziesz w sekcji Banned IP list. Lista potrafi być długa.

Ręczne odblokowanie adresu#

Przyda się, kiedy zbanujesz sam siebie, bo na przykład kilka razy z rzędu pomyliłeś hasło. Zdarza się najlepszym:

sudo fail2ban-client set sshd unbanip 81.15.20.33

W miejsce 81.15.20.33 wstaw adres do odblokowania.

Najczęstsze błędy#

Zmiany wpisane do jail.conf zamiast do jail.local. Przy aktualizacji fail2ban mogą zostać nadpisane, trzeba na to uważać. Zawsze pracuj na jail.local.

Ban na samego siebie. Wystarczy kilka razy źle wpisać hasło albo mieć pecha i łączyć się z tego samego adresu, z którego akurat ktoś próbuje się włamać. Na Mikrusie z opresji wyciągnie Cię MARIAN z panelu: odpalisz nim polecenie naprawcze (np. fail2ban-client unban --all), nawet gdy SSH już Cię nie wpuszcza.

Jail działa, ale nic nie banuje. Zajrzyj do sudo fail2ban-client status sshd, pole Currently failed. Ciągle zero? Możliwe, że SSH przyjmuje tylko klucze (PasswordAuthentication no) i fail2ban najzwyczajniej nie ma czego łapać. To akurat dobra wiadomość.

Od tej pory jesteś chroniony przed włamaniami brute-force, ale to nie usprawiedliwia naprawdę słabego i prostego hasła.