nftables

Jak zmusić jeden proces do korzystania z VPN na linux (OpenVPN)

Parę dni temu na forum dug.net.pl pojawiło się zapytanie dotyczące skonfigurowania linux'a w taki sposób, by ten umożliwił pojedynczemu procesowi w systemie (i tylko jemu) korzystanie z VPN, podczas gdy wszystkie pozostałe aplikacje korzystają ze standardowego łącza internetowego naszego ISP. Oczywiście to niekoniecznie musi być tylko jeden proces, bo to zagadnienie można rozciągnąć też na większą grupę procesów jednego lub więcej użytkowników. By to zadanie zrealizować, trzeba zdać sobie sprawę z faktu, że każdy proces w linux ma swojego właściciela, a ten właściciel przynależy do co najmniej jednej grupy. Dzięki takiemu rozwiązaniu, każdy proces w systemie ma przypisany m.in. identyfikator użytkownika (UID) oraz identyfikatory grup (GID), z którymi działa i na podstawie których to linux przyznaje uprawienia dostępu do różnych części systemu, np. urządzeń czy plików na dysku. W ten sposób możemy bardzo prosto ograniczyć dostęp do określonych zasobów konkretnym użytkownikom (bardziej ich procesom). Problem się zaczyna w przypadku sieci, gdzie w zasadzie dostęp do internetu ma domyślnie przyznany każdy proces. Naturalnie możemy skonfigurować filtr pakietów i zezwolić tylko części aplikacji na dostęp do sieci ale w dalszym ciągu, gdy tylko odpalimy VPN (w tym przypadku OpenVPN), to każdy proces mający prawo wysyłać pakiety sieciowe będzie je przesyłał z automatu przez VPN, jak tylko to połączenie zostanie zestawione. Istnieje jednak sposób, by nauczyć linux'a aby tylko procesy określonych użytkowników czy grup miały dostęp do VPN i gdy to połączenie zostanie zerwane, to te procesy nie będą mogły korzystać ze standardowego łącza internetowego. Trzeba jednak zaprzęgnąć do pracy iptables / nftables , tablice routingu oraz nieco inaczej skonfigurować klienta OpenVPN.

Blokowanie niepożądanej komunikacji z nftables na linux

Minęło już trochę czasu od momentu, w którym postanowiłem się przerzucić z iptables na nftables w swoim Debianie i w zasadzie większość mechanizmów obronnych mojego laptopowego firewall'a została już z powodzeniem przeportowana na ten nowy filtr pakietów. Poza tymi starymi regułami próbuję czasem ogarniać nieco bardziej wyrafinowane sposoby na unikanie zagrożeń sieciowych, choć implementacja niektórych rzeczy nie zawsze jest taka oczywista, z tym, że niekoniecznie niemożliwa do zrealizowana. Tak było w przypadku mechanizmu automatycznego blokowania hostów próbujących się łączyć z daną maszyną, która sobie najwyraźniej tego nie życzy. Dla przykładu, jest serwer udostępniający usługę SSH na porcie 11111 i tylko ten port jest wystawiony na świat. Wszelkiego rodzaju boty próbujące dostać się do maszyn linux'owych próbkują z kolei głównie standardowe porty, w tym przypadku 22 . Ci użytkownicy, którzy powinni mieć dostęp do usługi SSH, wiedzą na jakim porcie ona nasłuchuje. Można zatem założyć, że wszystkie połączenia na port 22 będą dokonywane przez boty albo przez użytkowników, którzy mają niecne zamiary. Wszystkie te połączenia można by zatem zablokować tworząc mechanizm automatycznego banowania hostów w oparciu o czas ostatniej próby połączenia, tak jak to zostało opisane mniej więcej w tym wątku na forum. Problem w tym, że tamto rozwiązanie dotyczy jedynie iptables w połączeniu z ipset , co nieco komplikuje wdrożenie go w przypadku nftables ale to zadanie jest jak najbardziej możliwe.

Unikanie SYN/ICMP/UDP/PING flood w linux z nftables

Obecnie nftables cierpi dość mocno z powodu pewnych problemów związanych z wydajnością przy aplikowaniu reguł zapory sieciowej. Niemniej jednak, w stosunku do iptables , nftables posiada tablicę netdev , która jest w stanie nieco zyskać w oczach tych nieco bardziej wybrednych użytkowników linux'a. Chodzi generalnie o fakt, że ta tablica jest umieszczona zaraz na początku drogi pakietów, tuż po odebraniu ich z NIC (interfejsu karty sieciowej), a biorąc pod uwagę fakt, że ruch sieciowy, który nigdy ma nie trafić do naszej maszyny, powinien być zrzucany jak najwcześniej (by nie marnować zasobów procesora i pamięci), to ta tablica wydaje się być idealnym miejscem by zablokować cały niepożądany ruch przychodzący. Przy wykorzystaniu iptables , takie pakiety zrzuca się w tablicy raw . Jeśli zaś chodzi o nftables , to zrzucanie pakietów w tablicy netdev jest ponad dwu lub nawet trzykrotnie bardziej wydajne (szybsze i mniej zasobożerne). Można zatem dość dobrze poradzić sobie z wszelkiego rodzaju atakami DOS/DDOS, np. ICMP/PING flood czy SYN flood. Zastanawiające może być natomiast ogarnięcie ataku UDP flood ale przed tym rodzajem ataku linux również jest w stanie się bez problemu ochronić.

Czy linux'owy firewall powinien blokować pakiety not-syn w stanie NEW

Od czasu do czasu w logu systemowym mojego Debiana można zanotować szereg pakietów przychodzących, które są zrzucane przez linux'owy firewall (nftables/iptables ). Po krótkiej analizie okazało się, że są to pakiety protokołu TCP mające stan NEW (czyli są to nowe połączenia) ale niezawierające przy tym flagi SYN . Mój laptop nie ma aktualnie przydzielonego zewnętrznego routowalnego adresu IPv4/IPv6, więc nasunęło się pytanie o przyczynę takiego stanu rzeczy -- przecie będąc za NAT, nikt spoza sieci nie powinien być w stanie nawiązać połączenia z moją maszyną, a ewidentnie co się do jej bram dobija i to nie z adresu lokalnego. Niby mam też odfiltrowane pakiety w stanie INVALID (np. te mające niepoprawny zestaw flag) ale widać te pakiety, o których mowa, nie zaliczają się do tego stanu, więc wygląda na to, że wszystko z nimi jest w porządku. Czy tego typu pakiety TCP w stanie NEW niemające ustawionej flagi SYN stanowią jakieś zagrożenie dla naszego komputera? Czy powinno się je zablokować, a może przepuścić w filtrze pakietów? A jeśli zablokować, to czy zwykły DROP wystarczy czy może powinno się te pakiety potraktować przy pomocy REJECT ?

Brak wsparcia dla ipset w nftables

Użytkownicy Debiana często w roli firewall'a wykorzystują już dość leciwy iptables . W zasadzie, to tej implementacji linux'owego filtra pakietów sieciowych nic nie dolega, no może poza szeregiem wad konstrukcyjnych, które są obecnie tak ciężkie do zaadresowania, że w sumie trzeba by cały ten iptables napisać od początku. Wszystko przez rozwój internetu, za sprawą którego pojawiło się zapotrzebowanie na tworzenie całej masy reguł (w postaci adresów/portów źródłowych/docelowych), gdzie w standardowym iptables trzeba tworzyć osobne wpisy. Im więcej reguł w filtrze, tym przechodzenie pakietów przez zaporę sieciową trwa dłużej i wiąże się z mocnym obciążeniem dla procesora (zwłaszcza, gdy tych reguł jest kilkadziesiąt tysięcy). By jakoś uporać się z tymi problemami (nieznanymi w innych filtrach sieciowych) stworzono ipset . I faktycznie odciążył on mocno procesor maszyny ale i tak nie wyeliminował on podstawowych wad iptables . Dlatego też zaczęto szukać innego rozwiązania i tak pojawiła się alternatywa m.in. w postaci nftables . W przyszłym stabilnym Debianie (buster) nftables będzie wykorzystywany jako domyślny filtr pakietów i ci, który korzystali z ipset mogą się nieco zdziwić, że nftables nie posiada dla niego wsparcia. Rzecz w tym, że nftables potrafi natywnie obsługiwać listy adresów/portów i ipset nie jest mu w tym do niczego potrzebny.

Migracja z iptables na nftables w Debianie

Zgodnie z informacją, która pojawiła się już ponad pół roku temu, dystrybucje linux'a powoli zaczynają odchodzić od iptables . Prawdopodobnie w niedługim czasie iptables zostanie już całkowicie wyparty i zastąpiony przez nftables , przynajmniej jeśli chodzi o desktopy. Nawet Debian zakomunikował, że następne wydanie stabilne tej dystrybucji (Buster) będzie domyślnie wykorzystywało nftables . Wypadałoby zatem się przenieść na ten nowy framework i przygotować sobie kilka podstawowych reguł firewall'a, które zabezpieczoną naszą maszynę przed nieautoryzowanym dostępem z sieci.

Czy brak wsparcia dla SYNPROXY w nftables jest problemem

Przenosząc swoje reguły z iptables na nftables zauważyłem, że jedna z nich (gdyby tylko jedna) nie została przetłumaczona przez ten dedykowany translator do reguł. Chodzi o mechanizm SYNPROXY, który jest zwykle wykorzystywany do ograniczenia skali ataków DDOS z wykorzystaniem pakietów SYN. Co by nie mówić, to ochrona jaką daje SYNPROXY jest jak najbardziej pożądana z perspektywy serwerów. Dlaczego zatem, gdy się zajrzy na stronę wspieranych rzeczy w nftables, to przy SYNPROXY widnieje bliżej nieokreślone sformułowanie consider native interface ? Po rozmowach z deweloperami udało się ustalić, że ten zapis oznacza brak wsparcia dla SYNPROXY w nftables . Jeśli zatem ktoś wykorzystuje ten mechanizm mając dodane stosowne reguły w iptables , to czy powinien się on obawiać przejścia na nftables ?

Jak ustalić nazwę procesu korzystającego z sieci

Konfigurując filtr pakietów iptables/nftables na Debianie zwykle nie przykładamy większej wagi do procesów, które chcą nawiązać połączenia wychodzące z naszego linux'owego hosta. Mamy przecież "skonfigurowany" firewall w łańcuchach INPUT i FORWARD i wszelkie zagrożenia z sieci nie powinny nas dotyczyć. Problem w tym, że jeśli jakiś złowrogi proces zostanie uruchomiony w naszym systemie, to jest on w stanie komunikować się ze światem zewnętrznym praktycznie bez żadnych ograniczeń za sprawą braku jakichkolwiek reguł w łańcuchu OUTPUT . Można oczywiście temu zaradzić budując zaporę sieciową na bazie cgroups , gdzie każda aplikacja będzie miała oznaczone pakiety, przez co będzie można je rozróżnić i zablokować albo przepuścić przez filter. W tym wpisie jednak nie będziemy się zajmować konstrukcją tego typu FW, tylko spróbujemy sobie odpowiedzieć na pytanie jak namierzyć proces, który komunikuje się z siecią (lub też próbuje), posiadając jedynie log iptables/nftables .