Przed Wami kolejny wpis z serii (4-6 wpisów) mającej zakończyć temat podstawowej konfiguracji serwera, a dotyczących bezpieczeństwa (w podstawowym ujęciu). Dziś w pewnym sensie kontynuacja wpisu dotyczącego firewalla UFW, choć tym razem to nie my będziemy decydować co i kiedy zablokować, a zrobi to za nas na aplikacja, na podstawie wcześniej zdefiniowanych reguł…

Fail2Ban, czyli banowanie za złe zachowanie

Podobnie jak wspomniany UFW, tak również Fail2Ban jest pewnego rodzaju nakładką na IPtables (gdzie tak naprawdę odbywa się blokada), ale w przeciwieństwie do UFW, gdzie sami definiujemy co i jak zablokować/odblokować, to Fail2Ban działa automatycznie, na podstawie reguł, które zdefiniujemy.

Program po prostu działa w tle, analizuje logi wybranych aplikacji, i na podstawie zdefiniowanych reguł szuka „złych zachować” (np. nieudana próba logowania, tzw. brute force) i jeśli natrafi na takie działania, to podejmuje akcje – blokuje takiego delikwenta/bota.

Zastanawiałem się (chwile, bo jednak nie jest to aż tak istotny problem) nad odpowiednikiem angielskiego „jail”, czyli tłumacząc dosłownie, będzie to „więzienie”.

I choć brzmi mi to średnio, to jednak dość dobrze oddaje (przynajmniej w jakimś stopniu) sens działania Fail2Ban, więc niestety musicie – tak jak i ja – w tym poradniku to zaakceptować… ;-)

Instalacja i podstawowa konfiguracja

Instalacja aplikacji w systemach Debian/Ubuntu jest prosta, wystarczy skorzystać z polecenia:

sudo apt-get install fail2ban

Po instalacji możemy przystąpić do podstawowej konfiguracji, czyli… nie będziemy edytować podstawowego pliku konfiguracyjnego:

/etc/fail2ban/fail2ban.conf

Wynika to z tego, że w większości przypadków domyślne ustawienia, które się tam znajdują, będą OK, a zamiast tego lepiej skoncentrować się na:

Wiezienie lokalne

Wprawdzie podstawmy plikiem, w którym moglibyśmy coś zmienić, jest plik::

/etc/fail2ban/jail.conf

To chyba nie znajdziecie miejsca, w którym ktokolwiek będzie polecał takie działanie – plik ten może zostać nadpisany nową wersją przy aktualizacji programu, a tym samym stracicie wszystkie Wasze ustawienia.

Lepszym rozwiązaniem jest skopiowanie tego pliku pod nową nazwą:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

I wszelkie podstawowe modyfikacje przeprowadzamy później w tym pliku:

sudo nano /etc/fail2ban/jail.local

Podstawowa konfiguracja

To, co od razu warto zmienić/ustawić, to:

[DEFAULT]

# Jeśli masz stały adres IP - możesz go tu wpisać, zamiast aaa.bbb.yyy.zzz
# W innym przypadku skasuj ten fragment
ignoreip = 127.0.0.1/8 aaa.bbb.yyy.zzz
# Domyślny czas blokady w sekundach (86400 = 24 godziny):
bantime = 86400
# Domyslna ilość nieudanych prób, np. logowania:
maxretry = 3
# Czas do resetu licznika nieudanych prób:
findtime = 3600

destemail = adres-email@do-powiadomień

Warto też spojrzeć na:

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
#banaction = iptables-multiport
banaction = iptables-allports

# email action. Since 0.8.1 upstream fail2ban uses sendmail
# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
#mta = sendmail
mta = mail

Oraz:

# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

# Choose default action. To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_mw)s

W powyższym zapisie mamy ustawione, że w przypadku blokady dostaniemy również wiadomość e-mail, o czym decyduje ten fragment:

action = %(action_mw)s

Konfigurujemy więżenia

Dalej (w tym samym pliku) definiujemy więzienia – część jest już wstępnie zdefiniowana, wystarczy je tylko aktywować i ew zmodyfikować parametry (jeśli zajdzie taka potrzeba).

Sam najczęściej korzystam z więzienia dla szturmujących SSH:

[ssh]

enabled = true
port = 22,ssh,sftp
filter = sshd
logpath = /var/log/auth.log
maxretry = 2

[ssh-ddos]

enabled = true
port = 22,ssh,sftp
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 3

Oraz – zależnie od webserwera – Apache2:

[apache]

enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 3

[apache-noscript]

enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache*/*error.log
maxretry = 6

[apache-overflows]

enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache*/*error.log
maxretry = 2

Lub – teraz częściej – Nginx:

[nginx-http-auth]

enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/*error.log

Te elementy musicie już dodać samodzielnie, nie są one standardowo dostępne:

[nginx-badbots]

enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/*access.log
maxretry = 2

[nginx-noproxy]

enabled = true
port = http,https
filter = nginx-noproxy
logpath = /var/log/nginx/*access.log
maxretry = 2

Pozostałych domyślnych reguł albo nie używam, albo korzystam z na tyle specyficznych reguł, że nie ma sensu ich tu podawać.

Jeśli modyfikowaliście ścieżkę plików z logami dla danej usługi, i jest ona inna, niz standardowa/domyślna, to pamiętajcie by odpowiednio ustawić parametr „logpath”, w którym znajduje się ścieżka do tych plików (w innym przypadku Fail2Ban nie zadziała dla tej usługi, gdyż nie będzie mógł znaleźć podejrzanych działań w pliku z logiem).

Fail2Bank i Nginx

Jeśli korzystacie z webserwera Nginx (albo dowolnej innej usługi, której nie było w standardzie, i sami ją definiujecie) i dodaliście powyższe reguły (poza „nginx-http-auth”), to musimy jeszcze utworzyć odpowiednie filtry, które będą „tłumaczyły” Fail2Ban jak czytać i czego szukać w danym pliku log.

W tym zadaniu można posiłkować się już zdefiniowanymi filtrami, które można albo wykorzystać bezpośrednio, lub wykorzystać jako wzór. Część przydatnych filtrów znajdziecie również na tej stronie.

Nowe (dodatkowe) filtry

Filtry znajdują się w katalogu:

/etc/fail2ban/filter.d

I tu będziemy tworzyć nowe, ew edytować istniejące.

Nazwa pliku z filtrem (+ rozszerzenie .conf) odpowiada nazwie zdefiniowanej w pliku „jail.local”, a konkretnie linijce „filter” dla danego więzienia/pułapki.

Nie będę też wnikał w szczegóły kolejnych plików z filtrami, tylko przedstawię je w takiej formie, jakiej najczęściej (ale nie zawsze) sam używam – wynika to z tego, że pliki te „chodzą ze mną” między różnymi serwerami od jakiegoś już czasu, czasem wymieniam się nimi (jak i samymi pomysłami na kolejną pułapkę/więzienie) ze znajomymi, i pewnie dojście do sedna, zajęłoby za dużo czasu.

Złe boty „pożyczymy” sobie z pliku przeznaczonego dla Apache:

sudo cp /etc/fail2ban/filter.d/apache-badbots.conf /etc/fail2ban/filter.d/nginx-badbots.conf

Próby zrobienia sobie z naszego serwera proxy wytniemy za pomocą filtra który stworzymy:

sudo nano /etc/fail2ban/filter.d/nginx-noproxy.conf

O treści:

[Definition]

failregex = ^<HOST> -.*GET http.*

ignoreregex =

Na koniec musimy jeszcze zrestartować usługę:

sudo /etc/init.d/fail2ban restart

Przetestuj działanie

Po konfiguracji i restarcie usługi możecie sprawdzić status usługi, w tym ilość i nazwy więzień/pułapek:

sudo fail2ban-client status

W odpowiedzi otrzymacie np. coś takiego:

Status
|- Number of jail: 5
`- Jail list: nginx-noproxy, nginx-badbots, nginx-http-auth, ssh-ddos, ssh

Możecie też sprawdzić status konkretnego więzienia/pułapki:

sudo fail2ban-client status nginx-noproxy

I w odpowiedzi dostaniecie np. coś takiego:

Status for the jail: nginx-noproxy
|- filter
| |- File list: /var/log/nginx/access.log
| |- Currently failed: 1
| `- Total failed: 65
`- action
|- Currently banned: 1
| `- IP list: aaa.bbb.yyy.zzz
`- Total banned: 6

Możecie też sprawdzić IPtables pod kątem blokad nałożonych przez Fail2Ban za pomocą polecenia:

sudo iptables -S | grep "fail2ban"

I przykładowa odpowiedź:

-N fail2ban-nginx-badbots
-N fail2ban-nginx-http-auth
-N fail2ban-nginx-noproxy
-N fail2ban-ssh
-N fail2ban-ssh-ddos
-A INPUT -p tcp -j fail2ban-nginx-badbots
-A INPUT -p tcp -j fail2ban-nginx-noproxy
-A INPUT -p tcp -j fail2ban-ssh-ddos
-A INPUT -p tcp -j fail2ban-nginx-http-auth
-A INPUT -p tcp -j fail2ban-ssh
-A fail2ban-nginx-badbots -j RETURN
-A fail2ban-nginx-http-auth -j RETURN
-A fail2ban-nginx-noproxy -s aaa.bbb.yyy.zzz/32 -j REJECT --reject-with icmp-port-unreachable
-A fail2ban-nginx-noproxy -j RETURN
-A fail2ban-ssh -j RETURN
-A fail2ban-ssh-ddos -j RETURN

Ja osobiście preferuje jednak tego typu polecenie:

sudo iptables -L fail2ban-ssh -v -n --line-numbers

W ramach odpowiedzi dostaniemy listę blokad (w tym przypadku dla SSH) z przypisanymi im numerami:

Chain fail2ban-ssh (1 references)
num   pkts bytes target     prot opt in     out   source              destination
1       11  2402 REJECT     all  --  *      *     aaa.bbb.ccc.ddd     0.0.0.0/0
2     24M  3112M RETURN     all  --  *      *     0.0.0.0/0           0.0.0.0/0

Dzięki temu możemy szybko dokonać odblokowania wybranej pozycji bez zbędnego komplikowania polecenia:

sudo iptables -D fail2ban-ssh 1

Gdzie 1 to numer reguły/blokady do skasowania.

Może się zdarzyć, że zamiast „fail2ban-*” będzie „f2b-*”. Wtedy należy lekko zmodyfikować powyższe komendy:

sudo iptables -L f2b-ssh -v -n --line-numbers
sudo iptables -D f2b-ssh 1
sudo iptables -L f2b-sshd -v -n --line-numbers
sudo iptables -D f2b-sshd 1

Możesz przeprowadzić testy też na sobie

Z racji tego, że w przeciwieństwie do kosmetyków działanie Fail2Ban może być ciężko sprawdzić na zwierzętach (czego i tak nie popieram, ale „one to ponoć lubią”) możemy takie testy przeprowadzić na sobie.

Pamiętajcie tylko, by na czas testów wykluczyć swój adres IP z wyjątków (jeśli dodaliście), oraz by ustawić czas blokady na jakiś relatywnie krótki czas – powiedzmy 60 sekund – by po takich testach i stałym IP nie skończyło się brakiem dostępu do serwera przez kilka(dziesiąt) godzin, zwłaszcza jeśli chodzi o SSH… ;-)

(!) Zgłoś błąd na stronie
Pomogłem? To może postawisz mi wirtualną kawę?
LUTy dla D-Cinelike (DJI Mini 3 Pro, DJI Avata, OSMO Pocket) od MiniFly
Wdrożenie Omnibusa w sklepie na WooCommerce
Jak (legalnie) latać dronem w Kategorii Otwartej
Patryk