Ściany ogniowe oparte o IP Filter Brendan Conoboy, synk@swcp.com Erik Fichtner, emf@obfuscation.org Wersja oryginalna: Fri Mar 1 22:29:33 EST 2002

Oryginał tego dokumentu znajduje się pod adresem:

Tłumaczenie: Łukasz Bromirski, l.bromirski@mr0vka.eu.org Wersja tłumaczenia: 3.0, 2002/09/03 14:38:15

Oryginał tłumaczenia znajduje się pod adresem:

Dokument ten jest pomyślany jako wprowadzenie dla nowych użytkowników paczki IP Filter tworzącej ścianę ogniową. Jednocześnie, ma nauczyć użytkownika niektórych fundamentalnych zasad projektowania dobrych ścian ogniowych. Wprowadzenie Podstawy ścian ogniowych

Tą sekcję napisaliśmy tak, by zapoznać się ze składnią poleceń ipfilter, oraz teorią ścian ogniowych w ogólności. Możliwości które tu opisano znajdziesz w każdej dobrej paczce ściany ogniowej. Ta sekcja da Ci solidne podstawy, tak by lektura i zrozumienie sekcji zaawansowanej było bardzo łatwe. Należy podkreślić, że przeczytanie tylko tej sekcji nie wystarczy do zbudowania dobrej ściany ogniowej, a zapoznanie się z sekcją zaawansowaną jest absolutnie wymagana dla każdego kto chce zbudować efektywny system bezpieczeństwa.

Dynamika pliku konfiguracyjnego i kolejność

IPF ( Filtr IP ) posiada plik konfiguracyjny ( w przeciwieństwie do trybu pracy w której uruchamia się cały czas komendy dla każdej nowej reguły ). Plik konfiguracyjny jest zgodny z filozofią Unixa: każda nowa linia to reguła, znak '#' oznacza komentarz, możesz również wpisać regułę i po niej komentarz w jednej linii. Oczywiście dozwolone są również nadmiarowe spacje, a nawet poleca się je by zestawy reguł był czytelniejszy.

Podstawy przetwarzania reguł

Reguły przetwarzane są z góry na dół, każda dodawana po poprzedniej. Oznacza to po prostu, że jeśli cały Twój plik konfiguracyjny wygląda tak: block in all pass in all ...komputer widzi go jako: block in all pass in all Co oznacza, że po otrzymaniu pakietu, IPF najpierw stosuje regułę: block in all Jeśli IPF uzna, że należy przejść do następnej reguły, zinterpretuje ją: pass in all

W tym momencie możesz zadać sobie pytanie "a uzna, że należy przejść do następnej reguły?". Jeśli znany jest ci ipfwadm czy ipfw, prawdopodobnie nie zadasz sobie tego pytania. Potem będziesz mocno zdziwiony, dlaczego pakiety są odrzucane lub przepuszczane, podczas gdy wskazałeś inaczej. Wiele filtrów pakietów przestaje porównywać pakiety w momencie, gdy znajdą pierwszą regułę która pasuje. IPF nie jest jednym z nich.

Odmiennie, niż w przypadku innych filtrów pakietów, IPF utrzymuje flagę czy przepuścić pakiet czy nie. Dopóki nie przerwiesz porównywania, IPF sprawdzi cały zestaw reguł i podejmie decyzję czy przepuścić pakiet czy nie, na podstawie ostatniej pasującej reguły. Wygląda to tak: IPF pracuje. Dostał kawałek czasu procesora. Ma przed sobą listę do sprawdzenia, która wygląda tak: block in all pass in all Do interfejsu dociera pakiet i trzeba zabrać się do pracy. Pobiera pakiet i sprawdza pierwszą regułę: block in all IPF stwierdza "Jak na razie, zablokuję ten pakiet". Następnie ogląda drugą regułę: pass in all "Jak na razie, wpuszczę ten pakiet", stwierdza IPF. Potem patrzy na trzecią regułę. Nie ma jej, więc sprawdza jaką decyzję podjął ostatnio - przepuścić pakiet.

W tym momencie nadszedł dobry moment by zauważyć, że nawet gdyby zestaw reguł wyglądał tak: block in all block in all block in all block in all pass in all To i tak pakiet zostałby przepuszczony. Nie istnieje tutaj coś takiego jak efekt kumulacyjny. Ostatnia pasująca reguła zawsze decyduje o losie pakietu.

Kontrolowanie przetwarzania reguł

Jeśli miałeś już do czynienia z innymi filtrami pakietów, możesz stwierdzić że ten sposób organizacji przetwarzania jest mylący, możesz również spekulować że istnieją problemy z przenoszalnością do innych filtrów oraz, że prędkość przetwarzania reguł może być mała. Wyobraź sobie że masz 100 reguł i wszystkie pasujące były pierwszymi 10. Dla każdego pakietu sprawdzenie pozostałych reguł byłoby wielką stratą czasu. Na szczęście, istnieje proste słowo kluczowe które możesz dodać do reguły by od razu spowodować reakcję. Tym słowem jest quick.

Poniżej przedstawiono zmodyfikowaną wersję oryginalnego zestawu, tym razem z nową komendą. block in quick all pass in all W tym przypadku, IPF sprawdza pierwszą regułę: block in quick all Pakiet pasuje i przeglądanie reguł na nim się kończy. Pakiet zostaje odrzucony bez żadnego piśnięcia. Nie ma żadnych komunikatów, logów, konduktu pogrzebowego. Ciasto nie zostanie podane. Co więc z następną regułą? pass in all Do tej reguły IPF nigdy nie dociera. Mogłoby jej w ogóle nie być w pliku konfiguracyjnym. Działanie reguły all i słowo quick w poprzedniej regule powoduje, że nie są już sprawdzane żadne inne reguły.

Sytuacja w której połowa pliku konfiguracyjnego do niczego się nie przydaje, jest raczej stanem niepożądanym. Z drugiej strony, IPF ma za zadanie powstrzymywać pakiety tak jak został skonfigurowany, i robi bardzo dobrą robotę. Tak czy inaczej, IPF jest również po to by niektóre pakiety przepuszczać, więc wymagana jest pewna zmiana reguł by to zadanie zrealizować.

Podstawy filtrowania po adresie IP

IPF może sprawdzać pakiety pod kątem wielu kryteriów. Jednym z tych o których myślimy najczęściej jest adres IP. Istnieją pewne zakresy przestrzeni adresowej z których nigdy nie powinniśmy otrzymywać żadnych pakietów. Jednym z takich zakresów jest sieć nieroutowalna, 192.168.0.0/16 ( /16 to zapis maski w postaci CIDR. Możesz być bardziej przyzwyczajony do zapisu decymalnego, 255.255.0.0 - IPF akceptuje obydwa ). Jeśli chciałbyś zablokować 192.168.0.0/16, jednym ze sposobów jest: block in quick from 192.168.0.0/16 to any pass in all Tym razem mamy w końcu zestaw reguł który coś dla nas robi. Wyobraźmy sobie, że dociera do nas pakiet z adresu 1.2.3.4. Sprawdzana jest pierwsza reguła: block in quick from 192.168.0.0/16 to any Pakiet przyszedł z adresu 1.2.3.4 a nie z 192.168.*.*, więc reguła nie pasuje. Sprawdzana jest druga reguła: pass in all Pakiet przyszedł z adresu 1.2.3.4, który zdecydowanie należy do all ( czyli dowolnego adresu ), więc jest wysyłany tam gdzie chciałby dotrzeć.

Z drugiej strony, przypuśćmy że otrzymaliśmy pakiet z adresu 192.168.1.2. Sprawdzana jest pierwsza reguła: block in quick from 192.168.0.0/16 to any Pakiet pasuje, więc jest odrzucany i to koniec. Ponownie, IPF nie sprawdza drugiej reguły, ponieważ pierwsza reguła która pasowała, zawierała słowo quick.

W tym momencie możesz zbudować rozszerzalny zestaw adresów, z których niektóre należy zablokować a niektóre przepuścić. Ponieważ już zaczęliśmy blokować zakresy adresów prywatnych na naszej ścianie ogniowej, zadbajmy o resztę: block in quick from 192.168.0.0/16 to any block in quick from 172.16.0.0/12 to any block in quick from 10.0.0.0/8 to any pass in all Pierwsze trzy reguły blokują niektóre z zakresów adresów prywatnych.

Kontrola interfejsów

Często zdarza się, że firmy mają najpierw sieć wewnętrzną, zanim zechcą podłączyć się do świata zewnętrznego. Tak naprawdę, sensowne wydaje się założenie, że to główny powód dla którego ludzie w ogóle rozważają ściany ogniowe. Maszyna, która pełni rolę mostu ( ang. bridge ) między siecią wewnętrzną a siecią zewnętrzną jest routerem. Router od każdej innej dowolnej maszyny różni jedna podstawowa cecha: ma więcej niż jeden interfejs.

Każdy pakiet który otrzymujesz, przychodzi którymś interfejsem sieciowym; każdy pakiet który wysyłasz wychodzi również interfejsem sieciowym. Powiedzmy że masz trzy interfejsy: pętlę zwrotną - lo0 ( ang. loopback ), xl0 ( kartę ethernetową 3COM ) i tun0 ( podstawowy tunel we FreeBSD którego używa PPP ), ale nie chcesz otrzymywać pakietów przychodzących z interfejsu tun0? block in quick on tun0 all pass in all

W tym przypadku słowo on oznacza identyfikację danych przybywających wskazanym interfejsem. Jeśli pakiet przychodzi do interfejsu tun0 ( 'on tun0' ), pierwsza reguła go zablokuje. Jeśli pakiet przyjdzie do interfejsu lo0 lub xl0, pierwsza reguła nie będzie pasowała, a druga tak i pakiet zostanie przepuszczony.

Jednoczesne użycie adresu IP i nazwy interfejsu

To dziwny stan, w którym decydujesz, że chcesz mieć interfejs podniesiony ( w naszym przypadku tun0 ), ale nie chcesz otrzymywać przez niego pakietów. Czym więcej jest kryteriów które sprawdza ściana ogniowa, tym jest bardziej szczelna ( lub przeciekająca ). Może chcesz otrzymywać dane przez tun0, ale nie od 192.168.0.0/16? To początek potężnej ściany ogniowej. block in quick on tun0 from 192.168.0.0/16 to any pass in all Porównaj to do naszego poprzedniego zestawu reguł: block in quick from 192.168.0.0/16 to any pass in all Blokujemy w nim każdy ruch pochodzący z 192.168.0.0/16, niezależnie od interfejsu. W nowym zestawie reguł, w którym używamy słów 'on tun0' blokujemy tylko pakiety, które dotarły przez interfejs tun0. Gdyby pakiet przybył interfejsem xl0 zostałby wpuszczony.

W tym momencie możesz zbudować rozszerzalny zestaw adresów, z których niektóre należy zablokować a niektóre przepuścić. Ponieważ już zaczęliśmy blokować zakresy adresów prywatnych które docierają do interfejsu tun0, zajmijmy się resztą: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any pass in all Widziałeś już pierwsze trzy reguły, ale nie resztę. Czwarta wskazuje klasę A, w większości zmarnowaną, a używaną głównie na pętle zwrotne. Wiele oprogramowania komunikuje się ze sobą przez adres 127.0.0.1, więc zablokowanie tego adresu przy połączeniach z zewnątrz to też dobry pomysł. Piąta linia, 0.0.0.0/8 nigdy nie powinna znaleźć się w Internecie. Większość stosów IP traktuje 0.0.0.0/32 jako domyślną bramę, a reszta sieci 0.*.*.* jest traktowana na różne dziwne sposoby, co wynika ze sposobu w jaki podejmowane są decyzję o routingu. Powinieneś traktować 0.0.0.0/8 tak jak 127.0.0.0/8. 169.254.0.0/16 zostało przydzielone przez IANA do użytku w procesie auto-konfiguracji, kiedy system nie otrzymał jeszcze adresu IP z serwera DHCP lub podobnego. Należy zwrócić uwagę, że w szczególności Microsoft Windows będą używać adresów z tego zasięgu gdy ustawione są na używanie DHCP a nie były w stanie znaleźć do tej pory serwera DHCP. 192.0.2.0/24 został również zarezerwowany dla użytku autorów dokumentacji jako przykład dzielenia na bloki. Celowo nie używamy tego zakresu, ponieważ mógłby on spowodować zamieszanie gdybyś je zablokował; wszystkie nasze przykłady używają adresów 20.20.20.0/24. 204.152.64.0/23 to blok zarezerwowany przez Sun Microsystems dla prywatnych połączeń klastrów, i zablokowanie go pozostawiamy tobie pod rozwagę. Na koniec, 224.0.0.0/3 wycina klasy D i E sieci, która używana jest głównie do ruchu multicastowego ( rozgłaszania ). Dokładniejsze definicje `klasy E' możecie znaleźć w RFC 1166.

Istnieje bardzo ważna zasada w filtrowaniu pakietów, która była odraczana do momentu omówienia blokowania sieci i brzmi ona: w momencie gdy wiesz, że określony typ danych dociera z określonych miejsc, konfigurujesz system by zezwolić tylko na ruch tego typu danych z tych określonych źródeł. W przypadku klasy nieroutowalnej, wiesz że nic z 10.0.0.0/8 nie powinno docierać do ciebie przez tun0, ponieważ nie masz żadnego sposobu by na niego odpowiedzieć. Jest to pakiet nielegalny. Tak samo należy traktować inne nieroutowalne adresy, jak również 127.0.0.0/8.

Wiele oprogramowania, dokonuje uwierzytelniania na podstawie źródłowego adresu IP. Jeśli posiadasz sieć wewnętrzną, powiedzmy 20.20.20.0/24, wiesz że cały ruch dla tej sieci może wychodzić przez lokalny ethernet. Gdyby pakiet z 20.20.20.0/24 dotarł przez połączenie PPP, jest absolutnie sensownym zrzucić go na podłogę, albo umieścić w ciemnym pokoju przesłuchań. Nie powinien w żaden sposób móc osiągnąć swojego celu. Możesz to osiągnąć stosując to co już wiesz o IPF. Nowy zestaw reguł wyglądać będzie tak: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in quick on tun0 from 20.20.20.0/24 to any pass in all Filtrowanie dwukierunkowe; Słowo kluczowe `out'

Do tej pory przepuszczaliśmy lub blokowaliśmy ruch przychodzący. By wyjaśnić, ruch przychodzący to cały ruch, który dociera do ściany ogniowej na dowolnym interfejsie. Analogicznie, ruch wychodzący to cały ruch, który ma zamiar opuścić interfejs ściany ogniowej ( obojętnie czy wygenerowany lokalnie czy tylko przekazywany ). Oznacza to, że wszystkie pakiety są filtrowanie nie tylko gdy docierają do ściany ogniowej, ale również w momencie jej opuszczania. W związku z tym implikuje to komendę `pass out all', która może lub może nie być pożądana. Tak samo jak możesz przepuszczać lub blokować ruch wchodzący, możesz robić to samo z ruchem wychodzącym.

Teraz gdy wiemy że istnieje sposób by filtrować zarówno ruch wychodzący jak i wchodzący, sami musimy znaleźć sensowne zastosowanie dla czegoś takiego. Jednym z możliwych pomysłów, jest powstrzymywanie sfałszowanych ( ang. spoofed ) pakietów przed wchodzeniem do Twojej sieci. Zamiast wypuszczać na ruterze cały ruch, ograniczymy go tylko do pakietów pochodzących z 20.20.20.0/24. Możesz to zrobić w ten sposób: pass out quick on tun0 from 20.20.20.0/24 to any block out quick on tun0 from any to any Jeśli pakiet przyjdzie z 20.20.20.1/32, zostanie przepuszczony przez pierwszą regułę. Jeśli pakiet przyjdzie z 1.2.3.4/32, zostanie zablokowany przez regułę drugą.

Możesz również wykonać podobne reguły dla adresów nieroutowalnych. Jeśli jakaś maszyna próbuje skierować pakiet przez IPF do 192.168.0.0/16, dlaczego by go nie odrzucić? Najgorsze co może się stać to to, że zaoszczędzisz trochę przepustowości: block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 204.152.64.0/23 block out quick on tun0 from any to 224.0.0.0/3 block out quick on tun0 from !20.20.20.0/24 to any

Z najbardziej ograniczonego punktu widzenia, zapis ten nie rozszerza Twojego bezpieczeństwa. Rozszerza natomiast bezpieczeństwo wszystkich innych i jest generalnie miłą rzeczą do zrobienia. Z drugiej strony, ktoś może stwierdzić, że skoro nie może rozsyłać sfałszowanych pakietów przez Twoją sieć, masz mniejsze znaczenie jako punkt przekaźnikowy dla cracker'ów i w związku z tym prawdopodobieństwo, że staniesz się celem ataku maleje.

Prawdopodobnie znajdziesz wiele sposobów użycia blokowania pakietów wychodzących. Jedną z rzeczy o których zawsze należy pamiętać, to fakt, że `in' i `out' są kierunkami odnoszącymi się do ściany ogniowej, nigdy w stosunku do dowolnej innej maszyny.

Logowanie tego co się dzieje; Słowo kluczowe `log'

Do tego momentu, całe blokowanie i przepuszczanie pakietów odbywało się w całkowitej ciszy. Zwykle chcesz jednak wiedzieć, że jesteś atakowany, a nie zastanawiać się czy ta ściana ogniowa w ogóle Ci coś daje. Podczas gdy nie logowałbym każdego pakietu który został przepuszczony i w niektórych przypadkach wszystkich blokowanych pakietów, chciałbym wiedzieć parę rzeczy o blokowanych pakietach z 20.20.20.0/24. By to wykonać, dodajemy słowo kluczowe `log': block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any pass in all Do tej pory ściana ogniowa robi dobrą robotę blokując pakiety nadchodzące z podejrzanych miejsc, ale jest jeszcze trochę do zrobienia. Jedną z rzeczy o którą powinniśmy zadbać, jest by pakiety do 20.20.20.0/32 i 20.20.20.255/32 były zrzucane na podłogę. Jeśli tego nie zrobimy, otwieramy naszą sieć na atak typu smurf. Te dwie linie zabezpieczą naszą hipotetyczną sieć przed użyciem jako przekaźnik smurf: block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32

Dodanie tych linijek, doprowadza nas do zestawu reguł wyglądającego mniej więcej tak: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all

Kompletne filtrowanie dwukierunkowe według interfejsu

Do tej pory przedstawialiśmy jedynie fragmenty kompletnego zestawu reguł. W momencie gdy tworzysz swój zestaw, powinieneś utworzyć reguły dla każdego kierunku i interfejsu. Domyślnie ipfilter przepuszcza wszystkie pakiety . Jest to sytuacja analogiczna do tej, w której istnieje niewidoczna reguła na początku która brzmi `pass in all' i `pass out all'. Zamiast polegać na domyślnym zachowaniu, zadbaj by wszystko było tak dokładne i konkretne jak to możliwe, interfejs po interfejsie, do momentu w którym każda ewentualność zostanie rozpatrzona.

Zaczniemy od interfejsu lo0, który będzie pracował bez ograniczeń. Ponieważ istnieją programy rozmawiające z innymi na systemach lokalnych, zezwalamy na to i utrzymujemy ten stan bez żadnych restrykcji: pass out quick on lo0 pass in quick on lo0 Następny jest interfejs xl0. Później będziemy nakładać ograniczenia na interfejs xl0, ale na początek zaczniemy tak jakby wszystko w naszej sieci lokalnej było warte zaufania i damy interfejsowi dokładnie to samo co w przypadku lo0: pass out quick on xl0 pass in quick on xl0 Na koniec, jest również interfejs tun0, który do tej pory filtrowaliśmy tylko połowicznie: block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 204.152.64.0/23 block out quick on tun0 from any to 224.0.0.0/3 pass out quick on tun0 from 20.20.20.0/24 to any block out quick on tun0 from any to any block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all Mamy już dosyć dużo filtrowania, zabezpieczamy sieć 20.20.20.0/24 przed fałszowaniem pakietów i przed używaniem do fałszowania pakietów. Kolejne przykłady będą oparte na jednostronnym podejściu, ale miej na uwadze że to tylko dla jasności, a kiedy będziesz konfigurował swój własny zestaw reguł, musisz dodawać reguły dla każdego kierunku i interfejsu.

Kontrolowanie konkretnych protokołów; Słowo kluczowe `proto'

Ataki Odmowy Usługi ( ang. Denial of Service lub DoS ) są równie częste co exploity związane z przepełnieniem bufora ( ang. buffer overflow ). Wiele ataków DoS związanych jest z zawiłościami stosu TCP/IP systemu operacyjnego. Często, sprowadzało się to do pakietów ICMP. Dlaczego nie zablokować ich w ogóle? block in log quick on tun0 proto icmp from any to any W tym momencie każdy pakiet ICMP nadchodzący przez tun0 będzie logowany i odrzucany.

Filtrowanie ICMP z użyciem słowa kluczowego `icmp-type'; Łączenie zestawów reguł

Oczywiście, odrzucanie całego ruchu ICMP nie jest idealną sytuacją. Dlaczego nie? Ponieważ lepiej i użyteczniej jest, gdy na ruch pakietów tego protokółu zezwalamy przynajmniej po części. Zapewne zatem będziesz chciał przepuszczać pewne rodzaje ruchu ICMP a odrzucać inne. Jeśli chcesz by działały traceroute i ping, musisz przepuszczać pakiety ICMP typu 0 i 11. Dokładnie rzecz biorąc, nie jest to dobry pomysł, ale jeśli potrzebujesz wyważyć bezpieczeństwo z jednej strony i wygodę z drugiej, IPF pozwoli ci to zrobić: pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 Pamiętaj, że kolejność w zestawie reguł jest ważna. Ponieważ każda z reguł ma słowo `quick', musimy umieścić reguły przepuszczające ( pass ) przed blokującymi ( block ), więc tak naprawdę ostatnie trzy reguły powinny się znaleźć w pliku konfiguracyjnym w tej kolejności: pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any Dodanie tych trzech reguł do tych, które zabezpieczają przed fałszowaniem pakietów może być trochę kłopotliwe. Jednym z błędów może być włączenie nowych reguł ICMP na początku: pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all Problem polega na tym, że pakiet ICMP typu 0 z 192.168.0.0/16 zostanie przepuszczony przez pierwszą regułę i nie zostanie zablokowany przez regułę czwartą. Również, ponieważ używamy ICMP ECHO_REPLY (typ 0) by przepuścić pakiety do 20.20.20.0/24, z dołączonym słowem `quick', otworzyliśmy się właśnie z powrotem na atak typu smurf, negując ostatnie dwie reguły blokujące. Ups. By temu zapobiec, ustawimy reguły dotyczące ICMP po regułach zabezpieczających przez fałszowaniem pakietów: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any pass in all Ponieważ blokujemy ruch sfałszowany zanim zajmujemy się pakietami typu ICMP, pakiety sfałszowane nigdy nie docierają do zestawu reguł ICMP. Bardzo ważne jest pamiętanie o takich rzeczach podczas łączenia zestawów reguł.

Porty TCP i UDP; Słowo kluczowe `port'

Ponieważ zaczęliśmy już blokować pakiety na podstawie protokołu, możemy również zacząć blokować pakiety na podstawie specyficznych cech każdego z nich. Najczęściej używa się numeru portu. Usługi takie jak rsh, rlogin i telnet są bardzo przydatne, ale również bardzo niebezpieczne jeśli chodzi o podsłuchiwanie ( ang. sniffing ) i fałszowanie. Można oczywiście pójść na kompromis i zezwolić na używanie tych usług w sieci wewnętrznej a zablokować przy wychodzeniu na zewnątrz. Można to osiągnąć w prosty sposób, ponieważ rlogin, rsh i telnet używają określonych portów TCP (odpowiednio 513, 514 i 23). W związku z tym stworzenie reguł, które te usługi zablokują jest proste: block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23 Upewnij się, że wszystkie trzy znajdują się przed regułą `pass in all', dzięki czemu zamkną sieć od zewnątrz ( część reguł odpowiadająca za ochronę przed fałszowaniem pomijam dla jasności ): pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23 pass in all Możesz również chcieć zablokować porty 514/udp ( syslog ), 111/tcp i 111/udp ( portmap ), 515/tcp ( lpd ), 2049/tcp i 2049/udp ( NFS ), 6000/tcp ( X11 ) i tak dalej. Możesz uzyskać pełną listę portów na których aktualnie nasłuchujesz używając polecenia netstat -a ( lub lsof -i, jeśli masz go zainstalowanego ).

Blokowanie UDP zamiast TCP sprowadza się do zastąpienia `proto tcp' przez `proto udp'. Reguła dla syslog'a wyglądałaby następująco: block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514 IPF ma również skrótowy sposób zapisu w przypadku gdy chodzi o `proto tcp' jak i proto udp jednocześnie, tak jak w przypadku portmap i NFS. Reguła dla portmap'a wyglądałaby tak: block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111 Wprowadzenie do zaawansowanych ścian ogniowych

Ta sekcja została napisana w ten sposób, by przeczytać ją bezpośrednio po porzedniej części. Poniżej zawarto zarówno koncepcje projektowania zaawansowanych ścian ogniowych, jak i zaawansowane możliwości zawarte w programie ipfilter. W momencie gdy ta sekcja będzie ci doskonale znana, powinieneś być w stanie zbudować bardzo silną ścianę ogniową.

Gwałtowna paranoja lub polityka Domyślnego Blokowania ( ang. Default-Deny )

Istnieje pewien poważny problem gdy blokujemy usługi na podstawie portów: czasami się one przesuwają . Programy które bazują na RPC są w tym naprawdę okropne - lockd, statd, nawet nfsd słucha na portach innych niż 2049. Jest bardzo trudno przewidzieć, a nawet gorzej zautomatyzować proces dostrajania się w kółko i na okrągło. A co jeśli zapomnisz o usłudze? Zamiast zmagać się z bałaganem, zacznijmy od stanu zupełnie czystego. Aktualny zestaw reguł wygląda tak:

Tak, naprawdę zaczynamy od nowa. Pierwszą regułę której użyjemy będzie: block in all Nie przechodzi żaden ruch sieciowy. Żaden. Nawet tyci-tyci. Jesteś w tym momencie raczej bezpieczny. Konfiguracja użyteczna, ale bezpieczna. Najlepsze w tym wszystkim to to, że niewiele musisz teraz zrobić by nadal pozostać bezpiecznym, ale stać się też troszkę użytecznym. Powiedzmy że maszyna pracuje jako serwer WWW, nic więcej, nic mniej. Nie wykonuje nawet zapytań DNS. Chce tylko odbierać połączenia na port 80/tcp i to wszystko. Możemy to zrobić. Wykonamy to dokładając drugą regułę, którą już znasz: block in on tun0 all pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 Maszyna przyjmie ruch na port 80 dla 20.20.20.1 i odrzuci wszystko inne. Dla podstawowych zastosowań ścian ogniowych to wszystko co potrzeba.

Zezwolenie na ruch wynikające z innych reguł; reguła `keep state'

Zadaniem twojej ściany ogniowej jest zabezpieczenie przed niechcianym ruchem z punktu B do punktu A. Mamy generalne reguły które mówią `jeśli tylko ten pakiet jest do portu 23, to go puszczamy'. Mamy generalne reguły mówiące `jeśli tylko ten pakiet ma flagę FIN ustawioną, to go puszczamy'. Nasze ściany ogniowe nie znają początku, środka ani końca sesji TCP/UDP/ICMP. Mają tylko reguły które sprawdzają w stosunku do wszystkich pakietów. Musimy mieć nadzieję, że pakiet który ma flagę FIN ustawioną nie jest tak naprawdę skanem FIN, sprawdzającym nasze usługi. Mamy nadzieję że pakiet do portu 23 nie jest próbą przechwycenia naszej sesji telnetowej. A co jeśli byłaby szansa na zidentyfikowanie i zautoryzowanie poszczególnych sesji TCP/UDP/ICMP i rozróżnić te które są skanami portów czy też atakami DoS? Jest taki sposób, i nazywa się utrzymywaniem stanu ( ang. keep state ).

Chcemy wygody i bezpieczeństwa w jednym. Wielu ludzi również i dlatego Cisco ma klauzulę `established' ( nawiązane ) i pozwala przejść nawiązanym sesjom TCP. IPFW też ma również `established', IPFWADM ma `setup/established' ( konfigurujące/nawiązane ). Wszystkie mają tą opcję, ale nazwa jest bardzo myląca. Kiedy ją pierwszy raz zobaczyliśmy, myśleliśmy że nasz filtr pakietów śledzi każdą sesję i sprawdza co się w niej dzieje, że wie czy połączenie naprawdę jest nawiązane czy nie. Tak naprawdę, wszystkie wierzą pakietowi że jest tym czym twierdzi że jest, a każdy może przecież kłamać. Czytają sekcję flag nagłówka pakietu TCP i tu pojawia się problem bo nie mają opcji podobnego analizowania pakietów UDP/ICMP. Każdy kto potrafi spreparować nagłówki pakietów może pokonać taką ścianę ogniową.

No to co takiego szczególnego robi IPF, możesz zapytać? Cóż, inaczej niż w innych ścianach ogniowych, IPF naprawdę potrafi śledzić połączenia i stwierdzić czy połączenie jest nawiązane czy nie. I robi to zarówno dla pakietów TCP, UDP i ICMP, nie tylko TCP. IPF nazywa to właśnie utrzymywaniem stanu. Słowo kluczowe do zastosowania w regule brzmi keep state.

Do tej pory, mówiliśmy że pakiety przychodzą, zestaw reguł zostaje sprawdzony, pakiety wychodzą i znowu sprawdzany jest zestaw reguł. Dokładniej rzecz biorąc, to co się dzieje wygląda tak: pakiety przychodzą, sprawdzana jest tabela stanów, potem być może sprawdzany jest zestaw reguł dotyczących połączeń przychodzących, pakiety wychodzą, sprawdzana jest tabela stanów, i znów być może sprawdzany jest zestaw reguł dotyczących połączeń wychodzących. Tabela stanów to lista sesji TCP/UDMP/ICMP które są przepuszczane bez pytania przez ścianę ogniową, pomijając cały zestaw reguł. Brzmi jak poważna dziura w bezpieczeństwie? Poczekaj, to najwspanialsza rzecz która mogła przytrafić się twojej ścianie ogniowej.

Wszystkie sesje TCP/IP mają początek, środek i koniec ( aczkolwiek czasami jest nimi ten sam, jeden pakiet ). Nie możesz mieć końca bez środka, a środka bez początku. To oznacza, że wszystko co tak naprawdę potrzebujesz filtrować to początek sesji TCP/UDP/ICMP. Jeśli początek sesji ma prawo przejść przez ścianę ogniową, cała reszta ( środek i koniec ) również. Utrzymywanie stanu umożliwia Ci zignorowanie środka i końca, a skupienie się na blokowaniu/przepuszczaniu nowych sesji. Jeśli nowa sesja jest przepuszczana, wszystkie pakiety należące do niej również zostaną przepuszczone. Jeśli ma zostać zablokowana, żaden z pakietów który ma do niej należeć nie zostanie przepuszczony. Poniżej przykład dla pracy z serwerem ssh (i nic poza serwerem ssh): block out quick on tun0 all pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state

Pierwszą rzeczą którą możesz zauważyć, to brak komendy `pass out'. W rzeczywistości, jest tylko jedna, zawierająca wszystko reguła block out. Pomimo tego, zestaw reguł jest kompletny. Dzieje się tak, ponieważ poprzez utrzymywanie stanu tworzony jest cały zestaw reguł. W momencie, w którym pierwszy pakiet SYN dociera do serwera, tworzona jest pozycja w tabeli stanu i reszta sesji ssh jest również przepuszczana bez żadnej interferencji ze strony ściany ogniowej. Poniżej kolejny przykład: block in quick on tun0 all pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state W tym przypadku, serwer nie serwuje żadnych usług. Tak naprawdę, nie jest serwerem a klientem. I ten klient nie chce by żadne nieautoryzowane pakiety docierały do jego stosu IP. Jednakże, chce mieć pełen dostępu do internetu i naturalnie potrzebuje możliwości odpowiadania na pakiety które należą do połączeń przez niego inicjowanych. Ten prosty zestaw reguł tworzy listę stanów dla każdej nowej wychodzącej sesji TCP. I znowu, ponieważ tworzona jest nowa pozycja w liście stanów, nowe sesje TCP mają swobodę w komunikowaniu się tam i z powrotem tak jak chcą, bez niepotrzebnego zainteresowania ze strony ściany ogniowej. Wspomnieliśmy również, że działa to również dla UDP i ICMP: block in quick on tun0 all pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state Tak Wirginio, możemy pingować. Teraz utrzymujemy stany połączeń TCP, UDP, ICMP. Możemy wykonywać połączenia wychodzące tak jakby nie było żadnej ściany ogniowej, a jednocześnie wszyscy hipotetyczni atakujący nie mogą wejść z powrotem. Jest to bardzo wygodne bo nie ma potrzeby śledzić na których portach słuchamy, a jedynie porty na które chcemy by można się było dostawać.

Utrzymywanie stanu jest bardzo wygodne, ale jednocześnie może być trochę zagmatwane. Możesz sobie strzelić w stopę w bardzo dziwne sposoby. Rozważmy następujący zestaw reguł: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Na pierwszy rzut oka, wygląda na całkiem poprawną konfigurację. Umożliwiamy na nawiązywanie sesji przychodzących na port 23 i wychodzących wszędzie. Naturalnie, pakiety wychodzące na port 23 będą miały pakiety odpowiedzi, ale zestaw reguł jest ustawiony w ten sposób że reguła `pass out' wygeneruje pozycję w liście stanów i wszystko będzie działało poprawnie. Przynajmniej tak ci się tylko wydaje.

Przykra prawda polega na tym, że po 60 sekundach bezczynności pozycja w tablicy stanów zostanie zamknięta ( w przeciwieństwie do normalnych 5 dni ). Dzieje się tak ponieważ mechanizm śledzący połączenia `nie widział' oryginalnego pakietu SYN przeznaczonego do portu 23, a jedynie SYN ACK. IPF jest bardzo dobry w śledzeniu sesji TCP od początku do końca, ale nie jest zbyt dobry w odgadywaniu poprawności połączenia od połowy. Powinieneś przepisać reguły na takie: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Dodatkowe słowo w regułach spowoduje że pierwszy pakiet utworzy pozycję w tablicy stanów i wszystko będzie działało tak jak się tego spodziewałeś. W momencie gdy 3-stopniowy proces nawiązywania połączenia ( ang. handshake ) był widziany przez mechanizm utrzymywania stanu, połączenie oznaczane jest jako będące w trybie 4/4. Oznacza to, że jest ono skonfigurowane na długoterminowa wymianę danych, dopóki nie zostanie zamknięte ( kiedy to zmieniany jest również tryb ). Możesz sprawdzić aktualne tryby w tablicy stanów poleceniem `ipfstat -s'.

UDP ze sprawdzaniem stanów

UDP nie ma stanów, więc naturalnie wykonanie dobrej roboty w śledzeniu stanu połączenia jest tutaj dużo trudniejsze. Mimo to ipf robi dobrą robotę. Kiedy maszyna A wysyła pakiet UDP do maszyny B z portu źródłowego X na port docelowy Y, ipf pozwoli na odpowiedź z maszyny B do A z portu źródłowego Y na port docelowy X. Jest to krótkoterminowa pozycja w tabeli stanów, stworzona tylko na 60 sekund.

Poniżej przykład tego co się dzieje gdy wykonujemy nslookup by pobrać adres IP maszyny http://www.3com.com: $ nslookup www.3com.com Generowany jest pakiet DNS: 17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979+ Pakiet pochodzi z 20.20.20.1 i z portu 2111, a skierowany jest do 198.41.0.5 na port 53. Tworzona jest 60-sekundowa pozycja w liście stanów. Jeśli w tym czasie nadejdzie pakiet z 198.41.0.5 portu 53 przeznaczony dla 20.20.20.1 na port 2111, zostanie przepuszczony. Jak możesz sprawdzić, milisekundy później: 17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com Pakiet pasuje do kryteriów opisywanych przez pozycję w liście stanów i jest przepuszczany. W tym samym momencie w którym pakiet wchodzi, pozycja znika z listy stanów i żaden nowy pakiet nie może zostać wpuszczony, nawet gdyby twierdził że jest z dokładnie tego samego źródła.

ICMP ze sprawdzaniem stanów

IPFilter traktuje stany ICMP dokładnie tak, jak możnaby się spodziewać rozumiejąc jak ICMP używany jest z TCP i UDP, i przy zrozumieniu jak działa komenda `keep state'. Są generalnie dwa typy wiadomości ICMP: zapytania i odpowiedzi. Gdy wpisujesz regułę taką jak na przykład: pass out on tun0 proto icmp from any to any icmp-type 8 keep state by zezwolić na wychodzące odpowiedzi na żądanie echa ( typowy ping ), wpuszczony zostanie pakiet icmp-type 0, który jest zwyczajową odpowiedzią. Pozycja w liście stanów ma domyślny czas wygaśnięcia niekompletnego stanu 0/0 wynoszący 60 sekund. W związku z tym, jeśli utrzymujesz stan każdej wychodzącej wiadomości icmp która wywołuje odpowiedź icmp, potrzebujesz reguły `proto icmp [...] keep state'.

Jednakże, większość wiadomości ICMP to wiadomości o statusie generowane przez błędy w UDP ( i czasami TCP ). W IPFilter w wersjach 3.4.x i wyższych każda wiadomość o błędzie ICMP ( powiedzmy icmp-type 3 code 3 - port niedostępny, lub icmp-type 11 - przekroczony czas ), która pasuje do aktywnego wpisu w liście stanów, powoduje że pakiet ICMP jest wpuszczany. Na przykład, w starszych wersjach IPFilter, jeśli chciałeś by działał traceroute musiałeś użyć: pass out on tun0 proto udp from any to any port 33434><33690 keep state pass in on tun0 proto icmp from any to any icmp-type timex a teraz możesz uzyskać to samo poprzez wpis: pass out on tun0 proto udp from any to any port 33434><33690 keep state By zabezpieczyć się przed wślizgnięciem się nieproszonych pakietów ICMP przez Twoją ścianę ogniową, nawet gdy aktywny wpis w tabeli stanów istnieje, przychodzący pakiet ICMP jest sprawdzany nie tylko pod kątem poprawnego adresu źródłowego i przeznaczenia ( i portów, jeśli to go dotyczy ), ale jeszcze małej części danych w pakiecie określającej w wyniku którego pakietu ta wiadomość ICMP została wygenerowana.

Wykrywanie skanów FIN; słowa kluczowe `flags' i `keep frags'

Wróćmy do czterolinijkowego zestawu reguł z poprzedniej sekcji: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Jest on prawie, ale nie całkiem satysfakcjonujący. Problem polega na tym, że nie tylko pakiety SYN mogą dotrzeć do portu 23, ale również inne, stare pakiety. Możemy to zmienić przez zastosowanie słowa kluczowego `flags': pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state pass out quick on tun0 proto tcp from any to any flags S keep state block in quick all block out quick all Obecnie tylko pakiety TCP, skierowane do 20.20.20.1 na port 23 z ustawioną tylko flagą SYN mogą dotrzeć i utworzyć pozycję w liście stanów. Samotna flaga SYN ustawiona jest tylko w pierwszym pakiecie sesji TCP ( zwanej pakietem nawiązującym połączenie TCP ) i to jest to co chcieliśmy tak naprawdę uzyskać. Są przynajmniej dwie zalety takiego zapisu: nie dotrą do ciebie żadne inne pakiety które mogłyby namieszać w tabeli stanów. Po drugie, skany FIN i XMAS nie powiodą się ponieważ mają ustawione również inne flagi oprócz SYN. Aktualnie, wszystkie przychodzące pakiety muszą być albo nawiązującymi połączenie albo już do niego należeć. Jeśli nadejdzie cokolwiek innego, jest albo spreparowane albo jest skanem portów. Istnieje jednak jeden wyjątek - gdy dociera do nas pakiet sfragmentowany. IPF jest przygotowany na obsługę takich sytuacji, z pomocą słowa kluczowego `keep frags'. Przy jego zastosowaniu, IPF będzie potrafił śledzić również sesje z pakietami, które są sfragmentowane i pozwoli im przejść. Przepiszmy te trzy reguły by logować pakiety spreparowane i zezwolić na obsługę pakietów sfragmentowanych: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags pass out quick on tun0 proto tcp from any to any keep state flags S keep frags block in log quick all block out log quick all Taki zapis działa, ponieważ każdy pakiet który powinien być wpuszczony, zostanie najpierw wpisany do tabeli stanów, zanim reszta reguł zdąży go zablokować. Jedynym skanem którego ten zapis nie wykryje jest skan SYN. Jeśli naprawdę jesteś tym zaniepokojony, być może powinieneś logować również wszystkie pakiety SYN.

Odpowiadanie na zablokowane pakiety

Jak do tej pory, wszystkie nasze zablokowane pakiety byłu zrzucane na podłogę, i bez względu na to czy zostały zalogowane czy nie, nie odsyłaliśmy niczego do hosta który przysłał nam pakiet. Czasami nie jest to najbardziej pożądane rozwiązanie, ponieważ robiąc coś takiego, informujemy go że mamy działający filtr pakietów. Wydaje się dużo lepszym rozwiązaniem wprowadzenie w błąd atakującego, że nie działa żaden filtr pakietów i nie ma żadnych usług przy pomocy których możnaby się włamać. Tutaj dochodzimy do dużo bardziej wyrafinowanego blokowania.

Kiedy na systemie Unixowym nie działa usługa, zwykle wysyła on zdalnemu systemowi jakiś rodzaj odpowiedzi. W przypadku TCP, jest to pakiet RST (Reset). Kiedy blokujemy pakiet TCP, IPF może faktycznie odesłać pakiet RST do nadawcy jeśli użyjemy słowa kluczowego `return-rst'.

Podczas gdy do tej pory pisaliśmy: block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23 pass in all Możemy teraz napisać: block return-rst in log proto tcp from any to 20.20.20.0/24 port = 23 block in log quick on tun0 pass in all Potrzebujemy dwóch reguł `block', ponieważ `return-rst' działa tylko dla TCP, a my nadal chcemy zablokować protokoły takie jak UDP, ICMP i inne. Kiedy użyjemy takich reguł, strona zdalna otrzyma komunikat `connection refused' ( połączenie odrzucone ), zamiast `connection timed out' ( upłynął czas na nawiązanie połączenia ).

Możliwe jest również odsyłanie wiadomości z błędami, gdy ktoś wysyła pakiet UDP do portu w twoim systemie. Do tej pory pisaliśmy: block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111 Używając słowa kluczowego return-icmp możemy teraz napisać: block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111 Zgodnie z książką TCP/IP Illustrated, port-unreachable ( port nieosiągalny ) jest prawidłowym komunikatem ICMP odpowiedzi jeśli na danym porcie nie nasługuje żadna usługa. Możesz użyć dowolnego typu ICMP, ale port-unreachable jest prawdopodobnie najlepszą odpowiedzią. Jest również domyślna w przypadku użycia `return-icmp'.

Jednak, gdy zaczniesz używać `return-icmp', zauważysz że nie jest to bardzo skryte, ponieważ zwraca pakiet ICMP z adresem ściany ogniowej, a nie adresem maszyny dla której pakiet był przeznaczony. Zostało to naprawione w ipfilter w wersji 3.3 i dodano nowe słowo kluczowe: `return-icmp-as-dest'. Nowy format wygląda tak: block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111

Powinieneś być bardzo uważny i generować pakiety odpowiedzi tylko w sytuacjach, w których dobrze wiesz na co odpowiadasz. Na przykład, odpowiadanie return-icmp na broadcast w sieci lokalnej może skończyć się zalaniem pakietami sieci.

Wymyślne techniki logowania

Bardzo ważne jest, by zauważyć, że sama obecność słowa kluczowego `log' zapewnia tylko dostępność pakietu dla urządzenia logującego ipfilter: /dev/ipl. Tak naprawdę aby zobaczyć tą informację, musisz mieć uruchomione narzędzie ipmon ( lub inne, które czyta /dev/ipl ). Typowe użycie słowa `log' jest skojarzone z poleceniem ipmon -s, które dopiero loguje informacje do syslog. Od ipfilter 3.3, można nawet kontrolować zachowanie logujące syslog poprzez użycie słowa `log level', tak jak w regułach poniżej: block in log level auth.info quick on tun0 from 20.20.20.0/24 to any block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21 W dodatku, możesz ograniczać informacje które są logowane. Na przykład, możesz nie być zainteresowany faktem, że ktoś próbował twój port telnetu 500 razy, a jedynie, że w ogóle próbował to robić. Służy do tego opcja `log first' logująca tylko pierwszy pakiet. Oczywiście, pierwszeństwo dotyczy tylko jednej sesji i dla typowego zablokowania pakietu, trudno będzie ci uzyskać efekt by to robiło dokładnie to co chciałeś. Jednakże przy połączeniu tego z poleceniami `pass' i `keep state', może być to bardzo pomocne narzędzie w śledzeniu ruchu.

Inna użyteczna opcja którą możesz wykorzystać przy logowaniu, to zachowanie interesujących fragmentów pakietu oprócz normalnej informacji logowanej z pakietem. IPFilter zaloguje pierwsze 128 bajtów pakietu jeśli użyjesz słowa `log body'. Powinieneś starać się ograniczać takie logowanie, ponieważ czyni to twoje logi bardzo szczegółowymi. Dla niektórych zastosowań jest to jednak wygodne - można sprawdzić dokładniej pakiet, lub wysłać te informacje do jakiejś aplikacji do dalszej analizy.

Złożenie tego wszystkiego razem

Mamy teraz całkiem szczelną ścianę ogniową, ale nadal możemy ją jeszcze uszczelnić. Część oryginalnego zestawu reguł usuneliśmy, część została jako użyteczna. Sugerowałbym wrócenie do wszystkich dotyczących zabezpieczenia przed fałszowaniem. To sprawia, że zostajemy z: block in on tun0 block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state Zwiększanie wydajności przez tworzenie grup reguł

Rozszerzmy użycie naszej ściany ogniowej poprzez stworzenie bardziej skomplikowanej, i mamy nadzieję bardziej przystającej do świata rzeczywistego konfiguracji przykładowej. Na potrzeby tego przykładu, zmienimy nazwy interfejsów i numerację sieci. Załóżmy, że mamy trzy interfejsy na swojej ścianie ogniowej, xl0, xl1 i xl2. xl0 jest podłączony do sieci zewnętrznej 20.20.20.0/26 xl1 jest podłączony do naszej sieci zdemilitaryzowanej 20.20.20.64/26 xl2 jest podłączony do naszej chronionej sieci 20.20.20.128/25 Zdefiniujemy od razu cały zestaw reguł, ponieważ jak do tej pory powinieneś już umieć je czytać: block in quick on xl0 from 192.168.0.0/16 to any block in quick on xl0 from 172.16.0.0/12 to any block in quick on xl0 from 10.0.0.0/8 to any block in quick on xl0 from 127.0.0.0/8 to any block in quick on xl0 from 0.0.0.0/8 to any block in quick on xl0 from 169.254.0.0/16 to any block in quick on xl0 from 192.0.2.0/24 to any block in quick on xl0 from 204.152.64.0/23 to any block in quick on xl0 from 224.0.0.0/3 to any block in log quick on xl0 from 20.20.20.0/24 to any block in log quick on xl0 from any to 20.20.20.0/32 block in log quick on xl0 from any to 20.20.20.63/32 block in log quick on xl0 from any to 20.20.20.64/32 block in log quick on xl0 from any to 20.20.20.127/32 block in log quick on xl0 from any to 20.20.20.128/32 block in log quick on xl0 from any to 20.20.20.255/32 pass out on xl0 all pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state block out on xl1 all pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state block out on xl2 all pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state Z tego arbitralnego przykładu, od razu można zauważyć że nasz zestaw reguł powoli staje się coraz mniej czytelny. By sprawy pogorszyć, w momencie gdy dodamy reguły dla naszej sieci zdemilitaryzowanej (DMZ), musimy dodać dodatkowe reguły testujące dla każdego pakietu, co pogorszy wydajność połączeń xl0-xl2. Jeśli zbudujesz ścianę ogniową z regułami takimi jak te, a masz dużą przepustowość łącza i średnio dużo mocy obliczeniowej procesora, każdy kto ma stację roboczą w sieci podłączonej do interfejsu xl2 przyjdzie do ciebie by umieścić twoją głowę na talerzu. Zatem, by utrzymać połączenie głowy z torsem, możesz przyśpieszyć znacznie porównywanie przez stworzenie grup reguł. Pozwalają one na zapisanie swoich reguł w formie drzewa, zamiast w postaci linearnej - więc jeśli pakiet nie ma nic wspólnego z pewnym zestawem testów ( powiedzmy, reguł dotyczących xl1 ), nie będą one w ogóle brane pod uwage. Jest to coś w rodzaju posiadania wielu ścian ogniowych na tej samej maszynie.

Poniżej przykład z którym zaczniemy: block out quick on xl1 all head 10 pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10 block out on xl2 all W tym bardzo prostym przykładzie, widzimy małą zapowiedź potęgi grup reguł. Jeśli pakiet nie jest przeznaczony dla interfejsu xl1, nagłówek ( head ) dla grupy 10 ( group 10 ) w ogóle nie będzie pasował i nie zostanie uwzględniony przy porównywaniu. Jeśli pakiet pasuje do reguły xl1, słowo kluczowe quick spowoduje ucięcie przetwarzania na poziomie podstawowym/korzenia ( grupa reguł 0 ) i skoncentruje się na testowaniu reguł które dotyczą grupy 10, w tym wypadku sprawdzenia flagi SYN w pakietach przeznaczonych dla 80/tcp. W ten sposób, możemy przepisać powyższe reguły tak by zmaksymalizować wydajność naszej ściany ogniowej. block in quick on xl0 all head 1 block in quick on xl0 from 192.168.0.0/16 to any group 1 block in quick on xl0 from 172.16.0.0/12 to any group 1 block in quick on xl0 from 10.0.0.0/8 to any group 1 block in quick on xl0 from 127.0.0.0/8 to any group 1 block in quick on xl0 from 0.0.0.0/8 to any group 1 block in quick on xl0 from 169.254.0.0/16 to any group 1 block in quick on xl0 from 192.0.2.0/24 to any group 1 block in quick on xl0 from 204.152.64.0/23 to any group 1 block in quick on xl0 from 224.0.0.0/3 to any group 1 block in log quick on xl0 from 20.20.20.0/24 to any group 1 block in log quick on xl0 from any to 20.20.20.0/32 group 1 block in log quick on xl0 from any to 20.20.20.63/32 group 1 block in log quick on xl0 from any to 20.20.20.64/32 group 1 block in log quick on xl0 from any to 20.20.20.127/32 group 1 block in log quick on xl0 from any to 20.20.20.128/32 group 1 block in log quick on xl0 from any to 20.20.20.255/32 group 1 pass in on xl0 all group 1 pass out on xl0 all block out quick on xl1 all head 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10 pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state group 10 pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state block out on xl2 all pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state Teraz możesz poobserwować grupy reguł w akcji. Dla komputera w sieci xl2, kompletnie pomijamy wszystkie testy w grupie 10, kiedy nie komunikujemy się z żadnymi komputerami w tej sieci.

Zależnie od Twojej sytuacji, korzystne może być pogrupowanie reguł według protokołu, różnych maszyn, bloków sieciowych, lub czegokolwiek - tak by sprawić, że przepływ informacji będzie płynny.

słowo kluczowe - `Fastroute' daje niewykrywalności ( ang. stealth )

Nawet mimo faktu, że przekazujemy część pakietów a inne blokujemy, zachowujemy się tak, jak dobrze zachowujący się router powinien się zachowywać - zmniejszamy TTL pakietu i niniejszym oznajmiamy całemu światu że tak, jest tutaj przejście ( ang. hop ). Możemy jednak ukryć swoją obecność przed zbyt dociekliwymi aplikacjami takimi jak unix'owy traceroute, który używa pakietów UDP z różnymi TTL by zmapować ilość przejść pomiędzy dwoma komputerami. Jeśli chcemy, by nadchodzące traceroute działało, ale nie chcemy oświadczać że mamy tu ścianę ogniową która spowoduje dodanie jednego przejścia, możemy zrobić to regułą taką jak ta: block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465 Obecność słowa `fastroute' zasygnalizuje ipfilter żeby nie przekazywać pakietu do stosu IP dla wykonania routingu, co spowodowałoby zmniejszenie TTL pakietu. Pakiet zostanie po prostu od razu umieszczony na interfejsie wyjściowym przez ipfilter i nic nie zostanie zmienione. ipfilter oczywiście sprawdzi systemową tablicę routingu by sprawdzić na jakim interfejsie powinien wystawić pakiet, ale wykona zadanie przeroutowania pakietu sam.

Istnieje również powód, dla którego używamy tu słów `block quick'. Gdybyśmy użyli słowa `pass' i mielibyśmy włączone przekazywanie ( ang. forwarding ) pakietów IP w kernelu, skończyłoby się to na tym, że dostalibyśmy dwie ścieżki którymi pakiet mógłby wyjść, a to prawdopodobnie spowodowałoby błąd kernel panic.

Trzeba również dodać, że większość kerneli Uniksowych ( a w szczególności te, na których ipfilter zwykle pracuje ), mają dużo bardziej wydajny kod routingu niż ten w ipfilter, a w związku z tym nie powinieneś myśleć o słowie `fastroute' jako o sposobie na zwiększenie szybkości pracy swojej ściany ogniowej. Powinno być ono używane tylko w przypadku gdy ukrycie się jest najważniejsze.

NAT i proxy

Poza otoczeniem firmowym, jedną z największych zalet technologii ścian ogniowych jest możliwość połączenia wielu komputerów przez jeden interfejs zewnętrzny, często bez zgody, wiedzy czy nawet podejrzeń ze strony dostawcy internetowego. Ci którzy znają Linuksa nazywają to Maskaradą IP ( ang. IP Masquerading ), ale dla reszty świata jest ona znana pod nazwą Translacja Adresów Sieciowych, lub w skrócie NAT ( ang. Network Address Translation ).

Mapowanie wielu adresów w jeden

Najprostszym zastosowaniem NAT jest dokładnie to co robi jego odpowiednik - Linuksowa Maskarada IP. Zapisuje się to w jednej prostej regule: map tun0 192.168.1.0/24 -> 20.20.20.1/32 Bardzo proste. Zawsze gdy pakiet wychodzi przez interfejs tun0 ze źródłowym adresem pasującym do maski CDIR 192.168.1.0/24, adres jest zamieniany jeszcze na stosie IP, tak by zawierał adres źródłowy 20.20.20.1 a dopiero wtedy zostaje wysłany do swojego celu przeznaczenia. System utrzymuje listę jakie zmapowane połączenia są w trakcie tak by mógł wykonać czynność odwrotną gdy nadejdzie odpowiedź ( skierowana do 20.20.20.1 ) i odesłać ją do oryginalnego nadawcy.

Jest jednak pewien minus reguły którą teraz wpisaliśmy. W wielu przypadkach, nie wiemy jaki mamy adres IP naszego zewnętrznego interfejsu ( jeśli używasz tun0 czy ppp0 i typowego ISP ), więc ustawienie tablicy NAT staje się raczej problematyczne. Na szczęście NAT jest na tyle mądry, że potrafi zaakceptować adres w postaci 0/32. Sygnalizuje to, że musi sprawdzić sobie sam jaki właściwie adres ma interfejs zewnętrzny i prawidłowo zmodyfikować pakiet. Spójrz niżej: map tun0 192.168.1.0/24 -> 0/32 Możemy teraz załadować nasze reguły do ipnat i połączyć się ze światem zewnętrznym bez konieczności edytowania czegokolwiek. Musisz jednak uruchomić `ipf -y' by odświeżyć adres przypisany połaczeniu jeśli się rozłączysz i wdzwonisz ponownie, lub gdy wygaśnie Twoja dzierżawa na adres przydzielony przez DHCP.

Niektórzy z was mogą się zastanawiać, co dzieje się z portem źródłowym gdy wykonywane jest mapowanie. W przypadku naszej reguły, port źródłowy pakietu nie zostaje zmieniony w stosunku do oryginału. Są jednak przypadki gdy nie chcemy by tak się działo - może po drodze jest jeszcze jedna ściana ogniowa, lub wiele maszyn próbuje używać tego samego portu. Może to powodować kolizje i pakiet jest przepuszczany bez mapowania. ipnat pomaga w tym momencie, poprzez dostarczenie słowa kluczowego `portmap': map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000 Nasza reguła wrzuca wszystkie mapowane połączenia ( które mogą używać protokołu tcp, udp lub jednocześnie tcp/udp ) w zakres portów od numeru 20000 do 30000.

Możemy jeszcze ułatwić sobie życie, używając polecenia `auto' by poinformować ipnat by sam określił sobie jakich portów może użyć i zaalokował je proporcjonalnie wśród adresów, używanych w puli: map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto

Pamiętaj, że reguły mapujące odnoszą się tylko do protokołów, które określiłeś ( np. tcp, udp lub tcp/udp ), i nie odnoszą się do innych, takich jak ICMP czy IPsec ESP/AH. Dla nich, musisz dodać dodatkowe mapowania odnoszące się do wszystkich innych protokołów: map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000 map tun0 192.168.1.0/24 -> 0/32 Mapowanie wielu adresów w przydzieloną pulę adresów

Innym częstym zastosowaniem NAT jest wzięcie małej, statycznie przydzielonej puli adresów i zmapowanie wielu komputerów w tą mniejszą przestrzeń adresową. Jest to proste do uzyskania przy użyciu tego co już wiesz o słowach kluczowych `map' i `portmap'. Zapiszmy to jak poniżej: map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000 Zdarza się również, że zdalna aplikacja wymaga, by wszystkie połączenia przychodziły z tego samego IP. Możemy pomóc, instruując NAT by statycznie zmapował sesje z danej maszyny na pulę adresów i wykonał trochę magii z wybraniem portu. Robi się to, stosując słowo kluczowe `map-block', tak jak poniżej: map-block tun0 192.168.1.0/24 -> 20.20.20.0/24

Tak jak słowo `map', `map-block' ma również swoją wersję `portmap'. Używa się jej albo ze słowem kluczowym `auto': map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 auto lub ze słowem `ports', jeśli chcesz wskazać konkretne numery portów należące do określonych adresów IP: map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 ports 64 Mapowania jeden do jednego

Czasami zdarza się, że chcemy by komputer za ścianą ogniową z danym IP pojawiał się z innym IP. Jednym z takich przykładów może być labolatorium komputerowe, dołączone do różnych sieci, a mające wziąć udział w testach. Nie chcemy rekonfigurować całego labolatorium, ponieważ możemy postawić przed nim komputer wykonujący NAT i zmienić adresy w jednym miejscu. Można to wykonać za pomocą słowa kluczowego `bimap', od mapowania dwukierunkowego. Bimap posiada pewne dodatkowe zabezpieczenia zapewniające, że wie jaki jest stan połączenia, podczas gdy słowo `map' używane jest tylko do zaalokowania adresu i portu źródłowego oraz odpowiedniej modyfikacji pakietu. bimap tun0 192.168.1.1/32 -> 20.20.20.1/32 spowoduje zmapowanie dla jednej maszyny.

NAT według Zasad

Często zdarza się, że musimy zapewnić funkcjonowanie NATu zależne od adresów źródłowych i przeznaczenia. Na przykład, chcemy prowadzić NAT dla wszystkich, oprócz określonej podsieci: map tun0 from 192.168.1.0/24 ! to 5.0.0.0/20 -> 20.20.20.1/32 Można również zastosować taką konstrukcję: map tun0 from 192.168.1.5/32 port = 5555 to 1.2.3.4/32 -> 20.20.20.2/32 map tun0 from 192.168.1.0/24 to 5.0.0.0/20 -> 20.20.20.2/32 portmap auto Usługi fałszujące

A co to ma do rzeczy? Wiele. Powiedzmy że mamy serwer WWW pracujący na 20.20.20.5, a ponieważ staliśmy się ostatnio bardzo podejrzliwi co do bezpieczeństwa naszej sieci, chcemy by serwer nie pracował na porcie 80, ponieważ wymaga to krótkiego momentu pracy z przywilejami roota. Ale jak uruchomić go na mniej uprzywilejowanym porcie 8000 w świecie 'wszystko kropka com'? Jak ktokolwiek znajdzie nasz serwer? Możemy użyć usług przekierowania NATu by rozwiązać ten problem, instruując go by przemapował wszystkie połączenia przeznaczone dla 20.20.20.5:80 na 20.20.20.5:8000. Używa się do tego słowa kluczowego `rdr': rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000 Możemy również podać protokół, jeśli chcielibyśmy na przykład przekierować usługę UDP zamiast TCP ( która jest domyślna ). Na przykład, gdybyśmy chcieli zastawić zasadzkę na naszej ścianie ogniowej i udawać zainstalowanego Back Orifice dla Windows, możemy ochronić naszą sieć przez prostą regułę: rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp Możliwe jest modyfikowanie zachowania słowa `rdr' w zależności od adresów źródłowego i docelowego: rdr tun0 from 10.1.1.1/32 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8001 rdr tun0 from 10.1.1.1/32 port = 12345 to 20.20.20.5/32 port = 80 -> 192.168.0.5 port 8002 Należy jednak zaznaczyć bardzo ważną sprawę. Nie możesz łatwo użyć tego jako lustra, tzn.: rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp Taka konstrukcja nie zadziała, jeśli .5 i .6 są w tym samym segmencie LAN. Funkcja `rdr' jest wykonywana na każdym pakiecie, który trafia do ściany ogniowej na określonym interfejsie. Gdy nadchodzi pakiet który pasuje do reguły, jego adres docelowy jest zmieniany, pakiet trafia do ipf w celu przefiltrowania i gdy tylko przetrwa boje z regułami filtra, jest wysyłany do kodu routującego Uniksa. Ponieważ pakiet pochodzi z tego samego interfejsu, którym będzie musiał opuścić system by dotrzeć do maszyny docelowej, system jest w kropce. Lustra po prostu nie działają. Nie działa również podawanie adresu interfejsu z którego pakiet właśnie nadszedł. Pamiętaj że adresy docelowe dla `rdr' muszą istnieć po drugiej stronie ściany ogniowej, w sieci do której prowadzi inny interfejs niż ten, którym wszedł pakiet pierwotny.

Transparentne proxy; W końcu przekierowanie do czegoś się przydaje.

Ponieważ właśnie instalujesz ścianę ogniową możesz zdecydować, że jest to dobry moment na zastosowanie proxy dla wielu wychodzących połączeń. Dzięki temu możesz jeszcze bardziej zacieśnić swoje reguły filtrowania chroniące sieć. Może się również zdarzyć tak, że natrafisz na sytuację, której proces mapowania NAT nie może aktualnie poprawnie obsłużyć. Taką sytuację można obejść następującą konstrukcją: rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21 Ten wpis mówi, że każdy pakiet z interfejsu xl0 przeznaczony dla dowolnego adresu ( 0.0.0.0 ) na port ftp, zostanie przepisany tak by połączyć się z proxy, które pracuje na systemie wykonującym NAT na porcie 21.

Ten specyficzny przykład proxy FTP prowadzi do pewnych komplikacji, kiedy chodzi o serwery WWW czy inne automatycznie logujące się klienty, które nie wiedzą o wymaganiach komunikacji z proxy. Istnieją łaty dla ftp-gw z TIS Firewall Toolkit które w połączeniu z procesem NAT pozwalają na zapewnienie funkcjonalności, dzięki której można sprawdzić gdzie chciałeś wejść i wysłać cię tam automatycznie. Wiele paczek proxy pracuje obecnie również w środowisku transparentnego proxy ( na przykład Squid, znajdujący się pod adresem , pracuje w porządku ).

Takie zastosowanie słowa kluczowego `rdr' jest często użyteczne gdy chcesz zmusić użytkowników do autoryzowania się na proxy ( na przykład, gdy chcesz by twoi inżynierowie mogli przeglądać strony WWW, ale wolałbyś żeby raczej ludzie z call-center tego nie robili ).

Filtrowanie przekierowanych usług

Wielu użytkowników chce połączyć filtrowanie i translację adresów, by zapewnić usługi tylko określonym komputerom za ich ścianą ogniową. Na przykład, by zapewnić dostęp do serwera WWW za twoją maszyną 20.20.20.5 ( która tak naprawdę ma adres 192.168.0.5 w sieci wewnętrznej ) Twojemu przyjacielowi który ma adres 172.16.8.2, możesz wpisać następujący wiersz do ipnat.rules: rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000 a następujący wiersz do ipf.rules: pass in on tun0 proto tcp from 172.16.8.2/32 to 192.168.0.5/32 port = 8000 flags S keep state

Na pierwszy rzut oka może to wyglądać trochę dziwnie, ale dlatego że NAT odbywa się pierwszy, a w jego trakcie adres docelowy i port docelowy jest przepisywany zanim zajmie się nim kod filtrujący pakietu.

Magia ukryta w NAT; proxy aplikacji