Twój serwer jest bezpieczny. Poradnik, jak trwale blokować ataki

fail2ban Permanant ban

Trwała czarna lista IP z Fail2ban, UFW i Ipset

Wstęp: Poza tymczasową ochroną

W cyfrowym świecie, gdzie ataki na serwery są na porządku dziennym, sama reakcja nie wystarczy. Choć narzędzia takie jak Fail2ban stanowią podstawową linię obrony, ich tymczasowe blokady pozostawiają lukę – uporczywi atakujący, po upływie czasu bana, mogą wrócić i próbować ponownie. Ten artykuł stanowi szczegółowy przewodnik po budowie w pełni zautomatyzowanego, dwuwarstwowego systemu, który zamienia efemeryczne bany w trwałe, globalne blokady. Połączenie Fail2ban, UFW oraz potężnego narzędzia Ipset tworzy mechanizm, który trwale chroni serwer przed znanymi recydywistami.

Warstwa pierwsza: Reakcja z Fail2ban

Na początku każdego ataku stoi Fail2ban. Ten daemon monitoruje pliki logów (np. sshd.log, apache.log) w poszukiwaniu wzorców świadczących o próbach włamania – na przykład wielu nieudanych prób logowania. Gdy wykryje taką aktywność, natychmiastowo blokuje adres IP atakującego, dodając go do reguł firewalla na zdefiniowany czas (np. 10 minut, 30 dni). Jest to skuteczna, ale krótkotrwała reakcja.

Warstwa druga: Trwałość z UFW i Ipset

Aby ban stał się trwały, potrzebujemy silniejszej, scentralizowanej metody zarządzania adresami IP. W tym miejscu wkraczają UFW i Ipset.

Czym jest Ipset?Ipset to rozszerzenie do jądra Linuksa, które pozwala na zarządzanie zbiorami (setami) adresów IP, sieci, czy portów. Jest to znacznie bardziej wydajne rozwiązanie niż dodawanie tysięcy pojedynczych reguł do firewalla. Zamiast tego, firewall może odwołać się do całego zestawu za pomocą jednej reguły.

Instalacja i konfiguracja IpsetPierwszym krokiem jest instalacja Ipset w systemie. Używamy do tego standardowych menedżerów pakietów:sudo apt updatesudo apt install ipsetNastępnie tworzymy dwa zestawy: blacklist dla adresów IPv4 i blacklist_v6 dla IPv6.

sudo ipset create blacklist hash:ip hashsize 4096
sudo ipset create blacklist_v6 hash:net family inet6 hashsize 4096

Parametr hashsize określa maksymalną liczbę wpisów, co jest kluczowe dla wydajności.

Integracja Ipset z Firewallem UFWAby UFW zaczął korzystać z naszych zestawów, musimy dodać do jego reguł odpowiednie polecenia. Edytujemy pliki konfiguracyjne UFW, dodając reguły blokujące ruch, który pochodzi z adresów zawartych w naszych zestawach Ipset. Dla IPv4 edytujemy

sudo nano /etc/ufw/before.rules:

Zaraz po:

*filter
:ufw-before-input - [0:0]

dodajemy:

# =======================================================
# Reguły dla trwałej czarnej listy (ipset)
# Blokuj każdy przychodzący ruch od adresów IP z zestawu 'blacklist' (IPv4)
-A ufw-before-input -m set --match-set blacklist src -j DROP
# =======================================================

Dla IPv6 edytujemy

sudo nano /etc/ufw/before6.rules

Zaraz po

*filter
:ufw6-before-input - [0:0]

dodajemy:

# =======================================================
# Reguły dla trwałej czarnej listy (ipset) - IPv6
# Blokuj każdy przychodzący ruch od adresów IP z zestawu 'blacklist_v6'
-A ufw6-before-input -m set --match-set blacklist_v6 src -j DROP
# =======================================================

Po dodaniu reguł, przeładowujemy UFW, aby weszły w życie:

sudo ufw reload

Skrypt do automatycznej aktualizacji czarnej listy

Sednem systemu jest skrypt, który działa jako pomost między Fail2ban a Ipset. Jego zadaniem jest zbieranie zbanowanych adresów, unikalizowanie ich i synchronizowanie z zestawami Ipset.

sudo nano /usr/local/bin/update-blacklist.sh

Poniżej przedstawiono zawartość skryptu. Działa on w kilku krokach:

  1. Tworzy tymczasową, unikalną listę adresów IP z logów Fail2ban oraz istniejącej czarnej listy.
  2. Tworzy tymczasowe zestawy Ipset.
  3. Czyta adresy z unikalnej listy i dodaje je do odpowiednich zestawów tymczasowych (rozróżniając IPv4 i IPv6).
  4. Atomowo zamienia stare zestawy Ipset na nowe, tymczasowe, minimalizując ryzyko przerw w ochronie.
  5. Niszczy stare, tymczasowe zestawy.
  6. Zwraca podsumowanie liczby zablokowanych adresów.
#!/bin/bash
BLACKLIST_FILE="/etc/fail2ban/blacklist.local"
IPSET_NAME_V4="blacklist"
IPSET_NAME_V6="blacklist_v6"
touch "$BLACKLIST_FILE"
(grep 'Ban' /var/log/fail2ban.log | awk '{print $(NF)}' && cat "$BLACKLIST_FILE") | sort -u > "$BLACKLIST_FILE.tmp"
mv "$BLACKLIST_FILE.tmp" "$BLACKLIST_FILE"

sudo ipset create "${IPSET_NAME_V4}_tmp" hash:ip hashsize 4096 --exist
sudo ipset create "${IPSET_NAME_V6}_tmp" hash:net family inet6 hashsize 4096 --exist

while IFS= read -r ip; do
  if [[ "$ip" == *":"* ]]; then
    sudo ipset add "${IPSET_NAME_V6}_tmp" "$ip"
  else
    sudo ipset add "${IPSET_NAME_V4}_tmp" "$ip"
  fi
done < "$BLACKLIST_FILE"

sudo ipset swap "${IPSET_NAME_V4}_tmp" "$IPSET_NAME_V4"
sudo ipset swap "${IPSET_NAME_V6}_tmp" "$IPSET_NAME_V6"

sudo ipset destroy "${IPSET_NAME_V4}_tmp"
sudo ipset destroy "${IPSET_NAME_V6}_tmp"

COUNT_V4=$(sudo ipset list "$IPSET_NAME_V4" | wc -l)
COUNT_V6=$(sudo ipset list "$IPSET_NAME_V6" | wc -l)
let COUNT_V4=$COUNT_V4-7
let COUNT_V6=$COUNT_V6-7
[ $COUNT_V4 -lt 0 ] && COUNT_V4=0
[ $COUNT_V6 -lt 0 ] && COUNT_V6=0

echo "Czarna lista i ipset zaktualizowane. Zablokowane IPv4: $COUNT_V4, Zablokowane IPv6: $COUNT_V6"
exit 0

Po utworzeniu skryptu, należy nadać mu uprawnienia do wykonania:

sudo chmod +x /usr/local/bin/update-blacklist.sh

Automatyzacja i trwałość po restarcie

Aby skrypt działał bez ingerencji, używamy harmonogramu cron. Otwieramy edytor crontab dla użytkownika root i dodajemy regułę, która uruchomi skrypt co godzinę:

sudo crontab -e
0 * * * * /usr/local/bin/update-blacklist.sh

lub raz dziennie o 6 rano:

0 6 * * * /usr/local/bin/update-blacklist.sh

Ostatni, ale kluczowy krok, to zapewnienie, że zestawy Ipset przetrwają restart. Zestawy te są domyślnie przechowywane w pamięci RAM. Tworzymy więc usługę systemd, która zapisze ich stan przed zamknięciem serwera i wczyta go ponownie przy starcie.

sudo nano /etc/systemd/system/ipset-persistent.service
[Unit]
Description=Zapisuje i wczytuje zestawy ipset przy starcie/zamknięciu systemu
Before=network-pre.target
ConditionFileNotEmpty=/etc/ipset.rules

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c "/sbin/ipset create blacklist hash:ip --exist; /sbin/ipset create blacklist_v6 hash:net family inet6 --exist; /sbin/ipset flush blacklist; /sbin/ipset flush blacklist_v6; /sbin/ipset restore -f <(grep -v ' create' /etc/ipset.rules)"
ExecStop=/sbin/ipset save -f /etc/ipset.rules

[Install]
WantedBy=multi-user.target

Na koniec włączamy i uruchamiamy usługę:

sudo systemctl daemon-reload
sudo systemctl enable --now ipset-persistent.service

Jak to działa w praktyce?

Cały system to zautomatyzowany łańcuch zdarzeń, który działa w tle, chroniąc serwer przed atakami. Oto, jak wygląda przepływ informacji i działań:

  1. Reakcja na atak (Fail2ban):
    • Ktoś próbuje się włamać na serwer (np. wielokrotnie podając błędne hasło przez SSH).
    • Fail2ban, monitorując logi systemowe (/var/log/fail2ban.log), wykrywa ten wzorzec.
    • Natychmiast dodaje adres IP atakującego do tymczasowej reguły firewalla, blokując mu dostęp na określony czas.
  2. Trwałe banowanie (Skrypt i cron):
    • Co godzinę (zgodnie z ustawieniem w cron), system uruchamia skrypt update-blacklist.sh.
    • Skrypt czyta logi Fail2ban, znajduje wszystkie adresy, które zostały zbanowane (linijki zawierające „Ban”), a następnie porównuje je z istniejącą, lokalną czarną listą (/etc/fail2ban/blacklist.local).
    • Tworzy unikalną listę wszystkich zbanowanych adresów.
    • Tworzy tymczasowe zestawy ipset (blacklist_tmp i blacklist_v6_tmp) i dodaje do nich wszystkie adresy z unikalnej listy.
    • Wykonuje operację ipset swap, która atomowo zamienia stare, aktywne zestawy na nowe, zaktualizowane.
    • UFW, dzięki zdefiniowanym wcześniej regułom, natychmiast zaczyna blokować nowe adresy, które pojawiły się w zaktualizowanych zestawach ipset.
  3. Trwałość po restarcie (Usługa systemd):
    • Działanie Ipset jest ulotne – zestawy istnieją tylko w pamięci. Usługa ipset-persistent.service rozwiązuje ten problem.
    • Przed wyłączeniem/restartem serwera: systemd uruchamia polecenie ExecStop=/sbin/ipset save -f /etc/ipset.rules. Zapisuje ono aktualny stan wszystkich zestawów ipset do pliku na dysku.
    • Po włączeniu/restarcie serwera: systemd uruchamia polecenie ExecStart=/sbin/ipset restore.... Wczytuje ono z pliku /etc/ipset.rules wszystkie zablokowane adresy i automatycznie odtwarza zestawy ipset w pamięci.
    • Dzięki temu, nawet jeśli serwer zostanie zrestartowany, czarna lista IP pozostaje nienaruszona, a ochrona jest aktywna od pierwszych chwil po uruchomieniu systemu.

Podsumowanie i weryfikacja

Zbudowany system to w pełni zautomatyzowana, wielowarstwowa ochrona. Atakujący są tymczasowo banowani przez Fail2ban, a ich adresy są automatycznie dodawane do trwałej czarnej listy, która jest natychmiastowo blokowana przez UFW i Ipset. Usługa systemd zapewnia, że czarna lista przetrwa restarty serwera, chroniąc przed recydywistami na stałe. Aby zweryfikować działanie, można użyć poniższych komend:

  • sudo ufw status verbose
  • sudo ipset list blacklist oraz sudo ipset list blacklist_v6
  • sudo systemctl status ipset-persistent.service

Jak Stworzyć Niezawodną Białą Listę (Whitelist) Adresów IP w UFW i Ipset

Wprowadzenie: Dlaczego Biała Lista Jest Kluczowa?

Podczas konfigurowania zaawansowanych reguł firewalla, zwłaszcza tych, które automatycznie blokują adresy IP (jak w systemach z Fail2ban), istnieje ryzyko przypadkowego zablokowania samego siebie lub kluczowych usług. Biała lista (whitelist) to mechanizm, który działa jak przepustka VIP dla Twojego firewalla – adresy IP umieszczone na tej liście zawsze będą miały dostęp, niezależnie od innych, bardziej restrykcyjnych reguł blokujących.

Ten poradnik pokaże Ci, jak krok po kroku stworzyć solidną i trwałą białą listę, używając UFW (Uncomplicated Firewall) oraz ipset. Jako przykładu użyjemy adresu IP 111.222.333.444, który chcemy dodać jako zaufany.

Krok 1: Stworzenie Dedykowanego Zestawu ipset dla Białej Listy

Pierwszym krokiem jest utworzenie osobnego „kontenera” na nasze zaufane adresy IP. Użycie ipset jest znacznie wydajniejsze niż dodawanie wielu pojedynczych reguł do iptables.

Otwórz terminal i wpisz następujące polecenie:

sudo ipset create whitelist hash:ip

Co zrobiliśmy?

  • ipset create: Polecenie tworzące nowy zestaw.
  • whitelist: Nazwa naszego zestawu. Jest krótka i jednoznaczna.
  • hash:ip: Typ zestawu. hash:ip jest zoptymalizowany do przechowywania i bardzo szybkiego wyszukiwania pojedynczych adresów IPv4.

Krok 2: Dodanie Zaufanego Adresu IP

Teraz, gdy mamy już gotowy kontener, dodajmy do niego nasz przykładowy, zaufany adres IP.

sudo ipset add whitelist 111.222.333.444

Możesz powtórzyć to polecenie dla każdego adresu, który chcesz dodać do białej listy. Aby sprawdzić zawartość listy, użyj polecenia:

sudo ipset list whitelist

Krok 3: Modyfikacja Firewalla – Nadanie Priorytetu Białej Liście

To jest najważniejszy krok. Musimy zmodyfikować reguły UFW tak, aby połączenia z adresów na białej liście były akceptowane natychmiast, zanim firewall zacznie przetwarzać jakiekolwiek reguły blokujące (w tym te z czarnej listy ipset czy Fail2ban).

Otwórz plik konfiguracyjny before.rules:Jest to plik, w którym znajdują się reguły przetwarzane przed głównymi regułami UFW.

sudo nano /etc/ufw/before.rules

Dodaj regułę ACCEPT na samej górze: Przejdź na początek pliku i znajdź sekcję *filter. Zaraz pod linią

:ufw-before-input - [0:0]

, dodaj nasz nowy fragment. Umieszczenie go na samej górze gwarantuje, że zostanie przetworzony jako pierwszy.

*filter
:ufw-before-input - [0:0]
# =======================================================
# Reguła dla białej listy (ipset) - ZAWSZE MA PIERWSZEŃSTWO
# Akceptuj każdy ruch od adresów IP z zestawu 'whitelist'
-A ufw-before-input -m set --match-set whitelist src -j ACCEPT
# =======================================================

-A ufw-before-input: Dodajemy regułę do łańcucha ufw-before-input.

-m set --match-set whitelist src: Warunek: „jeśli źródłowy (src) adres IP pasuje do zestawu whitelist„.

-j ACCEPT: Akcja: „natychmiast zaakceptuj (ACCEPT) pakiet i przestań przetwarzać dalsze reguły dla tego pakietu”.

Zapisz plik i przeładuj UFW:

sudo ufw reload
Od tego momentu każde połączenie z adresu 111.222.333.444 będzie natychmiast akceptowane.

Krok 4: Zapewnienie Trwałości Białej Listy

Zestawy ipset są przechowywane w pamięci i znikają po restarcie serwera. Aby nasza biała lista była trwała, musimy upewnić się, że jest ona automatycznie wczytywana przy każdym starcie systemu. Wykorzystamy do tego naszą wcześniej stworzoną usługę

ipset-persistent.service.

Zaktualizuj usługę systemd: Musimy ją „nauczyć” o istnieniu nowego zestawu whitelist.

sudo nano /etc/systemd/system/ipset-persistent.service

Znajdź linię ExecStart i dodaj do niej polecenia create i flush dla whitelist. Jeśli masz już inne zestawy, po prostu dodaj whitelist na początku.

# Przykład zaktualizowanej linii
ExecStart=/bin/bash -c "/sbin/ipset create whitelist hash:ip --exist; /sbin/ipset create blacklist hash:ip --exist; /sbin/ipset create blacklist_v6 hash:net family inet6 --exist; /sbin/ipset create blacklist_nets hash:net --exist; /sbin/ipset flush whitelist; /sbin/ipset flush blacklist; /sbin/ipset flush blacklist_v6; /sbin/ipset flush blacklist_nets; /sbin/ipset restore -f <(grep -v '^create' /etc/ipset.rules)"


Najprościej jest zastąpić całą linię ExecStart jej kompletną wersją, uwzględniającą wszystkie Twoje zestawy.

Przeładuj konfigurację systemd:

sudo systemctl daemon-reload

Zapisz aktualny stan wszystkich zestawów do pliku: To polecenie nadpisze stary plik /etc/ipset.rules nową wersją, która zawiera już informacje o Twojej białej liście.

sudo ipset save > /etc/ipset.rules

Zrestartuj usługę, aby upewnić się, że działa z nową konfiguracją:

sudo systemctl restart ipset-persistent.service

Podsumowanie

Gratulacje! Stworzyłeś solidny i niezawodny mechanizm białej listy. Dzięki niemu możesz bezpiecznie zarządzać swoim serwerem, mając pewność, że zaufane adresy IP, takie jak 111.222.333.444, nigdy nie zostaną przypadkowo zablokowane. Pamiętaj, aby dodawać do tej listy tylko w pełni zaufane adresy, takie jak Twój domowy lub biurowy adres IP.

Jak efektywnie blokować adresy IP i podsieci na serwerze Linux

Blokowanie pojedynczych adresów IP jest łatwe, ale co, jeśli atakujący używają wielu adresów z tej samej sieci? Ręczne banowanie każdego z nich jest nieefektywne i czasochłonne.

W tym artykule dowiesz się, jak wykorzystać narzędzia ipset i iptables, aby skutecznie blokować całe podsieci, automatyzując ten proces i oszczędzając cenny czas.

Dlaczego blokowanie całych podsieci jest lepsze?

Wiele ataków, zwłaszcza tych typu „brute-force”, jest przeprowadzanych z wielu adresów IP należących do tego samego operatora lub z tej samej puli adresów (podsieci). Blokowanie tylko jednego z nich jest jak łatanie małej dziury w dużej zaporze — reszta ruchu wciąż może się przedostać.

Zamiast tego, możesz zablokować całą podsieć, na przykład 45.148.10.0/24. Taki zapis oznacza, że blokujesz aż 256 adresów jednocześnie, co jest znacznie skuteczniejsze.

Skrypt do automatycznego blokowania podsieci

Aby zautomatyzować proces, możesz użyć poniższego skryptu bash. Skrypt ten jest interaktywny — prosi Cię o podanie podsieci do zablokowania, a następnie dodaje ją do listy ipset oraz zapisuje w pliku, dzięki czemu będzie trwale zablokowana.

Przeanalizujmy skrypt krok po kroku:

#!/bin/bash

# Nazwa listy ipset, do której będą dodawane podsieci
BLACKLIST_NAME="blacklist_nets"

# Plik, do którego będą dopisywane zablokowane podsieci
BLACKLIST_FILE="/etc/fail2ban/blacklistnet.local"

# 1. Tworzy plik z czarną listą, jeśli jeszcze nie istnieje
touch "$BLACKLIST_FILE"

# 2. Sprawdza, czy lista ipset już istnieje. Jeśli nie, tworzy ją.
# Użycie "hash:net" pozwala na przechowywanie podsieci, co jest kluczowe.
ipset list $BLACKLIST_NAME >/dev/null 2>&1
if [ $? -ne 0 ]; then
    sudo ipset create $BLACKLIST_NAME hash:net maxelem 65536
fi

# 3. W pętli prosi użytkownika o podanie podsieci do zablokowania.
# Pętla kończy się, gdy użytkownik wpisze "koniec".
while true; do
    read -p "Podaj adres podsieci do zablokowania (np. 192.168.1.0/24) lub wpisz 'koniec': " subnet
    
    if [ "$subnet" == "koniec" ]; then
        break
    elif [[ "$subnet" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9]{1,2}$ ]]; then
        # Sprawdza, czy wprowadzony format jest poprawny
        
        # Sprawdza, czy podsieć nie jest już w pliku, aby uniknąć duplikatów
        if ! grep -q "^$subnet$" "$BLACKLIST_FILE"; then
            echo "$subnet" | sudo tee -a "$BLACKLIST_FILE" > /dev/null
        fi
        
        # Dodaje podsieć do listy ipset
        sudo ipset add $BLACKLIST_NAME $subnet
    else
        echo "Błąd: Nieprawidłowy format. Podaj adres w formacie 'X.X.X.X/Y'."
    fi
done

# 4. Dodaje regułę w iptables, która blokuje cały ruch z adresów na liście ipset.
# Upewnia się, że reguła jest dodawana tylko raz.
if ! sudo iptables -C INPUT -m set --match-set $BLACKLIST_NAME src -j DROP >/dev/null 2>&1; then
    sudo iptables -A INPUT -m set --match-set $BLACKLIST_NAME src -j DROP
fi

# 5. Zapisuje reguły iptables, aby przetrwały restart serwera.
# Ten fragment sprawdza, z jakiego narzędzia korzysta system
if command -v netfilter-persistent &> /dev/null; then
    sudo netfilter-persistent save
elif command -v service &> /dev/null && service iptables status >/dev/null 2>&1; then
    sudo service iptables save
fi

echo "Skrypt zakończył działanie. Lista '$BLACKLIST_NAME' została zaktualizowana, a reguły iptables są aktywne."

Jak używać skryptu

  1. Zapisz skrypt: Zapisz powyższy kod w pliku, np. block_nets.sh
  2. Nadaj uprawnienia: Upewnij się, że plik ma uprawnienia do wykonania: chmod +x block_nets.sh
  3. Uruchom skrypt: Wykonaj skrypt z uprawnieniami roota: sudo ./block_nets.sh
  4. Podawaj podsieci: Skrypt poprosi Cię o podanie adresów podsieci. Po prostu wpisuj je w formacie X.X.X.X/Y i zatwierdzaj Enterem. Po zakończeniu wpisz koniec.

Zapewnienie trwałości po restarcie serwera

Zestawy ipset są domyślnie przechowywane w pamięci RAM i znikają po ponownym uruchomieniu serwera. Aby zablokowane adresy pozostały aktywne, musisz użyć usługi systemd, która wczyta je przy starcie systemu.

Jeśli masz już taką usługę (np. ipset-persistent.service), musisz ją zaktualizować, aby uwzględniała nową listę blacklist_nets.

Edytuj plik usługi: Otwórz plik konfiguracyjny swojej usługi:

sudo nano /etc/systemd/system/ipset-persistent.service

Zaktualizuj linię ExecStart: Znajdź linię ExecStart i dodaj do niej polecenia create i flush dla zestawu blacklist_nets.Przykładowa, zaktualizowana linia ExecStart powinna wyglądać następująco:

ExecStart=/bin/bash -c "/sbin/ipset create whitelist hash:ip --exist; /sbin/ipset create blacklist hash:ip --exist; /sbin/ipset create blacklist_v6 hash:net family inet6 --exist; /sbin/ipset create blacklist_nets hash:net --exist; /sbin/ipset flush whitelist; /sbin/ipset flush blacklist; /sbin/ipset flush blacklist_v6; /sbin/ipset flush blacklist_nets; /sbin/ipset restore -f <(grep -v ' create' /etc/ipset.rules)"

Przeładuj konfigurację systemd:

sudo systemctl daemon-reload

Zapisz aktualny stan wszystkich zestawów do pliku: To polecenie nadpisze stary plik /etc/ipset.rules nową wersją, która zawiera już informacje o wszystkich Twoich listach, w tym blacklist_nets.

sudo ipset save > /etc/ipset.rules

Zrestartuj usługę:

sudo systemctl restart ipset-persistent.service

Dzięki tej metodzie możesz w prosty i wydajny sposób zarządzać bezpieczeństwem swojego serwera, skutecznie blokując całe podsieci, które wykazują podejrzaną aktywność, i mieć pewność, że te reguły pozostaną aktywne po każdym restarcie.

Komentarze

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *