Wstęp

Przed każdym początkującym dministratorem systemu komputerowego prędzej czy później stanie problem zapewnienia bezpieczeństwa swojemu systemowi (zaawansowani administratorzy mają o już we krwi). Jak podkreślają specjaliści "komputer dobrze zabezpieczony to komputer wyłączony" :). Jednak stosunkowo małym nakładem sił można swojego Linuksa wyposażyć w profesjonalne narzędzie. Iptables, bo tak nazywa się program, jest następcą popularnego Ipchains'a. Jest na standardowym wyposażeniu Linuksów z jądrem 2.4.

Opisane przykłady sprawdzałem dla systemu Linuks RedHat 7.1 (ta dystrybucja jest najbliższa sercu memu). W innych dystrybucjach mogą występować drobne różnice w sposobie uruchamiania programu.

 

Szybki start

 

Rys. 1. Zasada pracy Iptables'a

 

Jądro rozpoczyna pracę z trzema predefiniowanymi listami reguł w tabeli filtrującej. Są to łańcuchy INPUT (wejściowy), OUTPUT (wyjściowy) i FORWARD (przekazujący). Każdy pakiet docierający do hosta jest sprawdzany pod kątem miejsca przeznaczenia. Na tej podstawie kernel decyduje, czy ma zostać przekazany do sieci położonej gdzieś dalej czy skierowany do niego samego. Pakiet skierowany do tego komputera pozostaje "przetrawiony" przez reguły łańcucha INPUT. Jeżeli jego obecność zostanie tu zaakceptowana, pakiet będzie dopuszczony do procesu, do którego został skierowany. W przeciwnym wypadku zostanie odrzucony. Jeżeli posiadasz włączone przekazywanie pakietów i pakiet jest przeznaczony dla innego interfejsu sieciowego, pakiet przechodzi przez zestaw reguł łańcucha FORWARD. Reguły łańcucha zadecydują, czy może zostać przesłany dalej czy zostać odrzucony. Procesu uruchamiane na naszym hoscie także mogą być źródłem pakietów wydostających się do Internetu. Takie pakiety przechodzą przez łańcuch OUTPUT. Po akceptacji docierają do interfejsu sieciowego.

Nie będę opisywał tu dokładnie używania Iptables. Od tego jest man iptables. Jednak dla lepszego zrozumienia przedstawionych dalej przykładów opisze podstawowe operacje na łańcuchach.

Zmiana zasady dla wbudowanego łańcucha (-P).

Listowanie reguł w łańcuchu (-L).

Utworzenie nowego łańcucha (-F).

Wyczyszczenie reguł z łańcucha (-F).

Dodanie nowej reguły do łańcucha (-A).

Wstawienie reguły do łańcucha na określoną pozycję (-I).

Wymiana reguły na określonej pozycji (-R).

Skasowanie reguły (-D).

Skasowanie pustego łańcucha (-X).

Zerowanie liczników w łańcuchu (-Z).

Opcje filtrowania.

Użycie reguły dla konkretnego protokołu (-p).

Określenie adresu źródłowego pakietu (-s).

Określenie adresu docelowego pakietu (-d).

Określenie interfejsu sieciowego (-i).

Określenie portu źródłowego i docelowego odpowiednio (--sport i --dport).

Więcej opcji można znaleźć na stronach podręcznika systemowego man iptables. Ja na przykładach opiszę te najciekawsze.

 

Jedziemy z tym koksem!

Na wstępie podkreślam, że opisane powyżej reguły są tylko przykładem. Politykę bezpieczeństwa, a co za tym idzie wszelkie reguły np. filtrowania pakietów, należy rozpatrywać osobno dla każdego hosta w sieci. Użyte przeze mnie przykłady adresów IP należy zastąpić adresami wynikającymi z własnych potrzeb

Dla przykładu zakładamy, że mamy komputer, na którym pracuje serwer http, ftp z dostępem do sieci Internet bez przyłączonych sieci wewnętrznych.

Na płytkach z dystrybucją RedHat 7.1 znajduje się wersja iptables-1.2.1a-1. Jeżeli nie mamy jeszcze tego pakietu zainstalowanego to najwyższy czas to zrobić.

 

#rpm -i iptables-1.2.1a-1.rpm

 

Zaczynamy od załadowania modułów śledzenia połączeń (o ile nie mamy ich już wbudowanych w jądro).

 

#insmod ip_conntrack

#insmod ip_conntrack_ftp

 

Możemy zacząć ustalać politykę bezpieczeństwa naszego systemu. Na dobry początek blokujemy wszystko co przychodzi do naszej maszyny. Pozostawiamy tylko ruch wychodzący.

 

1) #iptables -P INPUT -j DROP

2) #iptables -P FORWARD -j DROP

3) #iptables -P OUTPUT -j ACCEPT

 

Należy pamiętać, że podczas pracy na zdalnym komputerze nie należy rozpoczynać od blokady ruchu przychodzącego, bo natychmiast stracimy możliwość komunikacji pomiędzy komputerami. No dobrze. Mamy zablokowany ruch przychodzący, ale mamy kilka usług, które chcielibyśmy udostępnić. Zaczynamy od naszego http.

 

4) #iptables -A INPUT -s 0.0.0.0/0 --dport 80 -j ACCEPT

 

W zależności od potrzeb można adres 0.0.0.0/0 (wszystkie hosty) zastąpić konkretnymi adresami komputerów bądź sieci. Dopuszczamy możliwość zdalnego logowania się przez ssh z naszego "bezpiecznego" hosta.

 

5) #iptables -A INPUT -s 351.172.248.255 --dport 22 -j ACCEPT

 

Dopuszczamy ruch z DNS'ów (warunek poprawnej pracy wielu usług). Dla sieci TPNET może to wyglądać tak.

 

6) iptables -A INPUT -s 194.204.159.1 -j ACCEPT

7) iptables -A INPUT -s 194.204.152.34 -j ACCEPT

 

Dobrym pomysłem może być zablokowanie wszystkich pakietów z ustawionym bitem SYN (inicjacja nowego połączenia dla protokołu TCP). Wykonujemy to dla wszystkich komputerów z wyjątkiem naszego zaufanego komputera.

 

8) iptables -A INPUT -p TCP -s ! 351.172.248.255 --syn -j DENY

 

Dopisanie powyższej linijki spowoduje odrzucanie wszystkich pakietów z ustawioną flagą SYN z hostów innych niż 351.172.248.255 (wykrzyknik przed adresem oznacza negację).

Iptables, w porównaniu ze swoim starszym bratem Ipchains posiada rozbudowane możliwości kontroli bitów pola KOD z nagłówka TCP. O ile Ipchains wykorzystywał tylko kontrolę bitu SYN, to Iptables może kontrolować zawartość wszystkich sześciu bitów tj.: URG, SYN, PSH, FIN, ACK, RST. Więcej o używaniu tej opcji można znaleźć w man iptables.

Jako ciekawostkę proponuję na tym etapie "zapuszczenie pinga" na jakiś adres w sieci. Zauważymy, że żaden z komputerów nam nie odpowiada. Odpowiedzialna jest za to reguła 1, która odrzuca wszystko, co nie spełnia reguł 3-7, czyli także odpowiedzi na nasze "pingi". Także ktoś z zewnątrz próbując sprawdzić czy nasza maszyna "żyje" nie otrzyma od niej odpowiedzi. Aby to zmienić możemy dopuścić do użycia cały protokół ICMP:

 

9) iptables -A INPUT -p icmp -j ACCEPT

 

lub tylko odpowiedzi na pingi wychodzące z naszego komputera.

 

10) iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

 

W tym drugim przypadku nasz komputer nie odpowiada na pakiety ICMP, jednocześnie zabezpieczając przed atakiem ping of death. Czas na dopuszczenie dla szerszego grona naszego serwera ftp.

 

11) iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT

 

Powyższy wpis umożliwia korzystanie z portów 20 i 21 (ftp), ale tylko w trybie passive off klienta ftp. Istnieje jednak możliwość udostępnienia pracy w trybie passive on. Jednak trzeba pozwolić na wymianę pakietów pomiędzy dynamicznie przydzielanymi portami zarówno po stronie serwera, jak i klienta ftp. Umożliwia to analiza śledzenia połączeń modułów ip_conntrack i ip_connttack_ftp. W iptables realizuje się to przez opcję -m state. Stany które można sprawdzać to:

NEW (NOWY) - pakiet tworzący nowe połączenie;

ESTABLISHED (NAWIĄZUJĄCY) - pakiet należący do istniejącego połączenia;

RELATED (ZWIĄZANY) - pakiet związany z połączeniem już ustanowionym, ale nie będący jego częścią;

INVALID (BŁĘDNY) - pakiet błędny lub nie do zidentyfikowania.

Wracając do naszego przykładu, odpowiedni zapis w Iptables będzie miał postać:

 

12) iptables -A INPUT -m state --state RELATED -j ACCEPT

 

Chcemy wiedzieć, czy inni użytkownicy naszego serwera wykorzystują go jako "maszyny przesiadkowej" do telnetowania się na inne komputery. W tym celu umieszczamy zapis.

 

13) iptables -A OUTPUT -p tcp --dport 23 -j LOG

 

Spowoduje to zapis w pliku meesages informacji o każdym pakiecie opuszczającym nasz komputer, a skierowanym do portu 23 (telnet) innego komputera. Jednak w szybkim czasie powoduje to "zapchanie" pliku. Niedogodność eliminujemy modyfikując regułę 13) do poniższej postaci.

 

14) iptables -A OUTPUT -p tcp --dport 23 -m limit --limit 1/min -j LOG

 

Zapis ten będzie ograniczał liczbe zapisów do pliku do częstotliwości 1/min (opcja -m. limit --limit 1/min). W razie potrzeby częstotliwość próbkowania można zmienić.

 

W ostatnim kroku dopuszczamy pracę na interfejsie lokalnym.

 

15) iptables -A INPUT -s 127.0.0.1 -j ACCEPT

 

Rys. 2. Przykład konfiguracji Iptables

 

Rozbudowanie łańcuchów o możliwość dopuszczania pakietów skierowanych do innych usług wymaga tylko przeanalizowania powyższych przykładów.

Jeżeli do tej pory gorliwie wstukiwaliśmy zmodyfikowane przez nas regułki, czas na zapisanie owoców naszej pracy aby nie utracić ich po restarcie komputera. W tym celu twórcy programu udostępnili dwa przydatne narzędzia. Pierwsze z nich iptables-save nazwa_pliku zapisuje do wskazanego przez nas pliku stan reguł w łańcuchach, drugie iptables-restore nazwa_pliku powoduje załadowanie łańcuchów z pliku do kernela.

Starsze pakiety filtów jak na przykład Ipchains doczekały sie już do konfiguracji, interfejsów graficznych (np. firewall-config). W chwili pisania artykułu jedyna formą configuracji Iptables było kłopotliwe wklepywanie reguł z klawiatury

 

#iptables-save /etc/iptables.cfg

#iptables-restore /etc/iptables.cfg

 

Teraz pozostaje tylko wykonać odpowiedni wpis, aby nasze reguły były ładowane automatycznie przy rozruchu systemu i gotowe. Można to uczynić na przykład na końcu pliku /etc/rc.d/rc.local. I gotowe.

Opisane przeze mnie przykłady nie wyczerpują wszystkich możliwości Iptables. Jednak opisywanie wszystkich jest tematem na dość pokaźną książkę.