Sieci  komputerowe 
Kompendium 

Karol Krysiak

Sieci komputerowe. Kompendium.

Włóż do koszyka

Więcej informacji


9. Konfiguracja firewalla.

9.1 Zagadnienia bezpieczeństwa sieci  LAN [9i].

Co dzień przybywa komputerów podłączonych do sieci Internet, tym samym rośnie prawdopodobieństwo, że któryś z użytkowników Internetu postanowi włamać się do naszej sieci lokalnej. Bezpieczeństwo sieci komputerowych jest zagadnieniem ogromnym i nie widzę możliwości wyczerpania tutaj tego tematu. Zwłaszcza, że co dzień odkrywane są nowe sposoby włamania lub zakłócenia pracy systemów komputerowych. W tym rozdziale zajmę się sposobami kompleksowego zabezpieczenia sieci komputerowej za pomocą techniki filtrowania datagramów (firewalling) oraz tłumaczenia adresów sieciowych (NAT - masquerading). Pierwszym krokiem podczas rozpatrywania zagadnień bezpieczeństwa jest określenie potencjalnych „wrogów” i zorientowanie w metodach ich pracy.

Cele ataków włamywaczy.

Poniżej pokrótce omówię najczęściej stosowane sposoby ingerencji w pracę systemów sieciowych. Istnieją dwa cele ataków crackerów (włamywaczy komputerowych):

1.      Uzyskanie dostępu do systemu.

2.      Zdestabilizowanie pracy systemu komputerowego.

Pierwszy cel osiągany jest poprzez zdobycie nazwy użytkownika w systemie (login) i używanego przez niego hasła. Czasem odbywa się to poprzez wykorzystanie błędu w oprogramowaniu danej usługi sieciowej i zdobycie dostępu do systemu na prawach przyznanych tej usłudze. Zdobycie loginu nie jest trudne, najczęściej wystarczy zdobyć adres poczty elektronicznej (E-mail) danego użytkownika (czasem jest to tzw. alias, co utrudnia zadanie włamywaczowi).

Statystyki podają, że najczęściej użytkownicy sieci komputerowych stosują hasła łatwe do złamania za pomocą metody słownikowej (korzystając ze słownika zawierającego odpowiednią liczbę słów). Dekodowanie haseł metodą brute-force jest bardziej czasochłonne (statystycznie) i dzięki temu łatwiejsze do wykrycia. Polega ono na sprawdzaniu wszystkich możliwych kombinacji znaków mogących znaleźć się w haśle danego systemu operacyjnego. Dlatego należy dbać, aby hasła użytkowników były jak najbardziej skomplikowane, powinny zawierać przynajmniej duże i małe litery oraz cyfry.

Drugi cel ataków, osiągany jest przez crackerów dzięki wykorzystaniu błędów (bug) w oprogramowaniu serwerów usług Internetowych, czasem stosu TCP/IP. Tego typu działaniem jest ostatnio popularna metoda unieruchamianiu serwisów WWW. Polega ona na wysyłaniu olbrzymiej liczby zapytań do serwera WWW, który próbując je wszystkie obsłużyć zostaje zablokowany. Główną metodą zabezpieczeń przed tego typu „problemami” jest ciągła aktualizacja oprogramowania sieciowego oraz śledzenie stron zawierających gotowe oprogramowanie służące do takich działań. Jest to zadanie administratora sieci komputerowej i w zakresie jego obowiązków musi być czas przeznaczony na tego typu działania.


Metody włamań.

Starą metodą jest podstawienie programu, udającego program logujący do systemu. W ten sposób użytkownik podaje swoje hasło, a program włamywacza posiada hasło w postaci niezakodowanej. W przypadku systemu Windows 95 (98) zainstalowanie takiego programu, udającego przykładowo system potwierdzania hasła poczty elektronicznej, nie stanowi zbytniego problemu.

Następną metodą jest nasłuchiwanie (sniffing), polega ona na podłączeniu do sieci komputera z uruchomionym oprogramowaniem do ściągania wszystkich ramek Ethernetowych w danym segmencie sieci. W tym momencie cracker uzyskuje dostęp do wszystkich haseł, które transmitowane są otwartym tekstem po sieci (np. odczytywanie poczty za pomocą protokołu POP, transmisja plików protokołem FTP). Pod nazwą sniffing zaszeregowane są również metody podsłuchu transmisji w kablach sieciowych lub też transmisji w kablach monitorowych. Przykładowo: istnieją urządzenia umożliwiające oglądanie (oczywiście zaszumionego) obrazu wyświetlanego na monitorze znajdującym się kilkanaście metrów od nas, za kilkoma ścianami.

Znanym problemem są usługi umożliwiające zdalną pracę: rlogin, rsh, rcp, których system zabezpieczeń jest zupełnie niewystarczający. Aktualnie są coraz rzadziej stosowane i najczęściej nie wykorzystywane. Zastąpione zostały usługą bezpiecznego połączenia ssh (Secure Shell).

Niebezpieczna może być również usługa ftp. Niewłaściwie skonfigurowany serwer ftp, może umożliwić włamywaczowi uzyskanie ważnych informacji, przykładowo pliku zawierającego hasła.

Jedną z kategorii zagrożeń stanowią tzw. furtki (backdoors) lub włazy (trapdors) będące nieudokumentowanymi funkcjami aplikacji, pozostawionymi przez programistów. W systemie Linux, dzięki pełnej dostępności źródeł programów, bardzo szybko są wykrywane i usuwane tego typu problemy.

Ponadto usługa smtp w implementacji wczesnych wersji programu sendmail okazała się niedostatecznie bezpieczna. Przykładowo przy odpowiednim przerobieniu przesyłki, interpretowana jest ona jako program wykonywalny i uruchamiana przez sendmaila.

Jednym z problemów może być wykorzystywanie przez administratorów serwerów WWW, skryptów CGI pochodzących z nieznanych źródeł. Dodatkowo korzystanie z usług WWW wymaga wiele ostrożności, ponieważ pojawia się bardzo dużo nowych technologii, których systemy zabezpieczeń nie są dobrze znane. Typowym przykładem jest technologia ActiveX wprowadzona przez firmę Microsoft, chociaż implementacja języka Java też nie jest wolna od błędów. Jednak znany jest fakt, że zastosowana w przeglądarce Netscape Communicator technologia Sand Box jest o wiele bezpieczniejsza od implementacji zabezpieczeń w Internet Explorerze.

Jedną z najgłośniejszych technik włamań było „podszywanie się (spoofing). Polega ono na wysyłaniu datagramów IP z nieprawdziwym adresem źródłowym, przez co komputer je odbierający błędnie identyfikuje ich nadawcę. Zabezpieczenie przed ta metodą zostało wkompilowane w jądro rutera i jest uruchamiane zawsze przy starcie systemu.

Systemy Linuxowe są odporne na atak Ping of Death polegający na wysyłaniu dużych pakietów ICMP i przepełnianiu stosu TCP. Łatwo rozpoznać takie pakiety ICMP po fragmentacji, która została dokonana ze względu na rozmiar przekraczający MTU.

Teardrop i Bonk są metodami ataków (niebezpieczne głównie dla Windows NT) używającymi nachodzących na siebie fragmentów pakietów. Ruter Linuxowy dokonuje defragmentacji i uniemożliwia takie ataki.

Niektóre z mniej stabilnych stosów TCP są wrażliwe na datagramy z dużą liczbą fragmentów i mogą nie odebrać ich wszystkich. Linux jest pozbawiony tego problemu. Można filtrować takie fragmenty lub skompilować jądro rutera z opcją `IP: always defragment' ustawioną na `Y' (tylko gdy dany ruter jest jedyną możliwa drogą dotarcia takich pakietów).

Istnieje na pewno wiele innych metod i ciągle pojawiają się nowe. Jedynym sposobem zabezpieczenia jest nieustanne śledzenie grup dyskusyjnych zajmujących się zagadnieniami bezpieczeństwa i natychmiastowe reagowanie na każde nowe zagrożenie. Jest to zadanie każdego administratora sieci. Ponadto podstawą tworzenia polityki zabezpieczeń dla danej firmy jest prawidłowe skonfigurowanie firewalla, będącego aktualnie niezbędnym składnikiem systemu bezpieczeństwa.

Podczas projektowania bezpiecznej sieci komputerowej możemy wyróżnić trzy poziomy (strefy) dostępu z Internetu:

I.                    Poziom zewnętrzny – sieć znajdująca się za firewallem z komputerami o adresach widocznych z Internetu. W tej sieci powinny znajdować się jedynie serwery świadczące usługi Internetowe.

II.                 Poziom wewnętrzny – podsieć z adresów nierutowalnych, mająca połączenie z Internetem za pomocą rutera z funkcjami firewalla i NAT (najczęściej masquerading). Tutaj powinny się znajdować komputery pracowników firmy.

III.               Poziom izolowany – sieć bez rutingu do Internetu, tutaj powinny się znajdować serwery baz danych strategicznych dla firmy (kadry, płace, dane techniczne produkcji, biura projektowe itp.) i komputery pracowników korzystających z tych zasobów.

Rzadko istnieje możliwość wprowadzenia takiej modelowej struktury.

            Pomimo istnienia aż tylu różnych metod włamania się do systemów informatycznych, najczęściej powodem problemów jest po prostu błąd człowieka. Głośne są przypadki pozostawiania haseł dostępu do systemu przyklejonych pod klawiaturą, a czasem karteczką do monitora. Dla tego bardzo ważny jest poziom zrozumienia zasad bezpieczeństwa przez użytkowników systemu i ich przestrzeganie. Ustalenie takich zasad, przyjęcie metod ich egzekwowania, ustalenie i sztywne przestrzeganie poziomów dostępu do systemu oraz odpowiednie jego skonfigurowanie (konstrukcja sieci, firewall) tworzy politykę bezpieczeństwa firmy.



9.2 Firewall [10i] [11i].

Firewall – „ściana ogniowa” termin wzięty z konstrukcji samochodu, jest to element konstrukcji uniemożliwiający rozprzestrzenianie się ognia w czasie pożaru na kabinę pasażerów. W sieci komputerowej jego zadaniem jest zapewnienie bezpieczeństwa sieci w przypadku prób włamania. Można wyróżnić dwa ogólne typy firewalli.

Firewalle filtrujące IP – na podstawie adresów IP oraz numerów portów podejmują decyzje o zakwalifikowaniu danego datagramu jako bezpieczny. Firewalle filtrujące działają na poziomie pakietów IP. Są zaprojektowane do kontroli przepływu bazując na adresie źródłowym, docelowym, porcie i typie pakietu (zawartych w każdym z pakietów). Ten typ firewalli jest bardzo bezpieczny, ale nie daje kontroli nad użytkownikami. Można udostępnić usługę, ale nie da się otrzymać informacji identyfikujących konkretnego użytkownika z niej korzystającego, poza adresem IP komputera z którego przyszła transmisja.

Serwery połączeniowe (proxy) - wykonują połączenie sieciowe w zamian za komputer z sieci lokalnej. Serwery proxy pozwalają na niebezpośredni dostęp do Internetu. Dobrym przykładem jest serwer proxy usługi WWW. Gdy łączymy się z proxy-serwerem za pomocą oprogramowania klienckiego uruchamia on swojego klienta i dostarcza danych których zarządaliśmy. Ponieważ serwery proxy podwajają każde połączenie, możliwe jest zapisywanie (logowanie) każdego z nich. Serwery proxy są w pełni bezpieczne, gdyż nie dokonują bezpośredniego rutingu. Jedyną ich wadą są ogromne wymagania sprzętowe oraz pewien brak elastyczności. W momencie pojawienia się nowej usługi, z której użytkownicy sieci chcą skorzystać, musimy zainstalować dodatkowy program na serwerze zapewniający daną usługę.

Poniżej przedstawię dokładniejszy podział firewalli i ich cechy.

Tradycyjne proxy (Traditional proxies).

Pakiety z sieci prywatnej nigdy nie wychodzą do Internetu i vice versa. Adresy IP w sieci prywatnej powinny być z klas nierutowalnych. Jedyną drogą połączenia się z Internetem, jest wywołanie firewalla, ponieważ jest on jedyną maszyną mogącą łączyć się równocześnie z obiema sieciami. Uruchamiamy jest na nim program zwany proxy, który tego dokonuje. Dla każdej usługi która ma być dostępna z Internetu, na firewallu musi być uruchomiony osobny program pośredniczący w jej świadczeniu.

Komputery w sieci wewnętrznej muszą być specjalnie skonfigurowane do uzyskania dostępu do wybranych usług. Przykładowo, aby ściągnąć stronę WWW, muszą połączyć się z firewallem na port 8080 i zażądać potrzebnej strony. W tym momencie uruchamia się odpowiedni program pośredniczący, ściąga potrzebne dane i przekazuje do odpowiedniego komputera w sieci lokalnej.

Przezroczyste proxy (Transparent proxies).

Pakiety z sieci prywatnej nigdy nie wychodzą do Internetu i vice versa. Adresy IP w sieci prywatnej powinny być z klas nierutowalnych. Jedyną drogą połączenia się z Internetem, jest wywołanie firewalla, ponieważ jest on jedyną maszyną mogącą łączyć się równocześnie z obiema sieciami. Uruchamiamy na nim program zwany transparent proxy, który tego dokonuje. Jądro Linuksa kieruje pakiety do tego programu, zamiast wysłać je bezpośrednio do Internetu. Dla każdej usługi która ma być dostępna z Internetu, na firewallu musi być uruchomiony osobny program pośredniczący w świadczeniu  takiej usługi.

Przezroczyste proxy oznacza, że klient nie musi wiedzieć o użyciu oprogramowania typu proxy i nie musi być specjalnie konfigurowany. Przykładowo: firewall jest skonfigurowany do przekierowywania (za pomocą komendy ipchains) wszystkich połączeń do portu 80 na port 8080 na którym pracuje tranparent proxy. Przy próbie pobrania dowolnej strony WWW, transmisja przekierowywana jest na port 8080, a następnie wszystko odbywa się jak w poprzednim przykładzie.

Tłumaczenie adresów IP (NAT lub Masquerading).

Pakiety z sieci prywatnej nigdy nie wychodzą do Internetu bez specjalnej obróbki i vice versa. Adresy IP w sieci prywatnej powinny być z klas nierutowalnych. W tym przypadku używamy specjalnych funkcji jądra Linuksa nazywanych  opisanych we wcześniejszych rozdziałach.  Masquerading ma wydzielone moduły do radzenia sobie ze skomplikowanymi protokołami jak FTP, RealAudio, Quake, itp.

Sieć publiczna.

W tym przypadku, nasza sieć jest częścią Internetu, pakiety mogą poruszać się bez zmian poprzez obie sieci. Filtrowanie pakietów jest użyte aby ograniczyć dostęp z Internetu tylko do naszych wewnętrznych serwerów i uniemożliwić dostęp do komputerów użytkowników. Ten typ firewalla ma najmniejsze możliwości kontroli i autoryzacji dostępu, ale jest równocześnie najbardziej elastyczny i wprowadza najmniej ograniczeń dla użytkowników z sieci wewnętrznej.



9.3 Obsługa filtrowania pakietów w Linuksie przez jądro w wersji 2.2 [11i].

W tym podrozdziale zamieszczam skrócony opis obiegu datagramów IP w jadrach wersji 2.2. Następny podrozdział jest poświęcony projektowi netfilter i opisuje działanie komendy iptables używanej w jadrach wersji 2.4.

Komenda ipchains jest linuksową komendą używaną do konfiguracji reguł firewalla i tłumaczenia adresów IP (NAT). Zastąpiła ona starszą ipfwadm. Aby móc wykorzystać komputer z systemem operacyjnym Linux do filtrowania pakietów należy skompilować jądro systemu z opcjami (dla jądra z serii 2.1 lub 2.2):

CONFIG_FIREWALL = y

CONFIG_IP_FIREWALL = y

W nowszych jądrach mogą to być inne parametry konfiguracyjne. Aby stwierdzić czy jądro ma prawidłowo wkompilowaną obsługę filtrowania datagramów, należy sprawdzić czy w katalogu /proc/net/ istnieje plik ip_fwchains, zawierający konfigurację reguł ipchains.

Przy konfigurowaniu firewalla za pomocą komendy ipchains, podstawowym pojęciem jest łańcuch (chain). Łańcuch jest to zbiór reguł filtrujących. Istnieją trzy standardowe łańcuchy: input, forward i output, ponadto użytkownik może tworzyć własne łańcuchy.

HOME


Algorytm podejmowania decyzji o losie datagramu.

 

Rys. 9.1 Algorytm przechodzenia pakietów przez system.

Droga datagramów IP poprzez firewall jest bardzo skomplikowana. Najważniejsze etapy zostały zaznaczone pogrubioną czcionką na powyższym schemacie.

Najpierw sprawdzana jest suma kontrolna datagramów (checksum), następnie testowane są one pod kątem deformacji (sanity). Później pakiety przechodzą przez łańcuch wejściowy (input chain) i jeśli trzeba podlegają procesowi NAT (demasquerade), czyli adres rutera usuwany jest z pola „adres docelowy” i zastępowany adresem IP komputera w sieci prywatnej. Dalej na podstawie tablicy rutingu (routing decision) lub protokołu rutującego podejmowana jest decyzja o dalszym losie pakietu. Procesy lokalne (local process) mogą odbierać pakiety po etapie rutowania i wysyłać pakiety poprzez etap rutowania i łańcuch wyjściowy (output chain). Jeśli pakiety nie są utworzone przez procesy lokalne, są sprawdzane w łańcuchu przejściowym (forward chain). Jeśli pakiety od procesów lokalnych są przekazywane do  lokalnego komputera (localhosta) przechodzą przez łańcuch wyjściowy (output chains) do interfejsu lo (lo interface - loopback). Wszystkie pakiety wydostające się z komputera muszą przejść przez łańcuch wyjściowy (output chain).



Składnia polecenia ipchains [11i].

Pokrótce przedstawię podstawową składnię polecenia ipchains. Skupię się na opcjach użytych w plikach konfiguracyjnych na ruterze. Dokładny opis pozostałych opcji znajduje się w publikacji Ipchains_HOWTO [11i].

Po poleceniu ipchains następuje opcja określająca działanie całej komendy.

-F        (Flush) – usuwa wpisy z wymienionego później łańcucha.

-A        (Append) dodaje nową regułę do łańcucha.

-I         (Insert) wstawia nową regułę do łańcucha na podane miejsce.

-D        (Delete) usuwa regułę z łańcucha.

Następnie występują wpisy określające źródło i cel transmisji

-s         (source) źródło.

-d         (destination) cel.

Adresy mogą być podawane jako nr IP lub nazwa oraz jako zakresy, np.:

199.95.207.0/24

199.95.207.0/255.255.255.0 

Większość opcji umożliwia operację negacji logicznej np.: „-s ! localhost” oznacza wszystkie hosty poza lokalnym. Protokół może być podawany jako numer lub nazwa (tcp, udp, icmp), nie jest ważne czy małe czy też duże litery.

            -p udp

Można również podawać numer portu dla którego układamy regułę:

-p TCP -s 0.0.0.0/0 1023 

Zakres portów:

-p TCP -s 0.0.0.0/0 1010:1023

-p TCP -s 0.0.0.0/0 :1023                  - wszystkie porty poniżej 1023

Równie dobrze możemy podać nazwę portu:

-p TCP -s 0.0.0.0/0 www

Określamy interfejs sieciowy, którego dotyczy reguła.

-i eth0

-i eth+              oznacza wszystkie interfejsy zaczynające się na eth.

Logowanie pakietów, flaga -l   .

Flaga -j specyfikuje co wykonać z pakietem pasującym do reguły. Jeśli nie ma tej flagi, to reguła jest używana do prostego zliczania pakietów ją spełniających. Działaniami które możemy zlecić są:

ACCEPT         - pozwala przejść pakietom przez firewalla.

DENY             - likwiduje pakiety, tak jakby nigdy nie doszły do firewalla.

REJECT          - likwiduje pakiety, (jeśli nie są to pakiety ICMP) wysyłając komunikat ICMP o nieosiągalności celu.

MASQ            - stosuje NAT (jądro musi być skompilowane z IP Masquerading enabled). Prawidłowe jedynie dla łańcucha forward.

REDIRECT     - przesyła pakiet na lokalny port, zamiast podanego w nagłówku. Używane tylko dla protokołów TCP i UDP. Numer portu może być podany po REDIRECT co przesyła pakiety na konkretny port. To działanie jest prawidłowe tyko dla łańcucha input (wejściowego).

RETURN        - jest identyczny z natychmiastowym osiągnięciem końca łańcucha.

Ustalamy politykę dla łańcucha. Polityka określa co należy zrobić z pakietem nie pasującym do żadnej z reguł.

ipchains -P input DENY

Tutaj znajdziesz moje prywatne tłumaczenie ipchains-howto. Nie jest ono przygotowane do publikacji i nigdy nie miałem zamiaru go publikować, ponieważ jednak i tak różnymi drogami pojawiło się w sieci, więc pozwolę je sobie również tutaj zamieścić.


9.4 Pakiet netfilter - obsługa filtrowania pakietów w Linuksie przez jądro w wersji 2.4 (komenda iptables)

Jeśli będziesz miał jakieś uwagi i komentarze to nie krępuj się i napisz: gallegher@w.pl

Polskie tłumaczenie howto do iptables znadziesz tutaj. Powinieneś je przeczytać najpierw, zanim zaczniesz czytać dalszy ciąg tego działu. Przeczytaj również pozostałe tłumaczenia pojawiające się na stronie Łukasza Bromirskiego - naprawdę warto. Zajrzyj również na stronę domową pakietu netfilter.

Taaaak. Widziałem, że nie będzie ci się chciało czytać takiej ilości tekstu. Dobrze omówię bardzo oględnie jak wędrują pakiety w jądrze 2.4 - nie będę omawiał składni komendy iptables. Jesli coś wyda ci się niejasne, zajrzyj do howto, lub na stronę manuala iptables.

Podstawowym pojęciem jest łańcuch (chain). Łańcuch jest to zbiór reguł filtrujących. Istnieją trzy standardowe łańcuchy: input, forward i output; łańcuchy dodatkowe prerouting i forward; ponadto użytkownik może tworzyć własne łańcuchy. Łańcuch jest listą reguł do których po kolei jest porównywany pakiet. Jeśli pakiet pasuje do którejś z reguł, wykonywana jest akcja zdefiniowana wewnatrz tej reguły. Reguły definiujemy właśnie komendą iptables. Jeśli pakiet nie pasuje do żadnej reguły wykonywana jest akcja zdefiniowana w polityce danego łańcucha. Tylko łańcuchy podstawowe i dodatkowe mają własną politykę, łańcuchy utworzone przez użytkownika nie mają własnej polityki, a pakiet po przejściu przez taki łańcuch wraca do łańcucha z którego został wywołany.


                       ______
                      /      \
>---[ PREROUTING ]---ruting )---[ FORWARD ]---+---[ POSTROUTING ]--->
                      \______/                  |
                         |                      |
                         V                      |
                     [ INPUT ]              [ OUTPUT ]
                         |                      ^
                         |                      |
                         +--> procesy lokalne --+

Pakiet sprawdzany jest najpierw w łańcuchu PREROUTING. Następnie podjemowana jest decyzja czy pakiet skierowany jest do komputera lokalnego i wtedy przechodzi przez łańcuch INPUT i dociera do procesów lokalnych, czy też do jednej z sieci, do których dany komputer jest ruterem. W takim wypadku podejmowana jest decyzja o rutingu danego pakietu (w uproszczeniu - definiowana karta sieciowa przez którą należy dany pakiet dalej przesłać) i pakiet trafia do łańcucha FORWARD. Pakiety wygenerowane przez procesy lokalne (np. przeglądarkę www wysylającą zapytanie o stronę) przechodzą przez łańcuch OUTPUT. Następnie wszystkie pakiety przechodzą przez łańcuch POSTROUTING i są wysyłane na karty sieciowe.

Tak naprawdę to podstawowe łąńcuchy należą do tabeli filter. Jest to główna tabela służąca do definiowania reguł filtrowania pakietów. Dodatkowo istnieje tabela nat, w której definiujemy popularną "maskaradę" oraz tabela mangle służąca do zmieniania zawartości pakietów przechodzących przez nasz firewall. Nie wszystkie łańcuchy istnieją w poszczególnych tabelach.

Do tabeli "mangle" (komenda: iptables -t mangle ...) należą łańcuchy:
      PREROUTING
      OUTPUT

Do tabeli "nat" (komenda: iptables -t nat ...) należą łańcuchy:
      PREROUTING - DNAT (destination nat) podmieniany jest adres docelowy pakietów
      POSTROUTING - SNAT (source nat) podmieniany jest adres źródłowy pakietów
      OUTPUT - DNAT dla pakietów generowanych przez procesy lokalne

Defaultową tabelą jest "filter" (komenda: iptables ... - nie trzeba używać przełącznika -t), należą do niej łańcuchy:
      INPUT
      OUTPUT
      FORWARD

Kolejność przechodzenia pakietów przez tabele: mangle -> nat -> filter.


Tworzenie firewalla - wstęp.

Postanowiłem omówić tworzenie firewalla, na konkretnym, praktycznym przykładzie. Zakładam, że masz komputer podpięty do jakiegoś rodzaju łącza stałego. Oczywiście potrzebujesz firewalla. Zawsze najlepszym wyjsciem, jest gdy firewall jest dedykowanym serwerem na którym nie ma uruchomionych żadnych dodatkowych usług. Dzięki temu nie ma możliwości (przynajmniej teoretycznie) włamu do niego. Brzmi to bardzo poważnie, ale tak naprawdę nie będzie zbyt dużo kosztowało. Wystarczy stare 486DX i jakieś 16MB RAM-u, czasem mozna dostać cos takiego za piwo od kogoś kto się chce pozbyć. Jeśli nie masz dysku twardego, to możesz poszukać jakiejs jednodyskietkowej dystrybucji Linuxa lub BSD przystosowanej do pełnienia roli rutera i firewalla. Jednak wtedy najpewniej nie będziesz mógł skorzystac z konfiguracji opisanej poniżej - wersje jednodyskietkowe Linuksów są wykonywane najczęściej na jadrach serii 2.2, czyli możesz korzystac z komendy ipchains. Jeśli chodzi o dystrybucję, to polecam Slackware - spójrz na porównanie statystyk "dziur" dla tego systemu i np. dla RedHata. Nie będę tutaj opisywał sposobu instalacji Linuksa, istnieje na ten temat zbyt wiele wyspecjalizowanych stron. Główną zasadą jest instalowanie jedynie niezbędnych pakietów. W ten sposób zmniejszasz prawdopodobieństwo, że w przyszłości w jednym z zainstalowanych przez ciebie pakietów zostanie odkryta jakaś dziura - im mniej pakietów zainstalowanych tym mniejsze prawdopodobieństwo wykrycia dziury.

OK. Przejdźmy do sedna. Jednym z problemów może być umowa, którą podpisałeś ze swoim dostawcą usług (ISP). Najczęściej jest w niej paragraf mówiący, że możesz uruchomić tylko jeden terminal z dostępem do Internetu. Uważam jednak, że jeśli uruchomisz jeden dodatkowy komputer jako firewall, z którego nie będziesz korzystał jak z terminala dostępowego do Internetu, to nie łamiesz ducha umowy (byćmoże łamiesz literę - nie jestem prawnikiem). W opisanej przeze mnie konfiguracji opiszę jak utrudnić Adminom ISP wykrycie działajacej u ciebie maskarady (a dokładniej NATu) i firewalla. Oczywiście opiszę konfigurację dla udostepniania łącza dla jednego komputera - aby uruchomić udostepnianie dla wiekszej ilości maszyn bedziesz musiał sam trochę pomyśleć. Jeśli uda ci się przerobić podaną przeze mnie konfigurację, to znaczy że i tak dałbyś radę to zrobić sam, w tym wypadku nie będę się czuł winny złamania przez ciebie umowy. Poza tym wyraźnie piszę: każdy uruchamia podane przeze mnie skrypty na własną odpowiedzialność.

Mam nadzieję, że przeczytałeś poprzednie rozdziały mojej strony - sieci.krysiak.info, ponieważ aby zrozumieć działanie podanych niżej skryptów będziesz potrzebował tej wiedzy.


Tworzenie firewalla - podstawy.

Ruter (i firewall), który konfigurujemy ma dwie karty sieciowe jedną - eth0 - na zewnątrz z numerem IP przydzielonym przez naszego dostawcę usług i drugą - eth1 - do naszej sieci lokalnej, której IP sami sobie konfigurujemy. Jesli masz łacze SDI to najprawdopodobniej musisz wymienić wpisy eth0 na ppp0.

eth0
przydzielony numer IP: 111.222.333.444
z maską 24 bity czyli 255.255.255.0
gateway (ruter): 111.222.333.1

eth1
przyjmujemy numer IP: 192.168.1.1
z maską 30 bitów 255.255.255.252

komputer w sieci wewnętrznej konfigurujemy:
numer IP: 192.168.1.2
z maską 255.255.255.252
gateway (ruter): 192.168.1.1
serwery DNS ustawiamy na zalecane przez dostawcę usług.

W przypadku Slackware'a wyremowałem (postawiłem na początku linii #) ze skryptu /etc/rc.d/rc.inet1 wszystko poza linią:

# poczatek skryptu /etc/rc.d/rc.inet1
HOSTNAME=`cat /etc/HOSTNAME`

Następnie konfigurujemy standardowe urządzenie lo.

/sbin/ifconfig lo 127.0.0.1
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo

W moim przypadku włączamy potrzebne moduły do kart sieciowych 3Com:

/sbin/modprobe 3c509

A nastepnie przechodzimy do konfiguracji tychże kart sieciowych i rutingu.

/sbin/ifconfig eth0 111.222.333.444 netmask 255.255.255.0 broadcast 111.222.333.255 up
/sbin/route add default gw 111.222.333.1
/sbin/ifconfig eth1 192.168.1.1 netmask 255.255.255.252 broadcast 192.168.1.3 up

Dalej musimy włączyć NAT (czyli taką "lepszą maskaradę")

modprobe ip_conntrack_irc
modprobe ip_nat_irc

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source=111.222.333.444
echo "1" > /proc/sys/net/ipv4/ip_forward
/etc/rc.d/firewall.start
/usr/local/sbin/sshd
# koniec skryptu /etc/rc.d/rc.inet1

Komendami modprobe właczamy moduły do irca (jeśli będą nam potrzebne). Komenda iptables uruchamia nam SNAT pakietów, który podmienia adres źródłowy pakietów z naszej sieci wewnetrznej na adres 111.222.333.444. W tym momencie pakiety z naszego komputera o adresie 192.168.1.2 wychodząc w Internet (z karty eth0) wydają się pochodzić z adresu 111.222.333.444. Aby to zadziałało musimy jeszcze uruchomić proces rutingu - dzieje się to w następnej linii. Nastepnie uruchamiamy nasz skrypt firewall.start. Na koniec uruchamiamy demona ssh (najlepiej w wersji 2) abyśmy mogli administrować naszym ruterem z zewnątrz. W tym momencie zaczynamy pisanie skryptu firewalla /etc/rc.d/firewall.start .


 

Tworzenie firewalla - konfiguracja.

Podstawową zasadą przy pisaniu reguł firewalla jest: najpierw stawiamy barierę nie do przebycia dla żadnych pakietów, a następnie wybijamy w niej przejścia tylko dla takiego ruchu, który chcemy przepuścić.

W skrócie: co nie jest dozwolone - jest zabronione. Czyli po pierwsze wybieramy połączenia które będą możliwe do naszego rutera z Internetu. Poza tym tak naprawdę powinniśmy również ściśle zdefiniować połączenia które host z sieci wewnętrznej może dykonywać do Internetu oraz połączenia które komputer (komputery) z sieci lokalnej mogą wykonywać do rutera. W przypadku większej sieci tak właśnie się postępuje, jednak dla naszej sieci składającej się jedynie z komputerów zarządzanych osobiście przez 1 osobę, nie ma takiej potrzeby. Poza tym ograniczalibyśmy w ten sposób sobie samym dostęp do różnych usług. Jest oczywiście niebezpieczeństwo takiego postępowania, przykładowo w przypadku gdy na naszym komputerze pojawi się się jakiś trojan, przy silnie restrykcyjnym firewallu, gdy trojan próbowałby nawiązać połączenie na zewnątrz, zostałoby ono usunięte i mielibyśmy o tym informację w logach systemowych. Oznacza to, że na komputerze lokalnym nie możemy zaniedbać podstawowych zasad bezpieczeństwa i musimy zainstalować jakieś (często upgradowane) oprogramowanie antywirusowe.

Czyli zaczynamy. W katalogu /etc/rc.d/ tworzymy sobie skrypt firewall.start, który jest uruchamiany z pliku rc.local (jest to poprawne dla większości dystrybucji Linuksa). Moja konfiguracja została oparta na opisie ze strony: www.sns.ias.edu/~jns/security/iptables - oczywiście dokonałem w niej pewnych zmian. Nie będę tworzył skryptu sparametryzowanego - jest on zbyt mało przejrzysty dla ludzi nieobytych ze skryptami shellowymi, a ponadto gdy zaglądamy do niego po kilku miesiącach jest trudniejszy w analizie. Przed komendami iptables występującymi w skrypcie powinieneś dopisać pełną bezwzględną ścieżkę dostępu, np.: /usr/local/sbin/iptables ...

#!/bin/sh
#Poczatek skryptu /etc/rc.d/firewall.start

modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Najpierw próbujemy ładować moduły które mogą się nam przydać. Bardzo ważnym modułem jest conntrack umożliwiający śledzenie połączeń. Dzięki niemu możemy stwierdzić które pakiety nie są poprawnymi pakietami danego połączenia. Moduł conntack potrafi śledzić - poza oczywistym protokołem TCP, który jest protokołem połączeniowym) również protokoły UDP i ICMP. Lista aktualnie śledzonych polączeń znajduje się w pliku /proc/net/ip_conntrack. W ostatnich 3 liniach ustawiliśmy politykę podstawowych łańcuchów na DROP - w tym momencie nasz host nie odbiera i nie przepuszcza żadnych pakietów. Teraz wykonamy wstepną konfigurację parametrów jądra wpływających na działanie stosu TCP/IP.

# wylaczamy odpowiedzi na pingi
/bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
# ochrona przed atakiem typu Smurf
/bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Nie aktceptujemy pakietow "source route"
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
# Nie przyjmujemy pakietow ICMP rediect, ktore moga zmienic nasza tablice rutingu
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
# Wlaczamy ochrone przed blednymi komunikatami ICMP error
/bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# wszystkie karty nie beda przyjmowaly pakietow z sieci innych niz te z tablicy rutingu
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter;
# Wlacza logowanie dziwnych (spoofed, source routed, redirects) pakietow
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
# W kernelu 2.4 nie trzeba wlaczac opcji ip_always_defrag

W linii 2 informujemy nasz ruter, aby nie odpowiadał na zapytania ICMP echo - czyli ruter nie będzie odpowiadał na pingi.

W linii 4 uniemożliwiamy odpowiedzi ICMP echo na pakiety typu broadcast w efekcie czego bronimy się przed atakiem typu Smurf. Atak ten polega na tym, że atakujący wysyła pakiety ICMP echo request skierowane na adresy broadcastowe naszej sieci. Wszystkie komputery naszej sieci odpowiadaja na takie pakiety co najczęściej powoduje silne przeciążenie sieci. Bardzo często adres źródłowy takiego pakietu jest zmieniony i ustawiony na rzeczywistą ofiarę, która otrzymuje nagle dużo pakietów z odpowiedziami typu echo-reply. Jeśli w ten sposób zostanie zaatakowanych kilka podsieci, łącze ofiary może ulec zapchaniu.

W linii 6 powiadamiamy jądro systemu, aby nie akceptowało pakietów "source routed". Atakujący może użyć tego typu pakietów, aby udawać, że jest z wnętrza naszej sieci, lecz ruch ten byłby kierowany spowrotem wzdłuż ścieżki po której do nas dotarł. Technika ta rzadko jest używana w uzasadninych celach.

W linii 8 zabraniamy zmieniania naszej tablicy rutingu na podstawie pakietów ICMP redirect.

W linii 10 powodujemy, że nasz host nie będzie reagował na fałszywe komunikaty o błędach.

Standardowym mechanizmem jest ignorowanie pakietów pochodzących z sieci nie znajdujących się w naszej tablicy rutingu, co odbywa się w linii 12. Oznacza to, że jeśli na karcie eth1 jest zdefiniowana sieć 192.168.1.0/30 to nie przyjmie ona pakietów z adresu 10.1.23.32. Oczywiście karta eth0 będzie przyjmowała wszystkie pakiety, ponieważ jest poprzez nią dostęp do naszego gatewaya (rutera).

Linia 14 powoduje, że informacja o wszelakich dziwnych (podejrzanych) pakietach znajdzie się w logach systemowych.

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Pierwsze co umożliwiamy to ruch na urządzeniu lo, które jest wykorzystywane przez różne procesy lokalne. Na ten ruch nie stawiamy żadnych ograniczeń.

Poniżej tworzymy nowy łańcuch o nazwie syn-flood który będzie zabezpieczał nasz ruter przed atakami typu DoS. Oczywiście jest bardzo prawdopodobne, że bedziesz musiał dobrać (najczęściej eksperymentalnie) czułość działania modułu limit.

iptables -N syn-flood
iptables -A INPUT -i eth0 -p tcp --syn -j syn-flood
iptables -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A syn-flood -j LOG --log-level debug --log-prefix "IPT SYN-FLOOD: "

iptables -A syn-flood -j DROP

W pierwszej linii tworzymy łańcuch syn-flood. W drugiej linii powodujemy, że wszystkie pakiety protokołu TCP z ustawioną flagą syn pojawiające się na karcie sieciowej eth0 i wędrujace przez łańcuch INPUT (skierowane bezpośrednio do naszego rutera) będą skierowane do łańcucha syn-flood. Pakiety z ustawioną flagą syn (i w poprawnym połączeniu również ack) służą do nawiązywania połączenia. W linii 3 zaczynamy "zliczanie" tych pakietów. Jeżeli pojawi się więcej niż jeden na sekundę pakiet nawiązujący połączenie z naszym ruterem, to po czterech takich pakietach reguła 3 przestanie przerzucać pakiety spowrotem (-j RETURN) do łańcucha INPUT. W takim wypadku zostaną wykonane następne regułki. Reguła 4 spowoduje że informacja o takim pakiecie pojawi się w logach systemowych z przedrostkiem: "IPT SYN-FLOOD: ". Reguła 5 spowoduje, że pakiet taki zostanie skasowany bez żadnej dodatkowej reakcji ze strony naszego hosta TCP/IP. Przydało by się jeszcze ustawić ograniczenie limit na ilość pakietów zapisywaną do logów, bo w przypadku ataku DoS może nam się dysk trochę przepełnić, zwłaszcza że system może nie nadążyć zapisywać tego do logów. Poprawna postać linii nr 4: iptables -A syn-flood -m limit --limit 1/s --limit-burst 4 -j LOG --log-level debug --log-prefix "IPT SYN-FLOOD: ". Tutaj też możemy poeksperymentować z wartościami parametrów.

iptables -A INPUT -i eth0 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -o eth0 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Powyższe linijki zapewniają nam przepuszczanie nawiązanych połączeń protokołu icmp (linia 1) i nawiązywanie połączeń pochodzących z naszego hosta (linia 2).

iptables -A INPUT -i eth0 -p tcp ! --syn -m state --state NEW -j LOG --log-level debug --log-prefix "IPT NEW: "
iptables -A INPUT -i eth0 -p tcp ! --syn -m state --state NEW -j DROP

Powyższe linie wynikają z pewnej niekonsekwencji w implementacji modułu conntack służącego do śledzenia połączeń w pakiecie netfilter. Moduł ten uznaje pakiety TCP bez flagi syn, a z ustawioną flagą ack za kontynuujące połączenie i są one uznawane za pakiety NEW czyli nawiązujące połączenie. W 1 z powyższych linijek logujemy (zapisujemy do logów) pakiety uznane za NEW (--state NEW) bez ustawionej flagi syn ( ! --syn ). W kolejnej linii porzucamy takie pakiety.

iptables -A INPUT -i eth0 -f -j LOG --log-level debug --log-prefix "IPT FRAGMENTS: "
iptables -A INPUT -i eth0 -f -j DROP

Podobna konstrukcja zastosowana jest w powyższych regułkach. Pakiety sfragmentowane -f na wszelki wypadek (atak Jolt2) porzucamy, oczywiście uprzednio je logując. Jeśli w logach systemowych będziemy mieli wiele informacji o takich pakietach, to będziemy musieli wyłączyć te reguły.

Poniżej mamy małe zabezpieczenie anty-spoofingowe (przeciw podszywaniu się pod inne adresy niż własne). W sumie niepotrzebne, ale nigdy nie wiadomo czy nasz stos TCP/IP nie ma jeszcze nie wykrytych błędów.

#Pakiety z adr. zrodlowym ustawionym na nasz.
iptables -A INPUT -i eth0 -s 111.222.333.444 -j DROP
# Pakiety z adresow nierutowalnych, multicast i zarezerwowanych
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP     # class A
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP  # class B
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP # class C
iptables -A INPUT -i eth0 -s 224.0.0.0/4 -j DROP    # multicast
iptables -A INPUT -i eth0 -d 224.0.0.0/4 -j DROP    # multicast

iptables -A INPUT -i eth0 -s 240.0.0.0/5 -j DROP    # reserved
iptables -A INPUT -i eth0 -d 127.0.0.0/8 -j DROP    # na eth0 do loopbacka?
iptables -A INPUT -i eth0 -d 111.222.333.255 -j DROP # broadcasty
iptables -A INPUT -i eth1 -p udp -d 192.168.1.255 --dport 137:138 -j DROP

Powyższe regułki nie powinny nastręczać wątpliwości. Na karcie eth0 nie powinny się pojawić pakiety z pochodzące z:
linia 2: naszego własnego adresu
linie 4-9: adresów zarezerwowanych
linia 10: pakiety z adresu interfejsu wewnętrznego lo
linia 11: poza tym wycinamy pakiety skierowane do wszystkich komputerów w naszej podsieci - najczęściej nie są zbyt ciekawe; w razie kłopotów nalezy wyremować tą linijkę.
Niestety najczęściej komputer którego bedziemy używali w naszej sieci lokalnej, będzie miał system operacyjny pewnej znanej wszystkim firmy. System ten silnie "śmieci" (wysyła wiele broadcastów IP protokołu UDP na porty 137 i 138) w wyniku enkapsulacji protokołu NetBIOS wewnątrz protokołu IP. Mam nadzieję, że wyłączyliscie protokół NetBIOS na karcie swojego komputera lokalnego? Abyśmy nie mieli logów systemowych zarzuconych informacjami o działalności tego protokołu, wpisujemy ostatnią z powyższych regułek. I w końcu dochodzimy do regułek definiujących jakie połączenia są możliwe do naszego komputera.

# lancuch INPUT
iptables -A INPUT -p tcp --sport 1024: --dport  22 -m state --state NEW -j ACCEPT   # ssh na obu kartach
iptables -A INPUT -p tcp --sport 1024: --dport 113 -m state --state NEW -j REJECT --reject-with icmp-port-unreachable   # identd
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j LOG --log-level debug --log-prefix "IPT INPUT: "
iptables -A INPUT -j DROP

Ponieważ w powyższych regułkach nie zdefiniowałem interfejsu sieciowego, będą one działały na obu kartach sieciowych w naszym ruterze. W drugiej linijce definiujemy regułkę mówiącą: pakiety protokołu tcp pochodzące z portów powyżej 1023 skierowane na port 22 (ssh) i uznane za NEW, czyli nawiazujące połączenie akceptujemy. Pozostałe pakiety dla połączenia nawiązanego za pomocą pakietu przepuszczonego przez regułkę nr 2 zostana przepuszczone przez regułkę w linii 4. Mówi ona: pakiety które uznasz za należące (ESTABLISHED) lub związane (RELATED) z juz istniejącym połączeniem zaakceptuj. Pakiety nie zaakceptowane przez te regułki zostaną zalogowane (regułka nr 5) i usunięte (regułka nr 6). Oczywiście gdyby nie było regułki nr 6 to zadziałała by polityka łańcucha INPUT ustawiona równiez na DROP ale troche paranoi nikomu nie zaszkodzi. Gdybyśmy uruchomili na naszym ruterze serwer WWW (czego oczywiście ze względów bezpieczeństwa nie polecam) wystarczyłoby skopiować regułkę nr 2, wkleić poniżej tej regułki (w linii poprzedzającej regułkę 4) i zmienić wartość portu 22 na 80. Przypominam, że numery portów znajdziesz w pliku /etc/services. Do wytłumaczenia pozostaje regułka nr 3. Bardzo czesto różne serwery usług (np ftp) pytają się hosta z którego sie łączymy o nasze dane za pomocą usługi ident działającej na porcie 113. Jeżeli nie byłoby regułki 3, przykładowy serwer FTP wysłałby pakiet na port 113 naszego rutera i czekał na odpowiedź. Ponieważ pakiet ten zostałby skasowany, nie otrzymałby żadnej odpowiedzi. W końcu otrzymalibyśmy zgode na połączenie, ale czas oczekiwania byłby dosyć długi. W linii 3 powodujemy, że na zapytania na port 113 protokołu TCP generowany jest pakiet protokołu ICMP z komunikatem: icmp-port-unreachable. Serwer FTP jest poinformowany że na naszym hoście usługa ident nie działa i juz bez dalszej zwłoki pozwala nam się zalogować. Zwróć również uwagę że dla protokołu UDP nie zostały zdefiniowane żadne regułki, ponieważ nie udostępniamy żadnych usług korzystających z tego protokołu. tak naprawde to udostepniamy jedynie ssh. Bardzo polecane byłoby zawężenie działania regułki 2 poprzez podanie numeru IP komputera z którego umożliwiamy połączenia na ssh.

# lancuch OUTPUT
iptables -A OUTPUT -m state --state ! INVALID -j ACCEPT
iptables -A OUTPUT -j LOG --log-level debug --log-prefix "IPT OUTPUT: "
iptables -A OUTPUT -j DROP

W tym łańcuchu powinniśmy również powinniśmy dokładnie zdefiniować połączenia które można nawiązywać z naszego rutera. Jednak w ten sposób sami sobie ograniczalibyśmy funkcjonalność naszego hosta. W przypadku profesjonalnego rutera dla większej podsieci nie należy zostawiać niczego przypadkowi, ale w naszym przypadku nie będziemy tacy dokładni. Regułka 2 akceptuje wszystkie poprawne pakiety. Składnia --state ! INVALID oznacza wszystkie pakiety nie zakwalifikowane jako NEW, ESTABLISHED ani RELATED. czyli uszkodzone. Regułka 3 powoduje logowanie odrzuconych pakietów,a regułka 4 ich usunięcie.

# lancuch forward
iptables -A FORWARD -i eth1 -p tcp -s 192.168.1.0/30 --sport 1024: -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -p udp -s 192.168.1.0/30 --sport 1024: -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -o eth1 -p tcp -d 192.168.1.0/30 --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -o eth1 -p udp -d 192.168.1.0/30 --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -p icmp -m state --state ! INVALID -j ACCEPT
iptables -A FORWARD -j LOG --log-level debug --log-prefix "IPT FORWARD: "
iptables -A FORWARD -j DROP

W łańcuchu FORWARD definiujemy regułki dotyczące pakietów wędrujących poprzez nasz ruter. Regułki 2 i 3 oznaczają: dla protokołów TCP i UDP wchodzących na kartę eth1 ( -i eth1 ) z sieci lokalnej 192.168.1.0/30 z portów powyżej 1023 przepuść pakiety nawiązujące połączenia, pakiety należące do istniejących połączeń i pakiety związane z istniejącymi połączeniami. Oznacza to że z sieci lokalnej możemy nawiązywac połączenia. Regułki 4 i 5 oznaczają: dla protokołów TCP i UDP wychodzących z karty eth1 ( -i eth1 ) do sieci lokalnej 192.168.1.0/30 na porty powyżej 1023 przepuść pakiety należące do istniejących połączeń i pakiety związane z istniejącymi połączeniami. W domysle nie przepuszczaj pakietów nawiązujących połączenia. Regułka 6 pozwala na niczym nie ograniczony ruch poprawnych pakietów protokołu ICMP. Jeśli pojawią się jakieś pakiety nie należące do istniejącego połączenia, nie zostaną one przepuszczone. Ostatnie dwie regułki, standardowo logują i wycinają wszystkie pozostałe pakiety.


Tworzenie firewalla - końcówka.

W tym momencie mamy działającego poprawnie firewalla. Należy tylko obserwować logi systemu i patrzeć co jest wycinane przez nasze regułki. Każdy wycięty pakiet będzie opatrzony przedrostkiem który zdefiniowaliśmy w regułkach --log-prefix "IPT FORWARD: " i dzięki temu łatwo dojdziemy gdzie się dzieje coś niedobrego. Przydało by się, abyśmy informacje o działaniu firewalla mieli w logach. W tym celu wpisujemy na koniec pliku /etc/syslog.conf coś takiego:

*.*           /dev/tty12
*.*           /var/log/all

i oczywiście restartujemy demona syslogd:

# killall -HUP syslogd

od tego momentu w pliku /var/log/all (oraz na konsoli12 - Alt+F12) będziemy mieli wszystkie logi systemowe. Należy uważać aby logi nam nie zapchały twardego dysku, czyli należy skonfigurować logrotate, ale to oczywiście znajdziecie już na stronach dotyczących konfiguracji Linuxa.

Teraz nastapi krótkie omówienie metod wykrywania przez Administaratorów sieci, uruchomionych komputerów z maskaradą. Oczywiście jeśli robisz coś takiego dla większej ilości komputerów niż 1 pamietaj, że łamiesz (najczęściej) warunki umowy. Do zrozumienia tego działu konieczna jest pewna wiedza nt. protokołu TCP/IP oraz procesu NAT. Teoretycznie proces NAT (czasem niezbyt poprawnie używam pojęcia maskarada) jest nie do wykrycia, w rzeczywistości jest wiele metod którymi może się posłużyć Admin aby stwierdzić, że dokonujemy czegoś takiego. Przykładowo może zajrzeć w pakiety TCP i np. stwierdzić, że wewnątrz nich adres źródłowy (np. przy protokole ICQ) komputera jest ustawiony na 192.168.1.2 (omawiam na przykładzie naszej instalacji). jednak takie działanie leży oczywiście w możliwościach Admina, jednak z punktu widzenia prawa jest nielegalne (nienaruszalność korespondencji, prywatność - było to gdzieś na grupach rozwijane i rzucane konkretne paragrafy) i nie może być użyte jako dowód przeciwko nam. Ogólnym wnioskiem z tych dyskusji było, że Admin może podglądac jedynie nagłówki protokołów IP i TCP, UDP, ICMP. Upraszczając można na ich podstawie wywnioskować o dokonywanej maskaradzie, jednak nie jest to nadal 100% dowód. Przykładowo maskarada wykonywana przez jądra serii 2.2 dokonywała połączeń z pewnego ściśle okreslonego zakresu portów zdefiniowanych w pliku: /usr/src/linux/include/net/ip_masq.h (dla jądra rozpakowanego w katalogu /usr/src/linux) w liniach o treści:

#define PORT_MASQ_BEGIN 61000
#define PORT_MASQ_END (PORT_MASQ_BEGIN+4096)

Oczywiście wystarczy zmienić te wartości i przekompilować jadro. W nowym jądrze 2.4 Możesz się teraz bindować do portów 61000-65095 nawet jeśli działa maskarada. Jej kod zakładał do tej pory że w tym zakresie portów mógł się rządzić, więc programy nie mogły go używać. Z moich obserwacji wynika, że w jądrach 2.4 NAT został rozwiązany poprawnie, alokuje porty od 1024 wzwyż (czyli tak jak powinien to robić normalny, pojedyńczy komputer. Dla procesów lokalnych również alokuje kolejne porty powyżej 1024 i nie gryzie się to z NATem.

Maskarada zmienia wartości nagłówka IP i protokołów niższych (TCP/UDP) (adres IP i numery portów, może coś jeszcze - nie sprawdzałem) co powoduje zmianę sum kontrolnych obu protokołów. Oczywiście aby to wykryć, Admin również musi przeczytać cały pakiet, do czego nie ma prawa. Czyli ponownie ma informację o używaniu NAT, ale nie może ona być dowodem przeciw nam. Ponadto są różne metody oparte na fingerprinting (wykrywaniu systemu operacyjnego) i porównaniu z np. rodzajem przeglądarki WWW raportowanej przez protokół HTTP (np. jeśli host wygląda jak Linux, a przeglądarką jest MS IE, to sprawa jest prosta), jednak są one równiez nielegalne. Podobno niedługo - po dostosowaniu polskiego prawa do Unii Europejskiej - samo posiadanie narzędzi mogących służyć włamywania się na inne komputer (np.: skaner portów) będzie karalne, ale to taka mała dygresja. Myślę, że po analizie działania protokołów TCP/IP, protokołów warstw wyższych można wymyślić jeszcze wiele metod na wykrywanie NAT, jeśli ktoś zna jeszcze jakieś sposoby to proszę o kontakt, chetnie rozwinę watek, a materiały otrzymane zamieszczeę oczywiscie z podaniem autora.

Poniżej zamieszczam cytat z grup dyskusyjnych, opisujący jeszcze jedną metodę wykrywania NATu. Może trochę pracochłonną, ale również szkuteczną. Niestety nie zapisałem autora tego opisu, więc jeśli ktoś się poczuwa to proszę okontakt.

1) Jak Można sprawdzić, czy komputer podejrzanego ma włączony ip_forwarding.

Na Twoim routerze:
# route add -net 1.2.3.0/24 gw podejrzany eth0
# ping 1.2.3.4

Na drugiej konsoli:
# tcpdump -n -i eth0
00:59:47:270862 > v.x.y.z > 1.2.3.4: icmp: echo request
00:59:47:271276 < v.x.y.z > 1.2.3.4: icmp: echo request

No prosze... podejrzany odbił pakiet na swoją trasę domyślną, czyli do Ciebie ;>

2) Jeśli już wiesz, że ma ip_forwarding, możesz sprobować dowiedzieć się, jaki wybrał adres podsieci. Można to zrobić podobnie jak w pierwszym punkcie. Na przykład

# route add -net 10.1.1.0/24 gw podejrzany eth0
# ping 10.1.1.1 // albo lepiej: 10.1.1.255

Jeśli 10.1.1.0/24 nie jest jego siecią, stanie się to samo co w 1)
Jeśli jest, dostaniesz:
- icmp echo reply - jeśli trafiłeś w działającego hosta
- icmp host unreachable - jeśli nie ma takiego hosta
albo coś innego, ale na pewno pakiet `icmp echo request' nie wróci do ciebie

OK. Po takiej dawce możemy przejść do konkretów. Ponieważ jądro 2.4 sensownie posługuje się portami, więc tym się nie musimy martwić. Jest jeszcze jeden, w 99% pewny sposób na wykrycie NAT. Po prostu nasz firewall jest oczywiście ruterem, a każdy ruter ma obowiązek zmniejszać pole TTL w nagłówku IP o 1. Uwzględniając, że komputery z systemem M$ Windows wysyłają pakiety z TTL=128, to pakiety te na naszej karcie eth0 będą miały już ustawiony TTL=127. Można to sprawdzić prostą komendą:

# tcpdump -v -n -i eth0

Pakiety generowane lokalnie przez nasz ruter mają ustawioną wartość TTL=64 (tak jest przynajmniej u mnie). Aby zwiększyć wartość pola TTL o jeden, czyli ukryć fakt przechodzenia pakietów przez ruter, na końcu naszego skryptu konfigurującego firewalla dodajemy linijkę:

# Zwiekszamy o 1 pole TTL pakietow przechodzacych przez nasz NAT
iptables -t mangle -A PREROUTING -s 192.168.1.0/30 -j TTL --ttl-inc 1

Zmiana wartości TTL odbywa się w tabeli mangle (-t mangle) w łańcuchu PREROUTING. Nie możemy wykorzystać łańcucha OUTPUT tej tabeli (innych łańcuchów ona nie posiada) ponieważ zmieniałby on tylko pakiety wychodzące z rutera, a nie przechodzące przez niego. Ograniczamy pakiety zmieniane przez regułkę do pochodzących z naszego komputera 192.168.1.2 na którym dokonujemy procesu NAT. Niestety najprawdopodobniej nie sprowadzi się to do wpisania dodatkowej regułki do pliku konfigurującego firewalla. Najczęściej w dystrybucjach Linuxa, pakiet iptables jest bez patcha udostepniającego opcję -j TTL. Aby ją włączyć będziemy musieli sciagnąć źródła pakietu iptables, spatchować nasze jądro za pomocą patchy zawartych w pakiecie iptables, skompilować i zainstalować nowe jądro oraz skompilować samo iptables. Oczywiście wcześniej najlepiej jest usunąć pakiet iptables, który mieliśmy zainstalowany wraz z naszą dystrybucją Linuxa.

Pakiet iptables sciagamy ze strony domowej projektu netfilter. Należy zajrzeć do FAQ i z podanych tam adresów ściągnąć iptables. Następnie przeczytać rozdział dotyczący patch-o-matic. Jest to system patchy do iptables, jednym z nich jest właśnie patch TTL. Rozpakowujemy iptables i kompilujemy patche:

# tar -xvzf iptables-1.2.4.tar.bz2
# cd iptables-1.2.4
# make patch-o-matic

Otrzymamy listę pytań, najpierw o położenie źródeł jądra które chcemy spatchować, a następnie o to czy chcemy uzyć kolejnych patchy zawartych w patch-o-matic. Powinniście wybrać te związane z TTL (może równiez inne, jesli wam sie sposobaja ich możliwosci). Nastepnie skompilować i zainstalować samo iptables:

# make
# make install

Później czeka nas konfiguracja, kompilacja i instalacja nowego jądra, ale tego już nie będę omawiał. Pamietajcie jedynie, aby przy konfiguracji jądra zaznaczyć (chociaż jako moduły) elementy dotyczące iptables (a zwłaszcza TTL). Oczywiście nie wszystkie musicie wkompilowywać bezpośrednio w jadro, ale to już od was zależy.


Tworzenie firewalla - Direct Connect.

W trakcie używania skryptu okazało się, że są problemy z działaniem programu DirectConnect na komputerze lokalnym. Przy DC ustawionym w tryb pasywny, transfery z komputera lokalnego odbywaja się protokołem tcp z wysokich portów, na porty 411,412.

-p tcp -s 192.168.1.2 --sport 1024: -d IP --dport 411:412
-p tcp -d 192.168.1.2 --dport 1024: -s IP --sport 411:412

Czyli nie ma problemów, transfery przechodzą przez naszego firewalla. Jednak należało dodać regułki przepuszczające połączenia po protokole UDP.

iptables -A FORWARD -i eth1 -p udp -s 192.168.1.0/30 --sport 411:413 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -o eth1 -p udp -d 192.168.1.0/30 --sport 411:413 -m state --state ESTABLISHED,RELATED -j ACCEPT

Obsługę trybu aktywnego w DC opiszę jak już ją uruchomię, a to może potrwać. Zwłaszcza, że w pasywnym działa i nie jestem zmuszony tego robić.

Tworzenie firewalla - ustawianie bitów TOS.

Nieżle byłoby zapewnić naszym pakietom jakiś priorytet w Internecie. Ponieważ TCP/IP nie jest protokołem implementującym zbyt dobrze QoS (Quality of Service) oraz w rzeczywistości tylko niektóre rutery w sieci spełniają założenia RFC więc nie spodziewaj się cudów, ale nie zaszkodzi poustawiać bity TOS (Type of Service) w nagłówku protokołu IP. Parametry podane poniżej zgodne są z zaleceniami RFC 1060/1349, jeśli ktoś byłby na tyle zawzięty by to sprawdzać. Po wpisaniu: iptables -m tos -h otrzymujemy listę proponowanych wartości bitów TOS:

                    dec ( hex)
Minimize-Delay       16 (0x10)
Maximize-Throughput   8 (0x08)
Maximize-Reliability  4 (0x04)
Minimize-Cost         2 (0x02)
Normal-Service        0 (0x00)

Na podstawie tych wartości dopisujemy na końcu naszego skryptu /etc/rc.d/firewall.start poniższe linijki:

# ustawiamy odpowiednio bity TOS w naglowku IP
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 20 -j TOS --set-tos 8
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 21 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 22 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 23 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 25 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 53 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p udp -s 192.168.1.0/24 --dport 53 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 80 -j TOS --set-tos 8
iptables -t mangle -A PREROUTING -p udp -s 192.168.1.0/24 --sport 411:413 -j TOS --set-tos 16 # DC
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.0/24 --dport 411:413 -j TOS --set-tos 8 # DC

Ostatnie dwie linijki dotyczą transmisji Direct Connect i są na razie dobrane eksperymentalnie. Aby podejrzeć zawartość tabeli mangle wpisujemy: iptables -L -t mangle.Dla połączeń z komputera lokalnego również możemy poustawiać TOS.

iptables -t mangle -A OUTPUT -p tcp --dport 20 -j TOS --set-tos 8
iptables -t mangle -A OUTPUT -p tcp --dport 21 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p tcp --dport 23 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p tcp --dport 25 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p tcp --dport 53 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p udp --dport 53 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j TOS --set-tos 8


Tworzenie firewalla - skrypt  /etc/rc.d/firewall.stop

Poniżej zamieszczam zawartość skryptu czyszczącego naszego firewalla. Pamiętaj, że po użyciu tego skryptu nadal działa NAT uruchomiony w skrypcie /etc/rc.d/rc.inet1, czyli komputer 192.168.1.2 ma ciągle dostęp do Internetu.

/etc/rc.d/firewall.stop

iptables -F
iptables -t mangle -F

iptables -P FORWARD ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -X syn-flood
/bin/echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all
/bin/echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/accept_source_route
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/accept_redirects
/bin/echo "0" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter;
/bin/echo "0" > /proc/sys/net/ipv4/conf/all/log_martians

Sieci  komputerowe 
Kompendium 

Karol Krysiak

Sieci komputerowe. Kompendium.

Włóż do koszyka

Więcej informacji