Filtrowanie stateful–inspection w Linuksie i BSD
Transkrypt
Filtrowanie stateful–inspection w Linuksie i BSD
Filtrowanie stateful–inspection w Linuksie i BSD Paweł Krawczyk 6 lipca 2001 Spis treści 1 Wstęp 3 2 Filtry pakietowe 3 3 Filtry stateful–inspection 4 4 Filtry w systemach operacyjnych 4 4.1 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4.2 BSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 4.3 Inne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 Linux 5 5.1 Wymagania . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5.2 Podstawy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5.3 Najprostsza konfiguracja dla stacji roboczej . . . . . . . . . . 6 5.3.1 O module state . . . . . . . . . . . . . . . . . . . . . . 6 5.3.2 Inne cechy modułu state . . . . . . . . . . . . . . . . . 7 5.4 Moduł state i FTP . . . . . . . . . . . . . . . . . . . . . . . . 7 5.5 Stacja robocza a protokół IDENT . . . . . . . . . . . . . . . 8 5.6 Konfiguracja dla serwera . . . . . . . . . . . . . . . . . . . . . 9 5.6.1 Ping . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.6.2 Dostęp do usług . . . . . . . . . . . . . . . . . . . . . 10 1 SPIS TREŚCI 2 5.6.3 Inne porty . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.6.4 Moduł unclean . . . . . . . . . . . . . . . . . . . . . . 10 5.7 Konfiguracja routerów . . . . . . . . . . . . . . . . . . . . . . 11 5.8 Dokumentacja . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 6 BSD 13 6.1 14 Najprostszy przykład . . . . . . . . . . . . . . . . . . . . . . . 7 Od autora 14 7.1 Uwagi końcowe . . . . . . . . . . . . . . . . . . . . . . . . . . 14 7.2 Zmiany . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1 1 WSTĘP 3 Wstęp Filtry pakietowe są dostępne praktycznie we wszystkich systemach operacyjnych. Stanowią podstawę ograniczeń dostępu do lokalnych usług, co przekłada się bezpośrednio na możliwość rozpoznania i zablokowania prób ataku. Dobrze administrowana sieć nigdy nie udostępnia na zewnątrz usług, które nie są niezbędne, nawet jeśli w danej chwili nie są znane żadne dziury w obsługujących je demonach. Celem tego artykułu jest przybliżenie użytkownikom Linuksa i systemów z rodziny BSD stosunkowo nowej i bardzo przydatnej techniki, jaką jest filtrowanie stateful–inspection. 2 Filtry pakietowe Klasyczny filtr pakietowy to zbiór reguł określających co system powinien zrobić z pakietem przychodzącym z sieci, lub do niej wychodzącym. Filtr jest sterowany zbiorem reguł, których podstawowymi elementami są wzorce oraz akcje, mówiące co zrobić z pakietem pasującym do danej reguły. W skład wzorca mogą wchodzić cechy charakterystyczne dla protokołu IP, takie jak adres źródłowy i docelowy pakietu, numery portów protokołów TCP i UDP, rozmaite flagi, typ komunikatu ICMP i inne, w zależności od zaawansowania i kompletności filtra. Przetwarzanie tych reguł odbywa się dla każdego pakietu przychodzącego lub wychodzącego z danego węzła. Pakiet pasujący do określonego w danej regułce wzorca jest traktowany zgodnie z przypisaną do niego akcją. Z reguły ogranicza się ona do przepuszczenia lub zablokowania pakietu, z ewentualnym odesłaniem odpowiedniego komunikatu ICMP. Klasyczne filtry pakietowe mają jedną charakterystyczną cechę, a mianowicie ich reguły są całkowicie lub w większości statyczne, to jest raz skonfigurowane przez administratora działają bez zmian aż do kolejnej jego ingerencji. Podejście takie stwarza nieraz konieczność takiego tworzenia reguł filtra, które nie implementują wszystkich wynikających z polityki bezpieczeństwa reguł, wymuszając pozostawienie w filtrze określonych furtek. Niedoskonałość klasycznych filtrów uniemożliwiają także całkowite zabezpieczenie serwera przed skanowaniem portów i innymi atakami, wykorzystującymi cechy protokołów TCP/IP. 3 FILTRY STATEFUL–INSPECTION 3 4 Filtry stateful–inspection Filtry stateful–inspection stoją o stopień wyżej od tradycyjnych zapór i skutecznie eliminują ich niedogodności. Podstawą ich działania jest bieżące śledzenie i analiza przechodzących przez dany węzeł połączeń, co pozwala na znacznie skuteczniejsze kontrolowanie ich legalności. Filtr cały czas przechowuje w pamięci informacje na temat aktualnego stanu każdego połączenia, wiedząc przy tym jakie kolejne stany są dozwolone z punktu widzenia zarówno protokołu, jak i polityki bezpieczeństwa. Filtry tego typu pozwalają na określenie możliwości dokonania danego połączenia bez konieczności operowania poszczególnymi stanami protokołu TCP. Do administratora należy tylko określenie kierunku oraz polityki względem rozpoczęcia danego połączenia, a filtr automatycznie weryfikuje kolejne etapy jego nawiązywania i późniejszy przebieg. Ta ostatnia cecha pozwala również na odrzucanie pakietów, które do danej sesji nie należą, co w praktyce przekłada się na skuteczne blokowanie prób skanowania portów lub wprowadzania sfałszowanych pakietów (spoofing). Przykładowo, klasyczny filtr pakietowy dla przepuszczenia pełnego połączenia TCP do danego serwera potrzebował co najmniej dwóch reguł: wpuszczania pakietów do danego adresu i ich wypuszczania na zewnątrz. Rozbudowywanie tej polityki na przykład od kierunek dozwolonych połączeń (czyli z której strony można je zaczynać) wymagało dalszego rozbudowania listy, na przykład o określenie że rozpoczynające połączenie pakiety z flagą SYN są wpuszczane tylko w danym kierunku. Dla filtra stateful–inspection w tym wypadku wystarczająca jest wyłącznie jedna reguła, a mianowicie że pakiety z flagą SYN są wpuszczane do serwera na danym porcie. Pakiety będące częścią połączenia idące w obu kierunkach będą przepuszczane automatycznie. Równocześnie jednak analogiczne, ale nie będące częścią dozwolonego połaczenia pakiety zostaną zablokowane. 4 Filtry w systemach operacyjnych Filtry stateful–inspection są dostępne w chwili obecnej w większości systemów open–source oraz w części produktów komercyjnych. 4.1 Linux Linux przeszedł do tej pory przez trzy wersje filtra pakietowego. W kernelach do 2.0 był to ipfw, następnie ipchains w 2.2 oraz iptables w kernelach 2.4. Tylko ostatni z nich jest filtrem stateful–inspection, działa jednak skutecznie i stabilnie. 5 LINUX 4.2 5 BSD We FreeBSD są dostępne dwa filtry pakietowe: ipfirewall/ipfw oraz ipfilter/ipf, w OpenBSD i NetBSD tylko ten ostatni. W ostatnich wersjach oba te filtry posiadają funkcję śledzenia połączeń, przy czym ipf zdecydowanie wyróżnia się elastycznością konfiguracji i dojrzałością. 4.3 Inne Filtry stateful–inspection są również spotykane w produktach komercyjnych. I tak, popularny Cisco IOS posiada tę funkcję pod nazwą Context Based Access Control (CBAC). Filtrem tego typu jest również CheckPoint FireWall–1. 5 Linux 5.1 Wymagania • Kernel 2.4.x, nie wiem które dystrybucje zawierają go domyślnie. Sam kompiluję ze źródeł. • Program iptables, dostępny w źródłach na stronie iptables lub jako pakiet dla poszczególnych dystrybucji. Użytkownicy Debiana mogą doinstalować kernel wraz z koniecznymi narzędziami z deb http://people.debian.org/~bunk/debian potato main. Jeśli konfigurujemy kernel samodzielnie, to istotne są następujące opcje w menu Networking options: • Network packet filtering (replaces ipchains) • IP: Netfilter Configuration, menu w którym należy wszystkie (oprócz jednej) pozycje zaznaczyć jako moduły (M) • IP tables support (required for filtering/masq/NAT) warto natomiast wkompilować na stałe, bo kernel nie potrafi sam załadować tego modułu. 5.2 Podstawy Konfiguracja iptables odbiega nieco od znanego z wcześniejszych wersji ipchains, głównie dlatego że nowy filtr jest w dużej mierze modularny. Opcje, które kiedyś były stałymi parametrami programu ipchains są obecnie realizowane przez poszczególne moduły. Do poprawnego działania potrzebne są 5 LINUX 6 odpowiednie moduły, wkompilowane w kernel 2.4 oraz program iptables, służący do konfiguracji filtra. Filozofii nowego filtra jest dość podobna — mamy tutaj także trzy domyślne zestawy reguł INPUT, FORWARD i OUTPUT oraz szereg celów (targets), które określają co należy zrobić z pakietem pasującym do danej regułki. Najczęściej używane to ACCEPT, DROP (zablokowanie pakietu bez powiadomienia nadawcy) oraz REJECT (zablokowanie ze zwróceniem komunikatu ICMP). 5.3 Najprostsza konfiguracja dla stacji roboczej Funkcja śledzenia połączeń jest w iptables realizowana przez moduł state. Najprostsza konfiguracja, która realizować będzie takie filtrowanie i użyteczna na przykład na stacji roboczej, która nie udostępnia żadnych usług, wygląda tak: iptables -F iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -p udp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -p icmp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -j LOG -m limit --limit 10/hour iptables -A INPUT -j DROP Konfiguracja ta składa się z następujących fragmentów: 1. Usunięcie wszystkich reguł filtra. 2. Dodanie reguły wpuszczającej wszystko na interfejsie lokalnym lo. 3. Dodanie do tablicy INPUT reguł wpuszczających pakiety należące do już nawiązanych (ESTABLISHED) połączeń. 4. Dodanie, na końcu, dwóch reguł blokujących. Pierwsza tak na prawdę tylko loguje pakiety, które nie zostały wpuszczone przez poprzednie reguły. Druga faktycznie je blokuje. 5.3.1 O module state Kluczowe w tym wypadku są regułki korzystające z modułu state. Ostateczny zezultat ich zastosowania jest taki, że wszystkie połączenia wychodzące będą działać bez ograniczeń (ponieważ nie skonfigurowaliśmy ograni- 5 LINUX 7 czeń w tablicy OUTPUT), a wszystkie połączenia przychodzące będą blokowan. Każde takie połączenie będzie jednak zapamiętywane i należące do niego pakiety powracające będą automatycznie przepuszczane przez tablicę INPUT. Równocześnie filtr stateful–inspection wykryje także pakiety nie pasujące do zapamiętanych połączeń i zasygnalizuje ich wyblokowanie. Mogą to być na przykład pakiety przysłane podczas próby spoofingu lub skanowania zaawansowanymi technikami, takimi jak ACK scanning. Zastosowanie celu DROP dla wyblokowanych pakietów będzie dodatkowym utrudnieniem dla skanującego wszystkie porty na danej maszynie, ponieważ brak typowej odpowiedzi (ICMP Port unreachable lub ICMP Packet filtered) spowoduje, że skaner będzie musiał czekać przez ustalony czas, zanim uzna taki port za nieaktywny. 5.3.2 Inne cechy modułu state Dodajmy, że stan ESTABLISHED nie odnosi się tylko do TCP, który jest protokołem połączeniowym i łatwo stwierdzić czy połączenie jest nawiązane, czy nie. Dokumentacja filtru definiuje ten stan jako odnoszący się do „połączeń, które wymieniły pakiety w obu kierunkach”. Stąd możliwe jest zastosowanie tej flagi do protokołów takich jak UDP i ICMP. Moduł state zna również inne stany połączeń. Są to: • NEW — pakiety inicjujące nowe połączenie (lub przesyłane tylko w jednym kierunku) • RELATED — pakiety nie należące bezpośrednio, ale związane w inny sposób ze znaną sesją; przykładem mogą być tutaj kanały danych w FTP lub błędy zwracane po ICMP 1 INVALID — pakiety nie związane z żadną zapamiętaną sesją 5.4 Moduł state i FTP Komentarza wymaga funkcja RELATED, która faktycznie rozszerza właściwości filtra warstwy trzeciej (IP, ICMP) i czwartej (TCP, UDP) o zdolność rozumienia i reagowania na stany protokołów wyższych warstw. Najprościej przedstawić to na przykładzie protokołu FTP, który od zawsze był zmorą osób projektujących filtry pakietowe. Protokół ten wykorzystuje stałe połączenie na port 21 serwera do wydawania komend, natomiast samo przesyłanie plików działa w dwóch trybach: 1 • 5 LINUX 8 • W trybie aktywnym (PORT mode) klient otwiera po swojej stronie jakiś wysoki port i podaje serwerowi jego numer. Serwer wykonuje na ten port połączenie i przesyła dane. • W trybie pasywnym (passive mode) to serwer otwiera wysoki port, a klient nawiązuje na niego połączenie otrzymując dane. Jak się łatwo domyślić, trybu aktywnego nie będziemy w stanie używać zza maskarady, ponieważ serwer FTP nie będzie w stanie połączyć się z naszym hostem, ukrytym za routerem realizującym NAT.2 Tryb pasywny również nie jest rozwiązaniem idealnym, ponieważ musimy zezwolić klientowi z sieci wewnętrznej na wykonywanie praktycznie dowolnych połączeń na zewnątrz3 . Z pomocą przychodzi nam tutaj funkcja RELATED, która wypuści na zewnątrz połączenia na określony wysoki port tylko wtedy, kiedy żądanie jego otwarcia zostało jawnie wydane podczas sesji FTP. W tym celu router musi śledzić każde przechodzące przez niego połączenia FTP i szukać w nich komend, otwierających porty pasywne. Jeśli takie znajdzie, zapamiętuje ten fakt na potrzeby regułki RELATED. Dla każdego protokołu wyższej warstwy musimy załadować odpowiedni moduł interpretujący. W przypadku FTP jest to moduł ip conntrack ftp, dostępny w standardowej dystrybucji kernela (drugi to ip conntrack irc. W sieci można również znaleźć moduły do innych protokołów. Należy pamiętać, że moduły te nie są ładowane automatycznie — trzeba je załadować jawnie za pomocą poleceń insmod albo modprobe. 5.5 Stacja robocza a protokół IDENT Powyższa konfiguracja jest skuteczna, ma jednak jedną wadę, która wyjdzie na jaw prędzej czy później. Otóż łącząc się z tak skonfigurowanego hosta z niektórymi serwerami FTP zauważymy, że występuje kilkudziesięciosekundowe opóźnienie pomiędzy nawiązaniem połączenia, a zalogowaniem do serwera. Wynika to stąd, że duża liczba serwerów FTP (i nie tylko) próbuje uzyskać od klienta informacje o użytkowniku po protokole IDENT, próbując nawiązać zwrotne połączenie na port 113, przypisany do tej usługi. Ponieważ nasz host nie akceptuje żadnych połączeń przychodzących i nie odrzuca ich w jawny sposób, serwer FTP wpuści nas dopiero po przekroczeniu czasu oczekiwania z usługą IDENT. 2 Chyba, że załadujemy moduł , który będzie oszukiwał nasz router i przekazywał połączenia do środka. 3 Większość serwerów FTP otwiera porty pasywne z pewnego określonego przedziału. Można więc obejść ten problem otwierając tylko ten zakres portów, ale nie jest to rozwiążanie eleganckie. 5 LINUX 9 Aby uniknąć tego nieszkodliwej, ale irytującej niedogodności należy spowodować, by połączenia na port 113 były jawnie odrzucane, dając tym samym do zrozumienia że nie mamy serwera IDENT. Poprawiona konfiguracja znajduje się poniżej: iptables -F iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp --dst 0/0 --dport 113 \ -j REJECT --reject-with icmp-port-unreachable iptables -A INPUT -p tcp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -p udp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -p icmp -j ACCEPT -m state --state ESTABLISHED iptables -A INPUT -j LOG -m limit --limit 10/hour iptables -A INPUT -j DROP Wykorzystaliśmy cel REJECT, ze wskazaniem że zwrócony ma być standardowy w takim wypadku komunikat ICMP Port unreachable. 5.6 Konfiguracja dla serwera O ile stacja robocza może jawić się z zewnątrz jako głuchy bastion, o tyle w przypadku serwera musimy dopuścić przynajmniej połączenia przychodzące na wybrane usługi. Konfiguracja komplikuje się jeszcze bardziej (pod względem ilości reguł), jeśli usługi te mają być dostępne tylko z niektórych adresów i tak dalej. Tworząc konfigurację filtra możemy oprzeć się o przedstawione wyżej przykłady konfiguracji, dopisując nowe regułki przed ostatnimi dwoma, blokującymi wszystko. 5.6.1 Ping Pierwszą modyfikacją może być dopuszczenie pakietów ICMP Echo, czyli popularnego pinga: iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT Tutaj należy się komentarz — o ile część administratorów blokuje tę usługę, o tyle ja sam jestem zdania że jest to polityka przynosząca więcej szkody niż pożytku i nie przyczyniająca się w znaczący sposób do poprawienia bezpieczeństwa serwera. Tymczasem ping przydaje się po prostu do stwierdzania, czy serwer działa i jak długo wędrują do niego pakiety.