Kompletny przewodnik po wdrażaniu Netfilter i Suricata w systemie Linux

Ostatnia aktualizacja: 1 marca 2026
  • NFQUEUE umożliwia programowi Netfilter delegowanie decyzji dotyczących filtrowania i znakowania do procesów w przestrzeni użytkownika, umożliwiając korzystanie z dynamicznych zapór IP i routerów.
  • Suricata udostępnia wieloprocesowy silnik IDS/IPS z obsługą NFQUEUE, AF_PACKET i reguł zgodnych z Snort i nowymi zagrożeniami.
  • Integracja NFQUEUE z Suricata, bazami danych, Memcached lub Pfsense umożliwia tworzenie zaawansowanych rozwiązań bezpieczeństwa i routingu przy użyciu bezpłatnego oprogramowania.
  • Wydajność zależy w dużej mierze od projektu wątków i logiki przestrzeni użytkownika, dlatego kluczowe znaczenie ma optymalizacja i ostrożny wybór ruchu, który ma być kontrolowany.

Implementacja Netfilter i Suricata

Jeśli pracujesz z sieciami w systemie GNU/Linux ( najlepsza dystrybucja Linuksa pod względem bezpieczeństwa i prywatności ) i interesuje Cię wyjście poza typową statyczną zaporę sieciową, prawdopodobnie zastanawiasz się, jak połączyć Netfilter, NFQUEUE i Suricata, aby zbudować naprawdę elastyczny system IDS/IPS bez wydawania fortuny na zastrzeżony sprzęt. Właśnie ten obszar omówimy w tym artykule, łącząc elementy niskiego poziomu (jądro, kolejki, C) z narzędziami wysokiego poziomu (Suricata, reguły, MySQL, Memcached, pfSense).

Idea jest bardzo mocna: wykorzystać fakt, że jądro (zobacz, jak zoptymalizować jądro Linuksa ) może kolejkować pakiety w przestrzeni użytkownika i pozwolić programowi niestandardowemu decydować, co z nimi zrobić. Można to wykorzystać do filtrowania ruchu (zaawansowane zapory sieciowe, IPS), dynamicznego routingu lub integracji logiki biznesowej (bazy danych, pamięci podręczne, wykrywanie ataków na aplikacje webowe, VoIP itp.). A jeśli dodamy Suricatę jako wieloprocesowy silnik IDS/IPS, otrzymamy bardzo solidną kombinację dla środowisk od laboratoriów po centra danych o dużym natężeniu ruchu.

NFQUEUE i Netfilter: podniesienie poziomu zapory do przestrzeni użytkownika

W typowym systemie GNU/Linux reguły Netfilter/iptables (lub nftables) są zazwyczaj używane jako statyczne zasady, które są w całości przechowywane w przestrzeni jądra . Frontendy i urządzenia (w tym wiele rozwiązań opartych na Netfilter lub filtrze pakietów BSD) przechowują konfigurację w plikach tekstowych, XML lub SQLite, a w przypadku jakichkolwiek zmian generują i ponownie ładują reguły. Jest to elastyczne, ale logika pozostaje swego rodzaju migawką zapory z drobnymi, dynamicznymi modyfikacjami (limity połączeń na sekundę, śledzenie połączeń, dopasowanie do kraju, warstwa 7, jeśli dostępna, itp.).

Propozycja NFQUEUE to prawdziwy przełom: zamiast, aby jądro zawsze podejmowało ostateczną decyzję, możemy delegować tę decyzję do procesu użytkownika . Jądro kolejkuje pakiet w numerowanej kolejce, a aplikacja korzystająca z biblioteki libnetfilter_queue pobiera go, analizuje i zwraca werdykt: akceptuje, odrzuca, a nawet oznacza do routingu zgodnego z polityką. To tak, jakby na zaporze sieciowej znajdował się programowalny „sędzia” napisany w C, Pythonie lub Perlu.

Piękno tego rozwiązania polega na tym, że nasz program może dosłownie robić wszystko, co chcemy: odpytywać /dev/urandom, bazę danych, usługę sieciową, rozproszoną pamięć podręczną lub zaawansowany algorytm, zanim odpowie na żądanie jądra. Z punktu widzenia architektury, zapora przestaje być prostym zestawem statycznych reguł, a staje się potokiem, w którym Netfilter, kolejki i aplikacje użytkownika pasują do siebie jak elementy układanki.

NFQUEUE składa się z dwóch części: celu NFQUEUE w iptables , który wysyła pakiety do określonej kolejki, oraz biblioteki użytkownika libnetfilter_queue , która umożliwia odczyt tych pakietów i wydanie werdyktu. Nie jest to prosty sniffer, taki jak tcpdump: tutaj mamy możliwość bezpośredniego decydowania o ścieżce, jaką podąża pakiet.

zaawansowany monitor systemu dla systemu Linux
Podobne artykuły:
Zaawansowany monitor systemu Linux: kompletny przewodnik

Podstawowa konfiguracja iptables z NFQUEUE

Z punktu widzenia iptables korzystanie z NFQUEUE jest dość proste: dodajesz regułę do interesującego cię łańcucha, aby wysyłać do kolejki pakiety spełniające określone kryteria (adres IP źródłowy/docelowy, porty, stany, dodatkowe moduły, takie jak GeoIP lub warstwa 7, jeśli są dostępne itd.).

Na przykład, jeśli chcemy wysłać do NFQUEUE wszystkie pingi przychodzące do samego hosta:

iptables -I WEJŚCIE -p icmp -j NFQUEUE

Wysyła przychodzące pakiety ICMP do kolejki 0 (chyba że określono inaczej). Możemy określić inną kolejkę za pomocą polecenia `--queue-num 3` . Podczas wyświetlania reguł z licznikami (`iptables -L -n -v -x`) zobaczymy wzrost liczników, co oznacza, że ​​pakiety są kolejkowane . Ważny szczegół: jeśli w kolejce znajdują się pakiety, a żaden proces użytkownika ich nie pobierze i nie przetworzy, domyślnym zachowaniem jest ich odrzucenie, więc awaria aplikacji, zgodnie z założeniami, powoduje zablokowanie ruchu.

Programowanie w oparciu o libnetfilter_queue: „hello world” w C

Aby dołączyć do kolejki z przestrzeni użytkownika, używana jest biblioteka libnetfilter_queue (która z kolei opiera się na libnfnetlink). W dystrybucjach takich jak Debian wystarczy zainstalować pakiety deweloperskie:

apt-get install libnfnetlink-dev libnetfilter-queue-dev gcc

Szkielet minimalnego programu, który zawsze akceptuje pakiety, składa się z kilku bardzo przejrzystych kroków: otwarcia biblioteki, odłączenia istniejących handlerów, powiązania z protokołem AF_INET, utworzenia kolejki z funkcją zwrotną, zdefiniowania trybu kopiowania i wejścia w pętlę odbioru . Funkcja zwrotna jest wykonywana dla każdego pakietu w kolejce, wyodrębniając identyfikator i zwracając werdykt.

W praktyce przepływ wygląda mniej więcej tak: `nfq_open`, aby pobrać uchwyt, `nfq_unbind_pf`, aby go wyczyścić, `nfq_bind_pf`, aby powiązać z AF_INET, `nfq_create_queue`, aby zarejestrować wywołanie zwrotne w kolejce 0, `nfq_set_mode`, aby wskazać, czy chcemy metadane, czy cały pakiet, pętla z `recv()` po deskryptorze i `nfq_handle_packet`, aby przetworzyć każdy pakiet . Po wyjściu kolejka jest niszczona za pomocą `nfq_destroy_queue`, a uchwyt zamykany za pomocą `nfq_close`.

Ten typ „hello world” pozwala na precyzyjny pomiar wpływu NFQUEUE. Jeśli skompilujemy przykład za pomocą czegoś takiego:

gcc -o nftest code.c -lnfnetlink -lnetfilter_queue

A jeśli umieścimy w kolejce ruch z iperf (na przykład port TCP 5001 w wejściach i wyjściach), zobaczymy, że kod, który po prostu akceptuje pakiety, ma niewielki wpływ na wydajność w sieci gigabitowej . Jest jednak pewien kluczowy szczegół: wyświetlanie informacji w wywołaniu zwrotnym (printf, fflush itp.) znacząco obniża przepustowość, co widać porównując iperf z debugowaniem ekranu i bez niego.

Zaawansowane opcje NFQUEUE: obejście, równoważenie i otwieranie awaryjne

NFQUEUE zawiera kilka interesujących opcji iptables, które modyfikują domyślne zachowanie kolejek i które należy znać przed wprowadzeniem do środowiska produkcyjnego lub o wysokiej wydajności, ponieważ mają one wpływ na sposób obsługi awarii aplikacji użytkownika lub zapełniania kolejki.

Polecenie `--queue-bypass` pozwala upewnić się, że jeśli żaden proces nie nasłuchuje kolejki, pakiety nie zostaną porzucone, lecz przekazane do następnego przeskoku w łańcuchu iptables. Może to być przydatne, jeśli chcesz, aby system „awaryjnie otworzył się”, gdy usługa użytkownika jest niedostępna, choć z punktu widzenia bezpieczeństwa jest to miecz obosieczny.

Opcja `--queue-balance` umożliwia dystrybucję pakietów w zakresie kolejek (na przykład od 0 do 3), a następnie przetwarzanie danych z każdej kolejki przez wiele niezależnych procesów lub wątków . Kod Netfiltera gwarantuje, że pakiety z tego samego przepływu zawsze trafiają do tej samej kolejki, co znacznie upraszcza zachowanie spójności logiki decyzyjnej.

Dostępny jest również tryb `--fail-open` , który kontroluje, co się dzieje, gdy kolejka się zapełnia, ponieważ proces użytkownika działa zbyt wolno. Włączenie go powoduje, że jądro akceptuje pakiety bezpośrednio zamiast je odrzucać, co zapobiega poważnym zakłóceniom w ruchu. Ponownie, może to stanowić problem bezpieczeństwa, ponieważ jeśli chcemy podejmować decyzje indywidualnie, utrata pakietów decyzyjnych oznaczałaby brak osiągnięcia tego celu.

Aby monitorować, co dzieje się z kolejkami, Netfilter udostępnia informacje w pseudo-fs /proc/net/netfilter/nfnetlink_queue , które można łatwo uzyskać z poziomu skryptów lub narzędzi monitorujących.

Integracja logiki biznesowej: testowanie z Memcached i MySQL

Po opanowaniu procesu „hello world”, kolejnym naturalnym krokiem jest wzbogacenie wywołania zwrotnego o wywołania do systemów zewnętrznych . Typowy eksperyment polega na podjęciu decyzji o zaakceptowaniu lub odrzuceniu pakietu na podstawie tego, czy adres IP źródła pojawia się w jakimkolwiek systemie zaplecza, takim jak baza danych MySQL lub pamięć podręczna Memcached.

  Podstawowe polecenia w systemie Linux

W przypadku Memcached, demon jest instalowany (apt-get install memcached), a klucz, na przykład authorized , ładowany jest z interesującym nas adresem IP. Możemy to zrobić za pomocą prostego polecenia echo i netcat, a następnie sprawdzić poleceniem get, czy wartość jest poprawnie zapisana. Następnie program NFQUEUE, oprócz pobrania identyfikatora pakietu, odbiera cały pakiet za pomocą NFQNL_COPY_PACKET , wyodrębnia nagłówek IP (struct iphdr) i konwertuje adres źródłowy na ciąg znaków za pomocą inet_ntop.

Aby uniknąć marnowania czasu na otwieranie połączeń z każdym pakietem, połączenie Memcached jest inicjowane tylko raz w metodzie głównej (memcached_create, memcached_server_list_append, memcached_server_push), a obiekt obsługi jest przechowywany w zmiennych globalnych. W wywołaniu zwrotnym wywoływana jest funkcja memcached_get z żądanym kluczem, źródłowy adres IP jest porównywany z pobraną wartością i jeśli są one zgodne, zwracany jest kod NF_ACCEPT; w przeciwnym razie zwracany jest kod NF_DROP. Jeśli klucz nie istnieje lub wystąpił błąd, pakiet jest odrzucany zgodnie z polityką konserwatywną.

Korzystając z iperf, strategia ta redukuje przepustowość do około 140 Mb/s w sieci gigabitowej , a zaobserwowano, że kolejka zaczyna odnotowywać straty (o czym świadczą na przykład symbole w samym kodzie). Innymi słowy, samo wywołanie usługi pamięci podręcznej dla każdego pakietu generuje już znaczny koszt, choć po optymalizacji pozostaje opłacalne dla średniego natężenia ruchu.

W przypadku MySQL podejście jest podobne, ale bardziej złożone: instalowana jest biblioteka serwera i klienta, tworzona jest baza danych (na przykład nfqueue) z prostą tabelą o nazwie authorized(ip varchar(50)), a następnie wstawiany jest dozwolony adres IP. W programie `mysql_init` i `mysql_real_connect` są uruchamiane podczas uruchamiania, a w wywołaniu zwrotnym konstruowane jest zapytanie takie jak `select * from certified where ip like 'xxxx'`. Jeśli zapytanie zostanie wykonane pomyślnie i zostanie znaleziony wiersz, pakiet jest akceptowany; w przeciwnym razie jest odrzucany.

Przy włączonym buforowaniu zapytań MySQL, testy dają około 188 Mbit/s , która spada do 103 Mbit/s po wyłączeniu buforowania. Te wartości, choć dalekie od gigabitów, pokazują, że nawet przy najmniej eleganckim podejściu (jednowątkowym, bez optymalizacji) , można obsłużyć znaczne wolumeny ruchu, podejmując decyzje na podstawie bazy danych lub buforowania.

Wydajność, wielowątkowość i użycie procesora

Testy z iperf, Memcached i MySQL wyraźnie pokazują, że limit wydajności nie jest narzucany przez samą NFQUEUE, ale przez logikę, którą dodajemy w przestrzeni użytkownika i sposób jej implementacji. Plik wykonywalny, który zwraca tylko NF_ACCEPT, osiąga prawie gigabit bez najmniejszego wysiłku; gdy tylko dodamy wejście/wyjście lub wywołania sieciowe, przepustowość spada, a procesor maszyny NFQUEUE, demona Memcached lub MySQL jest obciążany do granic możliwości.

Z architektonicznego punktu widzenia ma to dwie implikacje. Z jednej strony potwierdza, że ​​delegowanie decyzji dotyczących zapory sieciowej do aplikacji użytkownika w przypadku znacznego natężenia ruchu jest całkowicie wykonalne , pod warunkiem uwzględnienia rzeczywistych kosztów każdego wywołania. Z drugiej strony pokazuje, że aby zbliżyć się do maksymalnych możliwości platformy, należy rozważyć wielowątkowość lub wieloprzetwarzanie . NFQUEUE umożliwia dystrybucję ruchu na wiele kolejek; moglibyśmy uruchomić kilka kopii naszej aplikacji, z których każda nasłuchiwałaby innej kolejki, i wykorzystać wiele rdzeni bez kłopotów związanych z wątkami pthread czy masowymi rozwidleniami.

Inną oczywistą optymalizacją byłoby ograniczenie ruchu przechodzącego przez NFQUEUE . W testach cały przepływ iperf był kolejkowany, ale w rzeczywistym scenariuszu moglibyśmy kolejkować tylko pakiety ze stanem NEW, przepuszczać pakiety ESTABLISHED/RELATED i rezerwować kosztowną logikę na logowania lub podejrzane wzorce.

Ostatecznie kluczowe znaczenie ma wykorzystanie procesora i projekt wątku: jeśli proces użytkownika okaże się niewystarczający, kolejka się zapełni i będziemy musieli uciec się do takich rozwiązań, jak otwieranie po awarii lub akceptowanie odrzuceń, tracąc w ten sposób część precyzyjnej kontroli, do której to podejście ma służyć.

Dynamiczne routowanie z brandingiem Netfilter

NFQUEUE nie ogranicza się do poleceń „accept” lub „throw”. Można go również używać do stosowania flag Netfilter (fwmark) do pakietów i łączenia ich z regułami ip oraz iproute2, tworząc niezwykle elastyczne i niemal lekkie schematy routingu politycznego w stylu VRF.

Ogólnie rzecz biorąc, procedura wyglądałaby tak: zdefiniuj kilka tabel trasowania w pliku /etc/iproute2/rt_tables , na przykład wolną i szybką; przypisz każdej tabeli inną domyślną trasę (jedną przez światłowód, a drugą przez bardziej ograniczone łącze); użyj reguły IP, aby określić, że pakiety z fwmark 1 mają trafić do tabeli szybkiej, te z fwmark 2 mają trafić do tabeli wolnej itd.; a na koniec użyj NFQUEUE, aby odpowiednio oznaczyć pakiety przed zwróceniem werdyktu.

Do ustawienia werdyktu na podstawie wywołania zwrotnego używany jest `nfq_set_verdict2` , który działa podobnie jak `nfq_set_verdict`, ale pozwala ustawić wartość werdyktu, którą następnie zobaczy `ip rule`. Łącząc to wszystko, można zbudować router IP, który decyduje, gdzie kierować ruch na podstawie dowolnych kryteriów: od absurdalnych rzeczy, takich jak parzysty/nieparzysty rozmiar pakietu, po zewnętrzne dane wejściowe, takie jak algorytmy przewidywania ruchu, zdarzenia w mediach społecznościowych czy sygnały z systemów monitorujących.

W rezultacie powstaje system, w którym jądro nadal przesyła pakiety ze zwykłą szybkością, ale dokładna ścieżka, jaką pokonuje każdy przepływ, jest delegowana do zewnętrznego oprogramowania , które może zmieniać zdanie w czasie rzeczywistym, nie naruszając statycznych reguł.

NFQUEUE i Suricata: IPS wysokiego poziomu w systemie GNU/Linux

Wszystkie powyższe funkcje można zaprogramować ręcznie w C, ale w przypadku wykrywania włamań i głębokiej inspekcji pakietów, rozsądną opcją jest zazwyczaj skorzystanie z dojrzałego silnika IDS/IPS . Właśnie tutaj pojawia się Suricata, który powstał właśnie jako wieloprocesowa alternatywa dla Snorta, z możliwościami IPS od samego początku i silnym naciskiem na wykorzystanie wielu rdzeni procesora dostępnych obecnie na rynku.

Suricata została napisana od podstaw i jest dystrybuowana na licencji GPLv2 ; Open Information Security Foundation (OISF) zarządza zarówno silnikiem, jak i dość obszernym ekosystemem reguł i dokumentacji. W przeciwieństwie do Snort 2.x, który odziedziczył jednowątkowy rdzeń i został na niego nałożony patch, Suricata została zaprojektowana tak, aby dzielić obciążenie na wiele wątków: przechwytywanie, dekodowanie, wykrywanie i przetwarzanie, z różnymi strategiami podziału obciążenia.

Na poziomie funkcjonalnym Suricata zapewnia natywne wsparcie dla protokołu IPv6, inspekcję warstwy 7 (bardzo zaawansowana biblioteka HTTP wykorzystująca protokół HTP), rozpoznawanie protokołu niezależne od portów , rekonstrukcję przepływu i bardzo wydajny system zmiennych sesji (flowbits) umożliwiający korelację różnych etapów ataku rozprzestrzeniającego się na wiele połączeń TCP.

Dodatkową zaletą jest kompatybilność z regułami Snort oraz możliwość korzystania z zestawów sygnatur Sourcefire VRT i Emerging Threats (darmowa wersja ET Open i komercyjna wersja ET Pro). Ponadto eksportuje zdarzenia w bardzo przydatnych formatach (fast.log, JSON w eve.json) do integracji z systemami SIEM, ELK, Splunk i innymi.

Suricata jako IPS w systemie Linux: tryby przechwytywania i NFQUEUE

W systemie GNU/Linux Suricata może działać w różnych trybach, w zależności od sposobu przechwytywania ruchu: NFQUEUE, AF_PACKET, PF_RING, libpcap, NFLOG, IPFW, DAG, Napatech … Każdy z nich ma swoje zalety i wymagania. Na poziomie czystego IPS, dwa najważniejsze to NFQUEUE i AF_PACKET.

W trybie NFQ (NFQUEUE) przepływ jest podobny do opisanego wcześniej: zestaw reguł iptables wysyła pakiety do kolejki; Suricata, działająca w przestrzeni użytkownika, odczytuje dane z tej kolejki, sprawdza zawartość zgodnie z jej regułami i zwraca werdykt do jądra: NF_ACCEPT, NF_DROP lub NF_REPEAT. Trzecia opcja może zostać użyta do ponownego wstrzyknięcia pakietu do tej samej tabeli iptables po zastosowaniu dodatkowych znaczników lub modyfikacji.

Ten tryb jest bardzo elastyczny i łatwy do wdrożenia w istniejących infrastrukturach , ponieważ wymaga modyfikacji reguł tylko w określonych punktach (na przykład FORWARD, INPUT, OUTPUT) i pozostawienia reszty bez zmian. Kosztem jest dodatkowy narzut związany z przesyłaniem pakietów w górę i w dół przez kolejkę NFQUEUE, z wyżej wymienionym wpływem, jeśli wolumen jest bardzo duży lub reguły są zasobochłonne.

W trybie AF_PACKET Suricata działa bliżej interfejsu sieciowego, kopiując pakiety przez gniazda AF_PACKET. Jest to znacznie szybsze podejście z zerowym kopiowaniem , ale wymaga, aby system funkcjonował jako brama z dwoma interfejsami i aby blokowanie ruchu było realizowane na poziomie przekazywania między kartami sieciowymi: blokowany pakiet po prostu nie jest przekazywany z interfejsu wejściowego do interfejsu wyjściowego.

  Manipulacja atrybutem ORIGIN w protokole BGP i jej wpływ na sieć

W obu trybach Suricata może być łączona z Netfilter, ale NFQUEUE sprawdza się szczególnie dobrze w scenariuszach, w których chcemy ponownie wykorzystać całą logikę iptables (zasady, zakresy, poprzednie reguły) i wysyłać do Suricata tylko ten ruch, który chcemy szczegółowo przeanalizować.

Podstawowa instalacja Suricata z kodu źródłowego

Dla osób, które wolą kompilować Suricatę zamiast korzystać z pakietów, proces w dystrybucjach typu Debian/Ubuntu obejmuje najpierw instalację zależności kompilacji (build-essential, libpcre, libpcap-dev, libnet-dev, libyaml-dev, zlib, libcap-ng-dev, libjansson-dev itp.), pobranie archiwum tarball z oficjalnej strony internetowej i uruchomienie klasycznego ./configure, make, make install.

Podczas fazy konfiguracji skrypt wskaże, które funkcje pomocnicze zostały włączone: AF_PACKET tak/nie, PF_RING, NFQUEUE tak/nie, NFLOG, IPFW, obsługa libnss, libjansson, Prelude, PCRE JIT, Lua, GeoIP itp. Ważne jest, aby sprawdzić, czy NFQUEUE jest włączone, jeśli chcemy pracować w tym trybie , i czy zlokalizowano interesującą nas bibliotekę przechwytującą.

Po zainstalowaniu pliku binarnego możesz uruchomić polecenie `make install-conf` , aby wdrożyć domyślną konfigurację w `/etc/suricata` oraz `make install-rules` , aby pobrać i umieścić zestaw reguł Emerging Threats w `/etc/suricata/rules`. Zestawy te można następnie zaktualizować za pomocą narzędzi takich jak `suricata-update`.

W systemach Red Hat/CentOS logika jest podobna – używa się yum lub dnf do określania zależności (libpcap-devel, pcre-devel, libnet-devel, libyaml-devel, jansson-devel itd.), a następnie kompiluje się je według tych samych kroków. Ze względu na wydajność zaleca się również wyłączenie funkcji LRO/GRO w interfejsie przechwytywania za pomocą ethtool, ponieważ te funkcje odciążające mogą wpływać na widoczność pakietów na poziomie IDS.

Konfiguracja Suricata: YAML, zmienne i wątki

Główna konfiguracja Suricaty znajduje się w pliku /etc/suricata/suricata.yaml . Jest to dość czytelny i bogato komentowany plik YAML, w którym zdefiniowano wszystko, od ścieżek dziennika i zestawów reguł po polityki docelowego systemu operacyjnego i parametry wątków.

Jednym z podstawowych pól jest `default-log-dir` , które określa miejsce przechowywania plików dziennika (domyślnie `/var/log/suricata`). W sekcji `vars` znajdują się zmienne takie jak `HOME_NET`, `EXTERNAL_NET`, `HTTP_PORTS`, `SHELLCODE_PORTS` i `SSH_PORTS`, które pełnią funkcję skrótów w regułach. `HOME_NET` jest zazwyczaj konfigurowane z zakresem sieci lokalnej, który chcemy chronić, podczas gdy `EXTERNAL_NET` jest zazwyczaj definiowane jako `!HOME_NET`.

Kolejnym ważnym elementem jest polityka host-os-policy , która informuje Suricatę, który system operacyjny ma obsługiwać określone zakresy adresów IP. Pozwala to na dostosowanie sposobu reasemblacji protokołu TCP lub interpretacji określonych zachowań stosu sieciowego , utrudniając omijanie protokołów w oparciu o różnice między stosami (Windows vs. Linux itp.). Konkretne zakresy można przypisać do kategorii, takich jak Windows, Linux, BSD, Vista, Windows 2003 itp.

Sekcja wątków pozwala na precyzyjne dostrojenie powinowactwa procesora i liczby wątków detekcji. Domyślnie `set-cpu-affinity` jest zazwyczaj wyłączone, co pozwala harmonogramowi systemowemu na rozłożenie wątków na rdzenie. Parametr `detect-thread-ratio` wskazuje, ile wątków detekcji jest tworzonych na każdy dostępny rdzeń; z parametrem `detect-thread-ratio: 1.5` na komputerze 8-rdzeniowym, Suricata wygeneruje 12 wątków detekcji plus wątki przechwytywania i zarządzania.

Cały ten model znajduje odzwierciedlenie w wynikach po uruchomieniu demona: oprócz menedżerów przepływu i statystyk widoczny jest wątek przechwytujący (na przykład pcap) i wiele wątków detektora. Ta wieloprocesowa architektura pozwala Suricacie skalować się znacznie lepiej niż silniki jednowątkowe w przypadku łączy 10/40 Gb/s.

Aktualizacje zasad i podpisów w Suricata

Suricata wykorzystuje zestawy reguł do wykrywania wzorców ataków, anomalii i nadużyć protokołów. Oprócz akceptowania reguł w formacie Snort , najpopularniejszym ekosystemem jest Emerging Threats: ET Open (bezpłatny) i ET Pro (komercyjny), z regułami ukierunkowanymi na aktualne zagrożenia.

Wiele nowoczesnych dystrybucji zawiera narzędzie `suricata-update` , które upraszcza zarządzanie regułami: aktualizuje źródła, włącza lub wyłącza określonych dostawców i pobiera najnowsze wersje zestawów sygnatur. Typowy obieg pracy polega na zainstalowaniu `suricata-update` (na przykład za pomocą pip), uruchomieniu pierwszego `suricata-update` w celu pobrania ET Open, wylistowaniu źródeł za pomocą `suricata-update list-sources`, włączeniu dodatkowych źródeł, takich jak `ptresearch/attackdetection`, `oisf/trafficid` lub `sslbl/ssl-fp-blacklist`, a następnie ponownym uruchomieniu `suricata-update` w celu ponownego wygenerowania pliku reguł.

Plik suricata.yaml jest dostosowywany tak, aby wskazywał prawidłową ścieżkę do reguł. Od tego momentu Suricata zacznie generować zdarzenia alertowe, które będą rejestrowane w plikach fast.log (szybki, czytelny tekst) i eve.json (ustrukturyzowany JSON z bardzo kompletnymi informacjami) . Ten ostatni format jest szczególnie przydatny do zasilania pulpitów nawigacyjnych, systemów korelacji lub skryptów niestandardowych.

Oprócz sygnatur Suricata zawiera dekodery i parsery dla wielu protokołów , co zmniejsza jej zależność od portów: potrafi identyfikować ruch HTTP nawet jeśli przechodzi przez niestandardowe porty, wykrywać SSH, TLS, DNS itp. na różnych portach i poziomach enkapsulacji (w tym mieszane tunele IPv4/IPv6).

Praktyczne zastosowanie: od wykrywania luk w zabezpieczeniach sieci po automatyczne blokowanie

Jednym z najbardziej pożądanych przypadków użycia w środowiskach hostingowych lub centrach danych jest wykrywanie w czasie rzeczywistym prób wykorzystania luk w zabezpieczeniach aplikacji internetowych (np. WordPress i jego wtyczki) i automatyczna reakcja, zwykle poprzez blokowanie lub umieszczanie na czarnej liście źródłowego adresu IP w zaporze sieciowej.

Suricata, oparta na zaktualizowanych regułach, potrafi rozpoznawać specyficzne wzorce ataków na adresy URL, parametry, ładunki HTTP , a nawet sekwencje żądań, które pasują do znanych exploitów. System IDS może działać w trybie pasywnym, odbierając ruch poprzez mirroring z portu przełącznika (SPAN), ale aby pełnić funkcję systemu IPS i blokować ataki, musi być zintegrowany z płaszczyzną przekazywania.

Istnieją dwa popularne podejścia: skonfigurowanie systemu IDS jako mostu online, tak aby ruch fizycznie przechodził przez maszynę (za pomocą iptables, AF_PACKET lub PF, w zależności od platformy), lub pozostawienie topologii bez zmian, ale połączenie lustrzanego odbicia z działaniami na centralnej zaporze sieciowej za pośrednictwem API, skryptów lub NFQUEUE . Pierwsze podejście minimalizuje opóźnienie między wykryciem a zablokowaniem, kosztem dodania kolejnego elementu „pośrodku” sieci; drugie oferuje większą elastyczność i odporność, ale wprowadza większą złożoność do orkiestracji.

System wykrywania włamań (IDS) może wykryć próbę wykorzystania podatnej wtyczki WordPressa, a następnie, bezpośrednio lub za pośrednictwem powiązanego komponentu, dodać adres IP atakującego do czarnej listy iptables. Można to zrobić za pomocą danych wyjściowych JSON Suricata i skryptów wywołujących iptables/nftables lub delegując część logiki do NFQUEUE, gdzie sam silnik lub powiązany proces podejmuje decyzję „w locie”, bez czekania na aktualizację listy zewnętrznej.

Dzięki temu możesz skupić się na zagrożeniach, które naprawdę mają znaczenie (exploity, próby eskalacji, bardzo agresywne skanowanie), ignorując lub po prostu rejestrując szum tła, taki jak podstawowe skanowanie portów, które w wielu kontekstach same w sobie nie są niepokojące.

Suricata na Pfsense: zapora sieciowa typu open source ze zintegrowanym systemem IDS/IPS

Nie każdy może sobie pozwolić lub chce na zastrzeżoną, zaawansowaną zaporę sieciową, taką jak Palo Alto. W wielu środowiskach bardziej atrakcyjne jest wdrożenie rozwiązania open source z pfSense i Suricata , które zaspokaja zarówno zaawansowane potrzeby zapory sieciowej (wiele sieci WAN, VLAN, VPN, NAT itp.), jak i systemy IDS/IPS.

Pfsense, oparty na FreeBSD i Packet Filter, działa szczególnie dobrze w środowiskach zwirtualizowanych (Proxmox, KVM itp.), z tym wyjątkiem, że w komputerach KVM zaleca się stosowanie kart E1000 zamiast Virtio, jeśli chce się uniknąć problemów z wydajnością i awarii pod obciążeniem, chyba że zastosuje się zalecenia firmy Netgate (wyłączenie sprzętowego odciążania sum kontrolnych w System > Zaawansowane > Sieć i ponowne uruchomienie, pamiętając, że może to nie wystarczyć przy bardzo dużych obciążeniach).

Minimalne wymagania sprzętowe dla laboratorium z Suricata na Pfsense mogą być skromne (1 procesor 500 MHz, 1 GB pamięci RAM, 4 GB dysku), ale do poważnego użytkowania zalecane są co najmniej 2 procesory, 4 GB pamięci RAM i 16 GB pamięci masowej , nie zapominając o konieczności posiadania kilku interfejsów sieciowych (jeden dla sieci WAN, drugi dla sieci LAN, więcej, jeśli chcesz mieć wiele sieci WAN lub złożone sieci VLAN).

  SteamOS: wszystkie informacje potrzebne do jego zrozumienia

Instalacja samego pfSense jest bardzo szybka: uruchamiasz system z obrazu ISO, akceptujesz licencję, wybierasz instalację, wybierasz język i układ klawiatury, ustawiasz automatyczne partycjonowanie (Auto UFS, jeśli zamierzasz korzystać z całego dysku) i po kilku minutach system jest gotowy do pierwszego uruchomienia. Konsola oferuje menu do przypisywania interfejsów, restartowania, uruchamiania powłoki itp.

Na przykład w laboratorium w VirtualBox, powszechną praktyką jest tymczasowe wyłączanie zapory Pfsense z konsoli za pomocą pfctl -d, aby uzyskać dostęp do interfejsu internetowego przez sieć WAN (nazwa użytkownika admin, hasło pfsense) i dokończenie pracy początkowego kreatora: dane ogólne, serwery NTP, konfiguracja sieci WAN (w laboratorium zazwyczaj wystarcza DHCP), sieć LAN, zmiana hasła administratora i zastosowanie konfiguracji.

Po ustabilizowaniu dostępu można utworzyć regułę w zaporze sieciowej WAN, która zezwala na ruch HTTPS z dowolnego źródła do adresu IP pfsense, dodając opisowe separatory, aby wizualnie uporządkować reguły (na przykład „Dostęp do zapory”). Zaleca się również wyłączenie opcji blokowania sieci prywatnych w sieci WAN w środowisku testowym z adresami RFC1918, aby uniknąć konieczności ciągłego używania polecenia `pfctl -d`.

Instalacja Suricata na pfSense i przegląd

Po uruchomieniu bazy pfSense instalacja Suricata jest tak prosta, jak przejście do System > Menedżer pakietów > Dostępne pakiety , wyszukanie Suricata i zainstalowanie pakietu. Proces ten wymaga pobrania kilku plików i może zająć trochę czasu w zależności od sprzętu, ale jest w pełni obsługiwany przez interfejs internetowy.

Po zainstalowaniu, na karcie Usługi pojawia się wpis Suricata, gdzie można skonfigurować instancje według interfejsu (WAN, LAN, VLAN itp.), wybrać zestawy reguł, aktywować tryb IDS lub IPS oraz dostosować parametry wydajności i rejestrowania. Zakres opcji jest obszerny (wystarczający na całe artykuły dotyczące konfiguracji), ale zaletą jest to, że wiele zadań, które w systemie Linux wymagają ręcznej edycji YAML, jest obsługiwanych tutaj za pomocą formularzy i pól wyboru.

Ważna uwaga: Choć otwarcie administracji pfSense bezpośrednio na internet w środowisku laboratoryjnym może wydawać się kuszące, w środowisku produkcyjnym kluczowe jest ograniczenie dostępu do statycznych adresów IP, korzystanie z sieci VPN do zdalnego zarządzania i unikanie pozostawiania za wszelką cenę odsłoniętej konsoli internetowej . pfSense jest bardzo elastyczny, ale należy go traktować jako element krytyczny, jakim jest.

Po włączeniu Suricata w pfSense otrzymujesz środowisko, w którym ruch przechodzi przez pfSense w celu obsługi zapory sieciowej i NAT, a Suricata sprawdza go zgodnie ze swoimi regułami i może blokować w trybie IPS . Ta kombinacja, zarządzana z poziomu jednego interfejsu webowego, znacznie upraszcza wdrażanie ochrony DPI w małych i średnich sieciach.

W wielu wdrożeniach uzupełnia je połączenie Pfsense/Suricata z systemem SIEM lub scentralizowaną platformą rejestrowania zdarzeń, wykorzystując ustrukturyzowane formaty wyjściowe do korelowania zdarzeń i wykrywania szerszych kampanii.

Monitorowanie zdarzeń i przykładowe dzienniki w Suricata

Po uruchomieniu Suricaty zdarzenia są rejestrowane w ścieżce zdefiniowanej przez default-log-dir, zazwyczaj /var/log/suricata . Plik fast.log wykorzystuje kompaktowy format tekstowy ze znacznikami czasu, identyfikatorami reguł, klasyfikacjami i priorytetami, co umożliwia szybką inspekcję z poziomu terminala (tail -f).

Na przykład, napotykając ruch z nieprawidłowymi sumami kontrolnymi TCP, możemy zobaczyć następujące wiersze: znaczniki czasu z datą i godziną, a następnie identyfikator reguły (np. 1:2200074:1), komunikat „SURICATA TCPv4 invalid checksum”, klasyfikację, priorytet oraz parę adresów IP/portów źródłowo-docelowych. Tego typu alerty pozwalają na szybką identyfikację problemów z integralnością pakietów lub prób obejścia zabezpieczeń.

Plik eve.json zawiera te same zdarzenia w formacie JSON, z polami takimi jak timestamp, event_type, src_ip, dest_ip, src_port, dest_port, proto oraz podplik alertu z parametrami action, gid, signature_id, rev, signature, category i severity. Ten format można łatwo pobrać za pomocą Logstash, Fluentd, Filebeat lub dowolnego innego agenta logującego , co pozwala na znacznie bogatszą analitykę niż w przypadku zwykłego tekstu.

Podczas wdrażania Suricaty na serwerze wielordzeniowym (np. 8-rdzeniowym), kompresja wątków jest wyraźnie widoczna w narzędziach takich jak htop w trybie wątkowym, pokazując jeden lub więcej wątków przechwytujących (pcap, AF_PACKET lub NFQ) oraz dużą liczbę wątków detekcji rozproszonych na rdzeniach. Dostosowanie współczynnika wykrywania i powinowactwa procesora może znacząco wpłynąć na przepustowość i opóźnienie, gdy natężenie ruchu zbliża się do limitu platformy.

Przed wdrożeniem w środowisku produkcyjnym warto poświęcić trochę czasu na dostrojenie zestawów reguł, które mają być aktywowane , aby uniknąć mnóstwa fałszywych alarmów, które mogłyby zablokować prawidłowy ruch lub zaśmiecić logi. Suricata-update pozwala wyłączyć całe kategorie lub pojedyncze reguły, aby znaleźć rozsądny balans między czułością a użytecznością.

Zastosowania specjalne: VoIP, analiza dźwięku i kreatywne NFQUEUE

Poza klasycznymi zastosowaniami (ochrona usług sieciowych, wykrywanie złośliwego oprogramowania, analiza DDoS), duet Netfilter+NFQUEUE pozwala na dość kreatywne rozwiązania w obszarach takich jak VoIP. Na przykład, możliwe jest skonfigurowanie filtra anty-SPIT (spam przez telefonię IP) lub systemu cenzurowania wulgaryzmów w strumieniach RTP.

Pomysł polegałby na tym, aby: identyfikować ruch RTP na podstawie portów lub rozpoznawania protokołu i przesyłać go do NFQUEUE; następnie z aplikacji użytkownika rekonstruować strumień RTP przy użyciu biblioteki, np. librtp , wyodrębniać dźwięk w formacie WAV i przesyłać go do modułu rozpoznawania słów kluczowych (wordspotting), np. biblioteki syntezy lub rozpoznawania oferowanej przez stronę trzecią.

Na podstawie wykrytych słów proces NFQUEUE może zezwolić na odtwarzanie, zablokować je, a nawet je zmodyfikować, wstawiając sygnał dźwiękowy do strumienia. To ostatnie wymaga jednak bardzo precyzyjnej kontroli nad protokołem RTCP, sekwencjami pakietów i synchronizacją – niemal jak podejście typu man-in-the-middle. Nie jest to trywialne, ale teoretycznie jest to całkowicie możliwe do osiągnięcia dzięki wykorzystaniu tego samego systemu kolejek i werdyktów.

Prawdą jest, że część z tego można by zrealizować za pomocą prostego sniffera przesyłającego dane do zewnętrznego procesora, a następnie przetwarzającego je na sygnalizacji SIP lub za pośrednictwem kontrolera SBC (Asterisk, Kamailio itp.). Różnica w porównaniu z NFQUEUE polega na tym, że działanie na przepływie RTP może być natychmiastowe i bezpośrednie , bez konieczności koordynowania wielu komponentów lub oczekiwania na zakończenie połączenia przez warstwę sygnalizacyjną.

Te scenariusze wyraźnie ilustrują potencjał połączenia GNU/Linux + Netfilter + Suricata + bibliotek firm trzecich: nie chodzi tu tylko o blokowanie portów i adresów IP, ale o podejmowanie złożonych decyzji dotyczących ruchu w czasie rzeczywistym przy użyciu ekosystemu w 100% wolnego oprogramowania.

Biorąc pod uwagę całą podróż, od małego programu w C, który zawsze akceptuje pakiety, po wdrożenie wieloprocesowego Suricata zintegrowanego z NFQUEUE, Pfsense, bazami danych i pamięcią podręczną, można docenić elastyczność, jaką oferuje ten zestaw technologii, umożliwiający budowę wszystkiego, od prostych dynamicznych zapór sieciowych po architektury IDS/IPS obejmujące centra danych, z prawdziwymi możliwościami dogłębnej inspekcji i zautomatyzowaną reakcją na coraz bardziej złożone ataki.