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.