Filtrowanie pakietów





1 Wstep
Filtry pakietowe sa dostepne praktycznie we wszystkich systemach operacyjnych. Stanowia podstawe ograniczen dostepu do lokalnych usług, co przekłada sie bezposrednio na mozliwosc rozpoznania i zablokowania prób ataku. Dobrze administrowana siec nigdy nie udostepnia na zewnatrz usług, które nie sa niezbedne, nawet jesli w danej chwili nie sa znane zadne dziury w obsługujacych je demonach.
Celem tego artykułu jest przyblizenie uzytkownikom Linuksa i systemów z rodziny BSD stosunkowo nowej i bardzo przydatnej techniki, jaka jest filtrowanie stateful–inspection.
Dwie uwagi odnosnie tego artykułu: po pierwsze, jest on w fazie intensywnego rozwoju i dosc czesto jest on uzupełniany o nowe funkcje oraz przykłady. Na samym koncu jest informacja, gdzie mozna znalezc aktualne wersje oraz jakie zmiany zostały wprowadzone do tej wersji. Po drugie, jesli przymierzasz sie do skonfigurowania filtra dla duzej sieci, zdecydowanie przeczytaj cały artykuł i wszystkie przykłady. Sa one tak skomponowane, ze kazdy kolejny zawiera tylko kilka nowych funkcji by zbytnio nie zaciemnic towarzyszacych im opisów. Sa one równiez stopniowane wzgledem stopnia skomplikowania oraz, co istotniejsze, skutecznosci.

2 Filtry pakietowe
Klasyczny filtr pakietowy to zbiór reguł okreslajacych co system powinien zrobic z pakietem przychodzacym z sieci, lub do niej wychodzacym. Filtr jest sterowany zbiorem reguł, których podstawowymi elementami sa wzorce oraz akcje, mówiace co zrobic z pakietem pasujacym do danej reguły. W skład wzorca moga wchodzic cechy charakterystyczne dla protokołu IP, takie jak adres zródłowy i docelowy pakietu, numery portów protokołów TCP i UDP, rozmaite flagi, typ komunikatu ICMP i inne, w zaleznosci od zaawansowania i kompletnosci filtra.
Przetwarzanie tych reguł odbywa sie dla kazdego pakietu przychodzacego lub wychodzacego z danego wezła. Pakiet pasujacy do okreslonego w danej regułce wzorca jest traktowany zgodnie z przypisana do niego akcja. Z reguły ogranicza sie ona do przepuszczenia lub zablokowania pakietu, z ewentualnym odesłaniem odpowiedniego komunikatu ICMP. Klasyczne filtry pakietowe maja jedna charakterystyczna ceche, a mianowicie ich reguły sa całkowicie lub w wiekszosci statyczne, to jest raz skonfigurowane przez administratora działaja bez zmian az do kolejnej jego ingerencji. Podejscie takie stwarza nieraz koniecznosc takiego tworzenia reguł filtra, które nie implementuja wszystkich wynikajacych z polityki bezpieczenstwa reguł,

3 FILTRY STATEFUL–INSPECTION 4
wymuszajac pozostawienie w filtrze okreslonych furtek. Niedoskonałosci klasycznych filtrów uniemozliwiaja takze całkowite zabezpieczenie serwera przed skanowaniem portów i innymi atakami, wykorzystujacymi cechy protokołów TCP/IP.
Filtry stateful–inspection stoja o stopien wyzej od tradycyjnych zapór i skutecznie
eliminuja ich niedogodnosci. Podstawa ich działania jest biezace sledzenie i analiza przechodzacych przez dany wezeł połaczen, co pozwala na znacznie skuteczniejsze kontrolowanie ich legalnosci. Filtr cały czas przechowuje w pamieci informacje na temat aktualnego stanu kazdego połaczenia, wiedzac przy tym jakie kolejne stany sa dozwolone z punktu widzenia zarówno protokołu, jak i polityki bezpieczenstwa.
Filtry tego typu pozwalaja na okreslenie mozliwosci dokonania danego połaczenia bez koniecznosci operowania poszczególnymi stanami protokołu TCP. Do administratora nalezy tylko okreslenie kierunku oraz polityki wzgledem rozpoczecia danego połaczenia, a filtr automatycznie weryfikuje kolejne etapy jego nawiazywania i pózniejszy przebieg. Ta ostatnia cecha pozwala równiez na odrzucanie pakietów, które do danej sesji nie naleza, co w praktyce przekłada sie 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łaczenia TCP do danego serwera potrzebował co najmniej dwóch reguł: wpuszczania pakietów do danego adresu i ich wypuszczania na zewnatrz. Rozbudowywanie tej polityki na przykład o kierunek dozwolonych połaczen (czyli z której strony mozna je zaczynac) wymagało dalszego rozbudowania listy, na przykład o okreslenie ze rozpoczynajace połaczenie pakiety z flaga SYN sa wpuszczane tylko w danym kierunku. Dla filtra stateful–inspection w tym wypadku wystarczajaca jest wyłacznie jedna reguła, a mianowicie ze pakiety z flaga SYN sa wpuszczane do serwera na danym porcie. Pakiety bedace czescia połaczenia idace w obu kierunkach beda przepuszczane automatycznie. Równoczesnie jednak analogiczne, ale nie bedace czescia dozwolonego połaczenia pakiety zostana zablokowane.

4 Filtry w systemach operacyjnych
Filtry stateful–inspection sa dostepne w chwili obecnej w wiekszosci systemów open–source oraz w czesci produktów komercyjnych.


4.1 Linux
Linux przeszedł do tej pory przez trzy wersje filtra pakietowego. W kernelach do 2.0 był to ipfw, nastepnie ipchains w 2.2 oraz iptables w kernelach 2.4. Tylko ostatni z nich jest filtrem stateful–inspection, działa jednak skutecznie i stabilnie. W chwili obecnej jest to jeden z najlepszych znanych mi filtrów pakietowych na swiecie.

4.2 BSD
We FreeBSD sa dostepne dwa filtry pakietowe: ipfirewall/ipfw oraz ipfilter/ipf, w OpenBSD i NetBSD tylko ten ostatni. W ostatnich wersjach oba te filtry posiadaja funkcje sledzenia połaczen, przy czym ipf zdecydowanie wyróznia sie elastycznoscia konfiguracji i dojrzałoscia. Pod wzgledem funkcjonalnym minimalnie ustepuje iptables, wbrew temu co na listach dyskusyjnych poswieconych BSD głosza niekiedy zwolennicy tego systemu.

4.3 Inne
Filtry stateful–inspection sa równiez spotykane w produktach komercyjnych. I tak, popularny Cisco IOS posiada te funkcje pod nazwa Context Based Access Control (CBAC). Filtrem tego typu jest równiez CheckPoint FireWall–1.

5 Linux

5.1 Wymagania
• Kernel 2.4.x, nie wiem które dystrybucje zawieraja go domyslnie 1 . Sam kompiluje ze zródeł.
• Program iptables, dostepny w zródłach na stronie iptables lub jako pakiet dla poszczególnych dystrybucji. Jesli konfigurujemy kernel samodzielnie, to istotne sa nastepujace opcje w menu Networking options:
• Network packet filtering (replaces ipchains)
• Wchodzimy do menu IP: Netfilter Configuration
1 Uzytkownicy Debiana moga doinstalowac kernel wraz z koniecznymi narzedziami przez APT deb http://people.debian.org/ bunk/debian potato main.
• IP tables support (required for filtering/masq/NAT) nalezy wkompilowac na stałe2
• Wszystki pozostałe opcje zaznaczamy jako moduły.

5.2 Podstawy
Konfiguracja iptables odbiega nieco od znanego z wczesniejszych wersji ipchains, głównie dlatego ze nowy filtr jest w duzej mierze modularny. Opcje, które kiedys były stałymi parametrami programu ipchains sa obecnie realizowane przez poszczególne moduły. Do poprawnego działania potrzebne sa odpowiednie moduły, wkompilowane w kernel 2.4 oraz program iptables, słuzacy do konfiguracji filtra.
Filozofia nowego filtra jest dosc podobna — mamy tutaj takze trzy domyslne zestawy reguł INPUT, FORWARD i OUTPUT oraz szereg celów (targets), które okreslaja co nalezy zrobic z pakietem pasujacym do danej regułki. Najczesciej uzywane to ACCEPT, DROP (zablokowanie pakietu bez powiadomienia nadawcy) oraz REJECT (zablokowanie ze zwróceniem komunikatu ICMP).
Warto jednak dodac, ze w nowym filtrze zasadniczo zmieniły sie reguły przepuszczania pakietów przez poszczególne zestawy reguł. Pakiety przesyłane (forwarded) z innych interfejsów przechodza wyłacznie przez zestaw FORWARD. Dwa pozostałe zestawy — INPUT i OUTPUT obsługuja wyłacznie pakiety konczace droge na lokalnym systemie lub na nim generowane.

5.3 Najprostsza konfiguracja dla stacji roboczej
Funkcja sledzenia połaczen jest w iptables realizowana przez moduł state. Najprostsza konfiguracja, która realizowac bedzie takie filtrowanie i uzyteczna na przykład na stacji roboczej, która nie udostepnia zadnych usług, wyglada 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
2Wynika to stad, ze kernel nie potrafi samodzielnie załadowac tego jako modułu przy wywołaniu iptables.

Konfiguracja ta składa sie z nastepujacych fragmentów:
1. Usuniecie wszystkich reguł filtra.
2. Dodanie reguły wpuszczajacej wszystko na interfejsie lokalnym lo.
3. Dodanie do tablicy INPUT reguł wpuszczajacych pakiety nalezace do juz nawiazanych (ESTABLISHED) połaczen.
4. Dodanie, na koncu, dwóch reguł blokujacych. Pierwsza tak na prawde 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 sa regułki korzystajace z modułu state. Ostateczny rezultat ich zastosowania jest taki, ze wszystkie połaczenia wychodzace beda działac bez ograniczen (poniewaz nie skonfigurowalismy ograniczen w tablicy OUTPUT), a wszystkie połaczenia przychodzace beda blokowane. Kazde takie połaczenie bedzie jednak zapamietywane i nalezace do niego pakiety powracajace beda automatycznie przepuszczane przez tablice INPUT. Równoczesnie filtr stateful–inspection wykryje takze pakiety nie pasujace do zapamietanych połaczen i zasygnalizuje ich wyblokowanie. Moga to byc 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 bedzie dodatkowym utrudnieniem dla skanujacego wszystkie porty na danej maszynie, poniewaz brak typowej odpowiedzi (ICMP Port unreachable lub ICMP Packet filtered) spowoduje, ze skaner bedzie musiał czekac przez ustalony czas, zanim uzna taki port za nieaktywny.

5.3.2 Inne cechy modułu state
Dodajmy, ze stan ESTABLISHED nie odnosi sie tylko do TCP, który jest protokołem połaczeniowym i łatwo stwierdzic czy połaczenie jest nawiazane, czy nie. Dokumentacja filtru definiuje ten stan jako odnoszacy sie do „połaczen, które wymieniły pakiety w obu kierunkach”. Stad mozliwe jest zastosowanie tej flagi do protokołów takich jak UDP i ICMP. Moduł state zna równiez inne stany połaczen. Sa to:
• NEW — pakiety inicjujace nowe połaczenie (lub przesyłane tylko w jednym kierunku)
• RELATED — pakiety nie nalezace bezposrednio, ale zwiazane w inny sposób ze znana sesja; przykładem moga byc tutaj kanały danych w FTP lub błedy zwracane po ICMP 3
• INVALID — pakiety nie zwiazane z zadna zapamietana sesja

5.4 Moduł state i FTP
Komentarza wymaga funkcja RELATED, która faktycznie rozszerza własciwosci filtra warstwy trzeciej (IP, ICMP) i czwartej (TCP, UDP) o zdolnosc rozumienia i reagowania na stany protokołów wyzszych warstw. Najprosciej przedstawic to na przykładzie protokołu FTP, który od zawsze był zmora osób projektujacych filtry pakietowe. Protokół ten wykorzystuje stałe połaczenie na port 21 serwera do wydawania komend, natomiast samo przesyłanie plików działa w dwóch trybach:
• Wtrybie aktywnym (PORT mode) klient otwiera po swojej stronie jakis wysoki port i podaje serwerowi jego numer. Serwer wykonuje na ten port połaczenie i przesyła dane.
• W trybie pasywnym (passive mode) to serwer otwiera wysoki port, a klient nawiazuje na niego połaczenie otrzymujac dane. Jak sie łatwo domyslic, trybu aktywnego nie bedziemy w stanie uzywac zza maskarady, poniewaz serwer FTP nie bedzie w stanie połaczyc sie z naszym hostem, ukrytym za routerem realizujacym NAT.4 Tryb pasywny równiez nie jest rozwiazaniem idealnym, poniewaz musimy zezwolic klientowi z sieci wewnetrznej na wykonywanie praktycznie dowolnych połaczen na zewnatrz5. Z pomoca przychodzi nam tutaj funkcja RELATED, która wypusci na zewnatrz połaczenia na okreslony wysoki port tylko wtedy, kiedy zadanie jego otwarcia zostało jawnie wydane podczas sesji FTP. W tym celu router musi sledzic kazde przechodzace przez niego połaczenia FTP i szukac w nich komend, otwierajacych porty pasywne. Jesli takie znajdzie, zapamietuje ten fakt na potrzeby regułki RELATED.
3Na przykład, komunikat ICMP Time Exceeded wysłany w odpowiedzi na wysłany przez nas pakiet UDP jest uznawany za RELATED w stosunku do niego.
4Chyba, ze załadujemy moduł ip nat ftp, który bedzie oszukiwał nasz router i przekazywał połaczenia do srodka.
5Wiekszosc serwerów FTP otwiera porty pasywne z pewnego okreslonego przedziału. Mozna wiec obejsc ten problem otwierajac tylko ten zakres portów, ale nie jest to rozwiazanie eleganckie.
Dla kazdego protokołu wyzszej warstwy musimy załadowac odpowiedni moduł interpretujacy. W przypadku FTP jest to moduł ip conntrack ftp, dostepny w standardowej dystrybucji kernela (drugi to ip conntrack irc. W sieci mozna równiez znalezc moduły do innych protokołów. Nalezy pamietac, ze moduły te nie sa ładowane automatycznie — trzeba je załadowac jawnie za pomoca polecen insmod albo modprobe.

5.5 Stacja robocza a protokoły IDENT i SOCKS
Powyzsza konfiguracja jest skuteczna, ma jednak jedna wade, która wyjdzie na jaw predzej czy pózniej. Otóz łaczac sie z tak skonfigurowanego hosta z niektórymi serwerami FTP zauwazymy, ze wystepuje kilkudziesieciosekundowe opóznienie pomiedzy nawiazaniem połaczenia, a zalogowaniem do serwera. Wynika to stad, ze duza liczba serwerów FTP (i nie tylko) próbuje uzyskac od klienta informacje o uzytkowniku po protokole IDENT, próbujac nawiazac zwrotne połaczenie na port 113, przypisany do tej usługi. Poniewaz nasz host nie akceptuje zadnych połaczen przychodzacych i nie odrzuca ich w jawny sposób, serwer FTP wpusci nas dopiero po przekroczeniu czasu oczekiwania z usługa IDENT.
To samo dotyczy protokołu SOCKS, działajacego domyslnie na porcie 1080. Wiele serwerów IRC wykonuje zwrotne połaczenie na ten port aby sprawdzic, czy uzytkownik nie loguje sie zza proxy. Tradycyjne wyblokowanie tego portu równiez jest przyczyna opóznien w logowaniu do serwera. Aby uniknac tej nieszkodliwej, ale irytujacej niedogodnosci nalezy spowodowac, by połaczenia na porty 113 i 1080 były jawnie odrzucane, dajac tym samym do zrozumienia ze nie mamy serwera IDENT ani SOCKS. Poprawiona konfiguracja znajduje sie ponizej:
iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 113 \
-j REJECT --reject-with icmp-port-unreachablev iptables -A INPUT -p tcp --dport 1080 \
-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
Wykorzystalismy cel REJECT, ze wskazaniem ze zwrócony ma byc standar5 dowy w takim wypadku komunikat ICMP Port unreachable.

5.6 Konfiguracja dla serwera
O ile stacja robocza moze jawic sie z zewnatrz jako głuchy bastion, o tyle w przypadku serwera musimy dopuscic przynajmniej połaczenia przychodzace na wybrane usługi. Konfiguracja komplikuje sie jeszcze bardziej (pod wzgledem ilosci reguł), jesli usługi te maja byc dostepne tylko z niektórych adresów i tak dalej. Tworzac konfiguracje filtra mozemy oprzec sie o przedstawione wyzej przykłady konfiguracji, dopisujac nowe regułki przed ostatnimi dwoma, blokujacymi wszystko.

5.6.1 Ping
Pierwsza modyfikacja moze byc dopuszczenie pakietów ICMP Echo, czyli popularnego pinga:
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT Tutaj nalezy sie komentarz — o ile czesc administratorów blokuje te usługe, o tyle ja sam jestem zdania, ze jest to polityka przynoszaca wiecej szkody niz pozytku i nie przyczyniajaca sie w znaczacy sposób do poprawienia bezpieczenstwa serwera. Tymczasem ping przydaje sie po prostu do stwierdzania, czy serwer działa i jak długo wedruja do niego pakiety.

5.6.2 Dostep do usług
Kolejnym krokiem jest wpuszczenie połaczen na te serwisy, które maja byc dostepne. W ponizszym przykładzie publicznie (zewszad) dostepne sa serwery SMTP (port 25) oraz WWW (80). Serwer SSH (22) jest dostepny tylko z adresu 192.168.13.2. Przed tym wszystkim jednak blokujemy wszystkie połaczenia z sieci 195.116.130.0/24, poniewaz podejrzewamy jej włascicieli o wysyłanie spamu.
iptables -A INPUT -p tcp -s 195.116.130.0/24 -j DROP
iptables -A INPUT -p tcp -d 0/0 --dport 25 -j ACCEPT
iptables -A INPUT -p tcp -d 0/0 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.13.2/32 -d 0/0 --dport 22 -j ACCEPT
Zamiast numerów portów mozna uzywac oczywiscie nazw z pliku /etc/services, czyli odpowiednio smtp, www i ssh. Przyczyni sie to do poprawienia czytelnosci takiej konfiguracji, ale w przypadku jej przenoszenia na inna instalacje moze spowodowac problemy, jesli plik services nie bedzie kompletny.
Warto uzywac ogólnej specyfikacji adresu docelowego w regułkach, czyli 0/0 (skrócona postac 0.0.0.0/0), chocby ze wzgledu na to ze serwer moze posiadac dodatkowe adresy IP, na które równiez nalezy nałozyc ograniczenia by cały filtr był skuteczny. Wyjatkiem od tej reguły sa systemy bedace równoczesnie routerami, ale o tym napiszemy dalej.

5.6.3 Inne porty
Stosowanie stateful–inspection na serwerze ma jeszcze jedna zalete, przydatna szczególnie na serwerach z kontami shell. Otóz taka konfiguracja skutecznie uniemozliwi uzytkownikom uruchamianie własnych demonów, nasłuchujacych na wysokich portach i robiacych rózne rzeczy, nieraz niepozadane z punktu widzenia bezpieczenstwa (boty, prywatne proxy itp.). Nie stanowi przy tym oczywiscie zadnego problemu otwarcie wysokich portów dla uzytkowników, którzy tego rzeczywiscie potrzebuja.

5.6.4 Moduł unclean
Moduł unclean 6 ma za zadanie wyłapywanie pakietów, które sa niepoprawne w rózny i trudny do sprecyzowania za pomoca standardowych regułek sposób. Moduł ten przeprowadza przetwarzanym pakiecie szereg testów, badajac jego zgodnosc ze standardami, wewnetrzna spójnosc, poprawnosc flag i szereg innych cech. Moduł ten nalezy umiecsic na poczatku listy, na przykład w postaci ponizszych regułek. Pozwoli on wychwycic i zablokowac szereg dotychczas znanych ataków zwiazanych z błedna fragmentacja pakietów i fałszywymi flagami, a takze nowe ataki lub pakiety uszkodzone na łaczach. iptables -A INPUT -j LOG -m limit --limit 10/hour -m unclean
iptables -A INPUT -j DROP -m unclean

5.7 Konfiguracja routerów
W tym przypadku jako router bedziemy rozumiec kazdy host, który posiada wiecej niz jeden interfejs sieciowy i zajmuje sie przesyłaniem pakietów z jednej sieci do drugiej. Host taki moze równoczesnie udostepniac rozmaite usługi ze swojego adresu. Sytuacja taka dodatkowo komplikuje konfiguracje i stawia dodatkowe wymagania w kwestii poprawnego zrozumienia przepływu danych i zaprojektowania ograniczen.
6Uwaga: autorzy modułu ostrzegaja, ze moduł ten ma charakter eksperymentalny i moze nie działac do konca poprawnie. Wyglada na to, ze do kernela 2.4.5 wszystko było dobrze, jednak od wersji 2.4.6 moduł zaczał u mnie błednie ciac poprawne pakiety, przez co ostatecznie musiałem go wyłaczyc.
Główna róznica w tym wypadku bedzie koniecznosc operowania nie tylko na tablicy INPUT, ale i FORWARD, odnoszacej sie do kazdej sytuacji gdy podlegajace filtrowaniu pakiety przechodza pomiedzy róznymi interfejsami. Wymaga to z reguły zdublowania konfiguracji moduług state dla tablicy FORWARD oraz okreslenia dodatkowych reguł dla poszczególnych interfejsów. Nalezy takze pamietac, ze w przypadku routera tablica INPUT moze sie odnosic do kazdego interfejsu i konieczne jest uwzglednianie jego nazwy (lub adresu) w konfiguracji filtra. Nie mozna juz zakładac, ze wszystkie dane przychodza przez jeden interfejs, tak jak w poprzednio rozpatrywanych przypadkach. Z tego samego powodu nalezy rozwaznie stosowac maski globalne (typu 0/0).
Ponizej znajduje sie rozbudowana konfiguracja, oparta o jedna z moich rzeczywistych instalacji. Zawiera ona praktycznie wszystkie opisane powyzej elementy plus dodatkowe elementy, wymagane w tej konkretnej sytuacji (np. NAT). Plik ten ma postac skryptu shella i jest po prostu uruchamiany przy starcie systemu. Komentarze znajduja sie w samym skrypcie 7.
#!/bin/sh
PATH="/sbin:/usr/local/sbin:$PATH"
# Ladujemy modul niezbedne dla RELATED
modprobe ip_conntrack_ftp
iptables -F
iptables -F -t nat
# Przychodzace IDENT odrzucamy z komunikatem ICMP
iptables -A INPUT -p tcp --dport 113 \
-j REJECT --reject-with icmp-port-unreachable
# Interfejs lokalny
iptables -A INPUT -i lo -j ACCEPT
# Wpuszczamy wszystko z LAN
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j ACCEPT
iptables -A FORWARD -i eth1 -s 10.0.0.0/8 -j ACCEPT
# Polaczenia juz nawiazane
iptables -A INPUT -p tcp -j ACCEPT -m state --state ESTABLISHED
iptables -A INPUT -p tcp -j ACCEPT -m state --state RELATED
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 -p icmp -j ACCEPT -m state --state RELATED
iptables -A FORWARD -p tcp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p tcp -j ACCEPT -m state --state RELATED
7Skrypt ten jest równiez dostepny oddzielnie pod adresem
http://arch.ipsec.pl/iptables/router1
iptables -A FORWARD -p udp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p udp -j ACCEPT -m state --state RELATED
iptables -A FORWARD -p icmp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p icmp -j ACCEPT -m state --state RELATED
# POP3 z serwera wewnetrznego wystawiony na zewnatrz za pomoca
# DNAT (odpowiednik dawnego port-forwarding)
# Adres 192.168.13.3 jest adresem zewnetrznym routera, serwer w LAN
# ma adres 10.1.1.241
iptables -t nat -A PREROUTING -p tcp -d 192.168.13.3/32 --dport 110 \
-j DNAT --to-destination 10.1.1.241
# Wpuszczamy ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Serwer DNS jest w publicznej sieci 192.168.14.0/24 podpietej na drugiej
# karcie sieciowej (stanowiacej DMZ)
iptables -A FORWARD -p udp -d 192.168.14.5 --dport 53 -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.14.5 --dport 53 -j ACCEPT
iptables -A INPUT -p tcp -d 217.96.88.194 --dport 22 -j ACCEPT
# Na routerze tez stoi serwer WWW
iptables -A INPUT -p tcp -d 192.168.13.3 --dport 80 -j ACCEPT
# Serwer WWW w DMZ
iptables -A FORWARD -p tcp -d 192.168.14.6 --dport 80 -j ACCEPT
# Serwer FTP w DMZ, otwarte porty dla polaczen pasywnych i aktywnych
iptables -A FORWARD -p tcp -d 192.168.14.4 --dport 21 -j ACCEPT
iptables -A FORWARD -p tcp -s 192.168.14.4 --sport 20 -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.14.4 --dport 40000:44999 -j ACCEPT
# Spammerow nie wpuszczamy
iptables -A INPUT -p tcp -s 195.116.130.0/24 -j DROP
# Dynamiczny NAT dla adresow z sieci wewnetrznej (maskarada)
iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -j MASQUERADEv iptables -A INPUT -j LOG -m limit --limit 10/hour
iptables -A INPUT -j DROP
iptables -A FORWARD -j LOG -m limit --limit 10/hour
iptables -A FORWARD -j DROP

5.8 Filtrowanie ruchu wychodzacego
W dotychczas omówionych przykładach stosowalismy wyłacznie filtrowanie ruchu przychodzacego z interfejsu zewnetrznego, zakładajac milczaco ze ruch wychodzacy z naszej sieci jest godny zaufania. Nie zawsze jest to prawda. Ruch wychodzacy nalezy filtrowac z kilku powodów:
1. System Windows stosowany obecnie najczesciej na stacjach roboczych jest srodowiskiem, w którym bujnie i chetnie kwitnie niewidzialne zycie w postaci wirusów, koni trojanskich oraz spyware 8. Kazde z tych zjawisk osobno powinno byc motywacja do filtrowania ruchu wychodzacego. Łatwo sie o tym przekonac uwaznie obserwujac ruch generowany przez komputery wyposazone w Windows oraz uzytkowników, chetnie zagladajacych na popularne portale, pornosajty i wymieniajacych sie „smiesznymi” programami.
2. W razie udanego wykorzystania dziury w jednym z naszych serwerów filtrowanie ruchu wychodzacego moze uniemozliwic włamywaczowi faktyczne skorzystanie z otwartej furtki. Sprytny złoczynca moze obejsc nasze filtry przychodzace konstruujac exploit tak, by to nasz serwer połaczył sie z wybrana przez niego maszyna i wystawił mu shell. Filtrowanie połaczen wychodzacym w najgorszym wypadku mu to utrudni, w najlepszym uniemozliwi.
3. Nalezy brac pod uwage, ze nasza siec stanie sie nie tylko celem, ale zródłem ataku na inne serwery. Dotyczy to w szczególnosci sieci dostawców internetowych i innych rozbudowanych sieci, z których korzystaja nieraz zupełnie obcy uzytkownicy. Filtrowanie ruchu wychodzacego moze utrudnic wiele tego rodzaju ataków, a w praktyce wyeliminowac mozliwosc ze nasza siec stanie sie zródłem ataków wykorzystujacych IP spoofing. Przykładowy, dosc rozbudowany skrypt realizujacy takie filtrowanie jest zamieszczony ponizej 9.
#!/bin/sh # Przykladowa, restrykcyjna konfiguracja iptables dla Linuxa 2.4.
# Ten skrypt zawiera rowniez funkcje zmniejszajace szanse odciecia
# sobie dostepu do danego hosta podczas zdalnej konfiguracji.
# Pawel Krawczyk 2001
# Opcje skryptu:
# flush - czysci wszystkie regulki i ustawia otwarta polityke
# temp - konfiguruje tymczasowe regulki (patrz ponizej)
# bez opcji - konfiguruje iptables
# Kolejnosc operacji:
# 1. zerowanie wszystkich tablic
8Oprogramowanie w mniej lub bardziej zawoalowany sposób szpiegujace dany komputer i wysyłajace rozmaite infomacje do serwerów producenta, najczesniej na wysokich portach i własnymi protokołami. 9Jest on równiez dostepny jako samodzielny plik pod adresem http://arch.ipsec.pl/iptables/shivling
# 2. ustawienie restrykcyjnej polityki DROP
# 3. ustawienie specjalnego dostepu dla interfejsu lo
# 4. ustawienie specjalnego dostepu dla sieci LAN
# 5. konfiguracja modulu unclean
# 6. ustawienie odrzucania polaczen dla IDENT i SOCKS
# 7. zezwolenie dla pakietow ICMP Echo (ping)
# 8. konfiguracja stateful-inspection (modul state)
# 9. ustawienie dostepu dla konkresnych uslug
# 10. konfiguracja NAT i PAT
# 11. konfiguracja logowania zablokowanych pakietow
export PATH=""
iptables_flush()
{
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -F
}
if [ "$1" = "flush" ]; then
iptables_flush
exit 0
fi
# Bezpieczne wywolanie iptables, gwarantujace ze
# nasze regulki zostana zaladowane albo w calosci
# albo w ogole. Zapobiega to sytuacji, kiedy tracimy
# dostep do danego hosta z powodu jednej, zle skonstruowanej
# regulki ktora miala nas do niego wpuszczac ;)
iptables() {
echo -n .
/sbin/iptables $@
if [ "$?" != "0" ]; then
iptables_flush
exit 1
fi
}
# Mozemy wlaczyc nasze nowe regulki tylko na chwile.
# Pozwala to sprawdzic, czy po ich uzupelnieniu nadal
# mamy dostep do hosta, jesli nie to automatycznie
# odzyskamy go po 30 sekundach. Skrypt nalezy tylko
# wywolac z opcja "temp".
if [ "$1" = "temp" ]; then
(sleep 30; /sbin/iptables -P INPUT ACCEPT ;\
/sbin/iptables -P OUTPUT ACCEPT ;\
/sbin/iptables -P FORWARD ACCEPT ;\
/sbin/iptables -F) &
fi
echo -n "Installing IPtables ruleset"
# Ladujemy modul stateful-inspection dla FTP
5 LINUX 16
/sbin/modprobe ip_conntrack_ftp
# Czyscimy wszystkie tablice
iptables -F
iptables -F -t nat
# Domyslnie nie przepuszczamy nic
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Interfejs lokalny ma specjalne prawa
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A FORWARD -o lo -j ACCEPT
# Wpuszczamy wszystko z sieci lokalnej i wypuszczamy
# wszystko na nia. Nie nalezy dodawac tutaj analogicznej
# regulki dla FORWARD, to zalatwi za nas modul state
iptables -A INPUT -i eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j ACCEPT
# Logujemy pakiety wyblokowane przez modul unclean
# *** Tymczasowo wylaczone z powodu problemow z unclean w Linuxie 2.4.6
#iptables -A INPUT -j LOG -m limit --limit 10/hour -m unclean
#iptables -A INPUT -j DROP -m unclean
#iptables -A OUTPUT -j LOG -m limit --limit 10/hour -m unclean
#iptables -A OUTPUT -j DROP -m unclean
#iptables -A FORWARD -j LOG -m limit --limit 10/hour -m unclean
#iptables -A FORWARD -j DROP -m unclean
# Odrzucamy z komunikatem ICMP Port Unreachable polaczeniav # na IDENT oraz SOCKS (czesto sprawdzane przez serwery IRC)
iptables -A INPUT -p tcp --dport 113 \
-j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p tcp --dport 1080 \
-j REJECT --reject-with icmp-port-unreachable
# Akceptujemy pakiety ICMP Echo (ping) wchodzace i wychodzace
# Akceptacja odpowiedzi jest realizowana przez modul state RELATED
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -j ACCEPT
# Zezwalamy na wszystko co odbywa sie w ramach juz dozwolonych
# polaczen
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 -p icmp -j ACCEPT -m state --state RELATED
iptables -A FORWARD -p tcp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p tcp -j ACCEPT -m state --state RELATED
iptables -A FORWARD -p udp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p icmp -j ACCEPT -m state --state ESTABLISHED
iptables -A FORWARD -p icmp -j ACCEPT -m state --state RELATED
iptables -A OUTPUT -p tcp -j ACCEPT -m state --state ESTABLISHED
iptables -A OUTPUT -p tcp -j ACCEPT -m state --state RELATED
iptables -A OUTPUT -p udp -j ACCEPT -m state --state ESTABLISHED
iptables -A OUTPUT -p icmp -j ACCEPT -m state --state ESTABLISHED
iptables -A OUTPUT -p icmp -j ACCEPT -m state --state RELATED
# Indywidualne regulki akceptujace okreslone porty lub serwery
# Zalecana jest jak najwieksza szczegolowosc tych regulek,
# w razie problemow nalezy posilkowac sie regulkami LOG
# czat.onet.pl
iptables -A OUTPUT -o ppp0 -p tcp -j ACCEPT -m state --state NEW \
-d 213.180.130.190 -m multiport --destination-port 5012,5013
iptables -A FORWARD -o ppp0 -p tcp -j ACCEPT -m state --state NEW \
-d 213.180.130.190 -m multiport --destination-port 5011,5012,5013
# Uslugi TCP, ktore wypuszczamy z naszej sieci:
# 80,8080 (WWW), 22 (SSH), 21 (FTP), 25 (SMTP), 119 (news), 53 (DNS)
# 8888 (Napster), 2064 (distributed.net), 706 (SILC)
TCP_OUT_ALLOW=80,8080,22,995,21,25,53,23,119,8888,2064,6667,706
# Uslugi UDP: 123 (NTP), 53 (DNS)
UDP_OUT_ALLOW=123,53
iptables -A OUTPUT -o ppp0 -p tcp -j ACCEPT -m state --state NEW \
-m multiport --destination-port $TCP_OUT_ALLOW
iptables -A OUTPUT -o ppp0 -p udp -j ACCEPT -m state --state NEW \
-m multiport --destination-port $UDP_OUT_ALLOW
iptables -A FORWARD -o ppp0 -p tcp -j ACCEPT -m state --state NEW \
-m multiport --destination-port $TCP_OUT_ALLOW
iptables -A FORWARD -o ppp0 -p udp -j ACCEPT -m state --state NEW \
-m multiport --destination-port $UDP_OUT_ALLOW
# Przerzucamy port 6699 (Napster) z zewnetrznego interfejsu
# na host w sieci lokalnej (10.1.1.3). Znane jako port
# forwarding lub Port Address Translation
iptables -t nat -A PREROUTING -p tcp -d 251.61.252.110/32 --dport 6699 \
-j DNAT --to-destination 10.1.1.3
# Maskarada (NAT) dla wszystkich hostow z sieci lokalnej
iptables -t nat -A POSTROUTING -p all -s 10.1.1.0/24 -j MASQUERADE
# Logujemy pakiety ktore nie zostaly zaakceptowane przez
# zadna z powyzszych regulek. Zostana one wyblokowane dzieki
# polityce DROP we wszystkich tablicach
iptables -A INPUT -j LOG -m limit --limit 10/hour
iptables -A OUTPUT -j LOG -m limit --limit 10/hour
iptables -A FORWARD -j LOG -m limit --limit 10/hour
echo .

5.9 Jeszcze o ruchu wychodzacym
Powyzsza konfiguracja jest dostosowana tak na prawde do nieduzej sieci, ukrytej za maskarada i w domysle zaufanej. Stad brak filtrowania ruchu przychodzacego z sieci lokalnej, które własciwie nalezałoby wprowadzic dla unikniecia ataków IP spoofing. Po pierwsze, mozna stworzyc Filtrowac nalezy przede wszystkim ruch, co do którego jestesmy pewni ze nie moze byc legalny. Na przykład pakiet z adresem zródłowym spoza naszej sieci, który nagle próbuje sie wydostac przez nasz router od strony LAN — cos takiego nie ma prawa zaistniec w legalnym ruchu i najprawdopodobniej jest jakims wariantem spoofingu. Analogicznie maja sie sprawy, gdy od strony WAN przyjdzie do nas pakiet z adresem zródłowym nalezacym do naszej sieci lokalnej.
Filtrowanie takie mozna zrealizowac co najmniej na dwa sposoby. Pierwszy z nich to stworzenie odpowiednich regułek. Załózmy, ze 200.117.223.0/24 to nasz LAN, a na swiat wychodzimy przez interfejs ppp0:
iptables -A FORWARD -s 200.117.223.0/24 -i ppp0 -j DROP
iptables -A FORWARD -s ! 200.117.223.0/24 -o eth0 -j DROP
Druga, prostsza metoda to wykorzystanie wbudowanego w Linuxa mechanizmu filtrowania takich oczywistych fałszerstw. Jest to mechanizm wprost zalecany przez RFC 1812 10 i właczany łatwo za pomoca intefejsu sysctl:
# echo 1 >/proc/sys/net/ipv4/conf/all/rp_filter
Wiele dystrybucji Linuxa posiada te funkcje, ukryta pod róznymi nazwami. Jest ona dostepna juz od kerneli 2.2 11.

5.10 Inne ciekawe funkcje
Filtr iptables posiada równiez kilka dosc interesujacych i niespotykanych do tej pory funkcji, które moga okazac sie bardzo przydatne w mniej typowych konfiguracjach.
Nowoscia jest filtrowanie po adresach sprzetowych kart sieciowych dostepne w module mac. Klepania zaoszczedzi moduł multiport pozwalajacy na podanie w jednej regułce kilku róznych portów (dotychczas mozna było podac albo pojedynczy port albo ciagły zakres).
10 F. Baker „Requirements for IPv4 routers” http://www.ietf.org/rfc/rfc1812.txt
11W kernelach 2.2 nalezy uzyc wartosci 2, a nie 1.
Interesujaca funkcja jest mozliwosc filtrowania pakietów na podstawie konkretnego uzytkownika lub grupy za pomoca modułu owner. Jest to oczywiscie mozliwe tylko w przypadku pakietów generowanych w lokalnym systemie, ale daje ogromne mozliwosci jesli chodzi o ograniczanie dostepu do sieci na serwerach, gdzie konta maja osoby niezaufane. Mozna równiez w ten sposób zmniejszyc ryzyko uruchomienia w systemie tylnej furtki w razie błedów w okreslonych aplikacjach serwerowych, na przykład zezwalajac uzytkownikowi apache wyłacznie na wysyłanie pakietów z portu 80. Mozliwosci jest wiele, zapraszam do nadsyłania własnych pomysłów i wdrozen. W tym artykule nie zostały takze omówione inne opcje iptables, których nie miałem okazji uzywac i nie wydawały mi sie wyjatkowo interesujace. Dobre opisy funkcjonalnosci filtra mozna znalezc w dokumentacji, opisanej ponizej.

5.11 Dokumentacja
• http://netfilter.samba.org/ Główna strona projektu netfilter/iptables, wraz z kodem zródłowym oraz podrecznikami.
• http://www.boingworld.com/workshops/linux/iptables-tutorial/ „Linux IPtables tutorial”
• iptables(8) Strona manuala systemowego poswiecona programowi iptables.
Omawiany tutaj filtr ipfilter (ipf) jest obecny we wszystkich systemach z rodziny BSD (FreeBSD, NetBSD i OpenBSD. W dwóch ostatnich stanowi jedyny systemowy filtr pakietów, instalowany domyslnie. Ipf jest takze dostepny dla innych systemów, np. dla Solarisa. Moim zdaniem jest to jeden z najlepszych i najelastyczniejszych filtrów pakietowych. Niestety w maju 2001 pomiedzy autorem, którym jest Darren Reed z Australii, a twórcami OpenBSD doszło do konfliktu na tle licencji filtra i od kolejnych wersji tego systemu nie bedzie on dostepny natywnie. W przypadku FreeBSD i NetBSD nic sie jednak nie zmieniło, a w dwa miesiace pózniej po tym jak OpenBSD usuneło filtr ze swojego systemu Darren ponownie zmienił licencje, tym razem na liberalna i usuwajaca wszystkie wczesniejsze ograniczenia. Zasadnicza cecha, która wyróznia ipf od innych filtrów pakietowych jest kolejnosc przetwarzania reguł. W wiekszosci filtrów sa one przegladane kolejno, od góry do dołu listy i pierwsza, która pasuje jest wykonywana, konczac tym samym przetwarzanie listy. W przypadku ipf wyglada to nieco inaczej — zawsze przegladana jest cała lista reguł i ostatnia z nich, która pasowała do aktualnego pakietu jest wykonywana. Ponizej opisany przykład ma za zadanie uwypuklenie róznic pomiedzy ipf, a wczesniej opisywanym iptables. Podstawy teoretyczne działania obu filtrów sa jednak zblizone, dlatego zwolenników ipf równiez namawiam do przeczytania teoretycznych fragmentów rozdziałów poswieconych Linuksowi.

6.1 Najprostszy przykład
Interfejsy sieciowe w BSD biora nazwy od konkretnych modeli kart — ponizsze przykłady wykorzystuja interfejs fxp0, czyli w rzeczywistosci karte Intel EtherExpress/100.
### FXP0 Internet
block in log on fxp0 from any to any
# Zwracamy RST w odpowiedzi na zadania IDENT
block return-rst in quick on fxp0 proto tcp from any \
to any port = 113 flags S/S
# Wypuszcamy wszystkie polaczenia wychodzace z "keep state"
pass out quick on fxp0 proto tcp from any to any keep state
pass out quick on fxp0 proto udp from any to any keep state
pass out quick on fxp0 proto icmp from any to any keep state
Widac tutaj zasadnicza róznice w działaniu filtra ipf, jaka jest brak wyraznego rozróznienia pomiedzy poszczególnymi kierunkami ruchu, tak jak to było w przypadku iptables. W powyzszym przykładzie blokujemy cały ruch przychodzacy, poza pakietami nalezacymi do połaczen zainicjowanych z tego hosta. Sa one wpuszczane przez filtr stateful–inspection, właczony flaga keep state. Przykłady dla ipf beda rozbudowywane w miare uzupełniania tego artykułu.

7.1 Uwagi koncowe
Konfiguracje przedstawione w przykładach nie sa kompletne. Mam nadzieje, ze pomogły Ci one zrozumiec działanie filtrów stateful–inspection i beda punktem wyjscia do tworzenia skutecznych zapór. Najskuteczniejsza w tym wypadku strategia jest tworzenie konfiguracji maksymalnie restrykcyjnej i uwazne obserwowanie logów systemowych. Kazdy zablokowany pakiet nalezy przeanalizowac i — jesli okaze sie ze był on wysyłany legalnie — rozszerzyc filter o regułe przepuszajaca ten rodzaj ruchu. Zdaje sobie sprawe, ze mogłem popełnic w tym artykule błedy, rzeczowe i inne, w takim wypadku bede wdzieczny za ich wskazanie. Komentarze oraz uzupełnienia sa równiez mile widziane, znajda sie one w kolejnych wersjach tego dokumentu.