====== Filtracja pakietów w systemie Linux ====== ===== nefilter i iptables ===== **[[http://pl.wikipedia.org/wiki/Netfilter|Netfilter]]** to część jądra systemu operacyjnego Linux zbierająca funkcje kontroli ruchu sieciowego. Do kontroli zachowania mechanizmów kernela składających się na netfilter służą programy **''iptables''**, ''ip6tables'', ''ebtables'' oraz ''arptables'' [[https://upload.wikimedia.org/wikipedia/commons/d/dd/Netfilter-components.svg|[1]]] [[http://netfilter.org/|Netfilter project]] jest zbiorem projektów związanych z frameworkiem do filtrowania pakietów, w tym iptables. ==== Hooki, tabele, łańcuchy ==== Podczas przejścia pakietu przez jądro Linuksa wykonywane są w ściśle określonej kolejności [[http://en.wikipedia.org/wiki/Hooking|hooki]] decydujące co z pakietem zrobić. Każdemu hookowi odpowada jeden **łańcuch** reguł (**chain**). Łańcuch reguły to wiele reguł które przetwarzane są **w kolejności** – jeśli któraś reguła zdecyduje o losie pakietu, późniejsze nie są brane pod uwagę. Łańcuchy są pogrupowane w **tabele** (**table**) pod względem funkcjonalności. W ''iptables'' dostępne są następujące tabele: * **filter** – odrzuca niechciane pakiety * **nat** – zmienia adresy źródłowe lub docelowe pakietu * mangle – modyfikuje pakiety * raw – udostępnia pakietów przed ich przetworzeniem przez część kernela (np. conntrack) * security – używana przy zaawansowanych modelach bezpieczeństwa w Linuksie (np. SELinux) Łańchy mają nazwy odpowiadające momentowi ich wywołania: * **PREROUTING** jest wykonywany dla pakietów przychodzących //przed routingiem// (czyli decyzją czy pakiet jest kierowany do tego komputera, czy należy go przesłać dalej lub odrzucić) * **INPUT** jest wykonywany dla pakietów //prz__y__chodzących// skierowanych do tego komputera * **FORWARD** jest wykonywany dla pakietów //prz__e__chodzących//, tj. pakietów ze świata, które mają być wysłane dalej * **OUTPUT** jest wykonywany dla pakietów wyprodukowanych na tym komputerze (//wychodzących//) * **POSTROUTING** jest wykonywany dla pakietów wychodzących po podjęciu decyzji gdzie je wysłać Droga pakietu przez mechanizmy filtrujące w systemie Linux podsumowana jest tutaj: ** [[https://pl.wikipedia.org/wiki/Plik:Netfilter-packet-flow-pl.svg|[PL]]] ** ** [[https://commons.wikimedia.org/wiki/File:Netfilter-packet-flow.svg|[EN]]] ** Można tworzyć własne łańcuchy, ale mogą one być uruchomione tylko przez dołączenie ich do już istniejących. ==== Stanowość i bezstanowość – conntrack ==== Jądro Linuksa jest zaopatrzone w mechanizm śledzenia połączeń (conntrack). Duża część reguł korzysta z dostarczanych przez niego informacji, co znacznie ułatwia konfigurację filtracji. ==== [Ekstra] Trwałość reguł (persistance) ==== Iptables nie dostarcza mechanizmu automatycznego zapisywania ustawień – po ponownym uruchomieniu lista reguł jest pusta, a polityki domyślne. Dla odtworzenia reguł przy starcie dystrybucje Linuksa dostarczają odpowiedni skrypt startowy. Zwykle zapisanie reguł odbywa się ręcznie (tj. trzeba wydać odpowiednią komendę). ===== Komendy ===== Komenda ''iptables'' wszędzie **rozróżnia wielkie i małe litery**, ponadto **kolejność argumentów** decyduje o zrozumieniu polecenia. Wyświetlanie listy reguł: * ''iptables [-t filter] -L [-n]'' – **wypisanie** (''--list'') **tablicy filtracji** \\ * ''iptables -t -L [-n]'' – wypisanie innych tablic \\ * ''iptables [-t ] --line-numbers -L'' – dodaje **numery reguł** Wzorce poleceń modyfikujących działanie filtracji i dodających reguły filtaracji: * ''iptables [-t filter] -P <łańcuch> '' – zmiana **domyślnego zachowania** (tj. jeśli żadna z reguł nie podejmie decyzji). Zwykle stosowane polityki to ''ACCEPT'' lub ''DROP''. Przykład: \\ ''iptables -P INPUT DROP'' – ignoruje pakiety przychodzące * ''iptables -A <łańcuch> '' – **dodaje** regułę do łańcucha (''--append''), np: \\ ''iptables -A INPUT -s 1.2.3.4 -j ACCEPT'' * ''iptables -I <łańcuch> [pozycja] '' – **wstawia** (''--insert'') regułę **na podane miejsce** do łańcucha (lub na początek jeśli numeru nie podano), np: \\ ''iptables -I INPUT 1 -s 1.2.3.4 -j ACCEPT'' * ''iptables -D <łańcuch> '' – **usuwa** (''--delete'') regułę na podanej pozycji z łańcucha, np: \\ ''iptables -D INPUT 2'' * ''iptables -D <łańcuch> '' – **usuwa** (''--delete'') regułę z łańcucha, np: \\ ''iptables -D INPUT -s 1.2.3.4 -j ACCEPT'' * ''iptables -F [łańcuch]'' – usuwa wszystkie reguły [z łańcucha] (''--flush''); wysoce niebezpieczne Zwykle reguły w ''iptables'' są zakończone akcją: * **''-j ACCEPT''** – przepuszcza pakiet * **''-j DROP''** – ignoruje (wyrzuca do śmieci) pakiet * **''-j REJECT''** – dodatkowa akcja, symuluje zamknięte gniazdo (wysyła ICMP //destination unreachable//) Są też dostępne inne akcje, np. ''LOG'', ''MARK'' i ''SET''. Więcej szczegółow w ''man iptables-extensions'' Rdzeń ''iptables'' zawiera niewiele filtrów – źródłowy i docelowy adres(''-s'' i ''-d''), interface (''-i'' i ''-o'') i protokół (''-p''). \\ **Patrz: ''man iptables''**. \\ Filtry można negować przez użycie '!' (wykrzyknika) Netfilter jest modularny – większość funkcji mieści się w **rozszerzeniach**, ładowanych przez ''-m ''\\ To pozwala na bardzo szczegółową filtrację. \\ **Patrz: ''man iptables-extensions''** Przykładowe rozszerzenia: * ''-m tcp/udp'' jest **automatycznie** ładowany razem z ''-p udp/tcp''; pozwala ustalić m. inn. port źródłowy i docelowy ''--sport / --dport'' * ''-m conntrack'' wybiera stan połączenia ''--ctstate'', m. inn.: ''INVALID,NEW,ESTABLISHED,RELATED'' * ''-m comment'' pozwala na dowolny komentarz ''--comment '' * ''-m limit'' dzięki ''--limit'' ogranicza ilość pakietów na jednostkę czasu * ''-m hashlimit'' pozwala m. inn. ustawić limit pakietów/czas dla każdego IP z osobna * ''-m time'' pozwala włączyć regułę o ''--datestart'' i wyłączyć o ''--datestop'' * ''-m u32'' udostępnia ''--u32'' wykonujący dowolny test na danych pakietu * ''-m connlimit'' używając ''--connlimit-above'' pozwala ograniczyć ilość połączeń z jednego adresu ''iptables'' ma rozbudowaną pomoc wewnętrzną – po napotkaniu ''--help'' przerwie dodawanie reguły i pokaże listę opcji, np.: \\ ''iptables -I INPUT -p tcp --help'' \\ ''iptables -m hashlimit -m limit -m connlimit --help'' ''iptables-save'' oraz ''iptables-restore'' są używane do zapisu/odczytu tablic do pliku. ==== Filtracja pakietów ==== === Filtracja na wejściu === Najczęściej stosowana do wpuszczania tylko pożądanego ruchu. Typowe podejście to zabronienie wszystkiego, co nie jest wprost dozwolone. ''iptables -P INPUT DROP'' – ustawienie domyślnej akcji wybieranej jeśli żadna z reguł nie zadziała \\ ''iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT'' – pozwala na ruch lokalny \\ ''iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT'' – pozwala przychodzić pakietom nawiązanych wcześniej połączeń \\ ''iptables -A INPUT -p tcp --dport 22 -j ACCEPT'' – pozwala na dostęp do ssh \\ === Filtracja pakietów przechodzących === Decyduje jaki ruch może przechodzić przez komputer. Podejście do reguł zależy od zastosowania. ''iptables -A FORWARD -m connlimit --connlimit-above 5 -j DROP'' – pozwala na nie więcej niż 5 połączeń przechodzących od każdego nadawcy === Filtracja na wyjściu === Służy do wypuszczania tylko pożądanego ruchu. Typowe podejście to blokowanie niepożądanego ruchu. ''iptables -A OUTPUT -p tcp --dport bnetgame -j REJECT'' – odrzuca połączenia na port "Battle.net Chat/Game Protocol"\\ ''iptables -A OUTPUT -p tcp -d google.pl -j DROP'' – blokuje próby połączenia z google.pl (Uwaga: iptables wypyta DNS o adresy IP i doda reguły z adresami IP, nie z nazwą google.pl) \\ ''iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT'' – pozwala na używanie http === Liczniki === iptables liczy ilość i rozmiar pakietów które dopasowały się do każdej reguły. Można: * ''iptables -v [-x] -L'' – wyświetlić listę reguł z uwzględnieniem liczników * ''iptables -Z [co zerować]'' – wyzerować stan liczników – wszystkich lub wybranego łańcucha / reguły **[[sk1:nf_fw|Filtracja pakietów w systemie Linux - ćwiczenia]]** ==== Manipulowanie pakietami ==== Przykłady na manipulację pakietami: \\ ''iptables -t mangle -A POSTROUTING -o wlan0 -j TTL --ttl-set 1'' \\ ''iptables -t mangle -A PREROUTING -i wlan0 -j TTL --ttl-inc 16'' \\ ''iptables -t mangle -A PREROUTING -i wlan0 -j TEE --gateway 10.0.0.3'' \\ ''iptables -t mangle -A POSTROUTING -p tcp --sport 5222 -j TOS --set-tos Minimize-Delay'' \\ ===== NAT (Network Address Translation) – translacja adresów ===== Ze względu na niewystarczającą ilość adresów IPv4 zwykle komputery w sieciach lokalnych używają adresów //z bloków prywatnych//. Na wiadomość z takiego komputera – wysłaną z adresem źródłowym z bloku adresów prywatnych – odbiorca nie ma szansy odpowiedzieć (bo gdzie miałby?). Routery z publicznym IP powinny automatycznie wycinać takie wiadomości [[https://tools.ietf.org/html/rfc1918|RFC 1918, str. 5]] Dlatego konieczne jest by na styku adresacji prywatnej i publicznej adresy były tłumaczone, stąd nazwa //NAT// = //Network Address Translation//. Ruch generowany przez komputery z wewnątrz sieci lokalnej musi mieć zmieniony adres źródłowy (source address), stąd nazwa //Source NAT// (//SNAT//). Tradycyjnie adresy źródłowe zmienia się w momencie kiedy pakiet opuszcza system. Jeśli zachodzi konieczność by ruch z sieci publicznej trafiał do komputera wewnątrz sieci lokalnej, trzeba zmienić adres docelowy (destination address), stąd nazwa //Destination NAT// (//DNAT//). Naturalnie urządzenie na styku sieci musi zmienić adres zanim podejmie decyzję o routingu (tj. decyzję gdzie pakiet ma trafić). ++++ Ilustracja do NATów |
{{:sk1:nat.svg|}} SNAT: - PC1 chce wysłać pytanie DNS pod jakim adresem znajdzie serwer put.poznan.pl - PC1 adresuje wiadomość: * w polu odbiorcy wpisuje 1.1.1.1 (znany adres serwera DNS) * w polu nadawcy wpisuje 192.168.0.2 (swój adres IP) - PC1 wysyła wiadomość przez bramę domyślną - router R1, adres 192.168.0.1 - R1 wybiera trasę dla pakietu (wykonuje routing) i kieruje pakiet w stronę internetu - R1 po wykonaniu trasowania (POSTROUTING) dokonuje **translacji adres źródłowego**: \\ zamienia adres źródłowy z 192.168.0.2 na 93.184.216.34 - R1 wysyła wiadomość w intenet - Serwer DNS (pod adresem 1.1.1.1) dostaje wiadomość adresowaną do niego z adresu 93.184.216.34 i odpowiada na nią adresując ją: * od 1.1.1.1 (od siebie) * do 93.184.216.34 (do adresu, z którego otrzymał pytanie) - R1 otrzymuje wiadomość z adresu 1.1.1.1 kierowaną na adres 93.184.216.34 - Przed wykonaniem trasowania R1 sprawdza, czy pakiet należy do połączenia dla którego już wykonuje translację adresów. W tym przypadku tak – zamienia więc adres //docelowy// z 93.184.216.34 na 192.168.0.2 - R1 wykonuje trasowanie i określa, że pakiet kierowany do 192.168.0.2 ma trafić do PC1 - PC1 otrzymuje odpowiedź z adresem źródłowym 1.1.1.1 i docelowym 192.168.0.2 DNAT: - PC1 wysyła żądanie nawiązania połączenia TCP na port 443 ze swojego do adresu 150.254.5.114 - R1 wykonuje translację SNAT i wysyła w internet pakiet: * z adresu 93.184.216.34 * do adresu 150.254.5.114 * protokołu TCP, na port docelowy 443 - R2 dostaje wiadomość z 93.184.216.34 na swój adres IP - Przed wykonaniem trasowania (PREROUTING) R2 sprawdza czy dla tego pakietu powinien wykonać trasowanie - R2 znajduje regułę: //pakiety TCP adresowane na port 443 tego komputera mają trafiać do 192.168.0.3//, więc dokonuje **translacji adresu docelowego**: zmienia adres docelowy 150.254.5.114 na 192.168.0.3 - R2 wykonuje trasowanie i określa, że pakiet kierowany do 192.168.0.3 ma trafić do //Serwer WWW// - //Serwer WWW// otrzymuje pakiet: * z adresu 93.184.216.34 * do adresu 192.168.0.3 - //Serwer WWW// generuje w odpowiedzi pakiet i adresuje go: * od 192.168.0.3 (od siebie) * do 93.184.216.34 (do adresu, z którego otrzymał pytanie) - //Serwer WWW// przesyła odpowiedź do bramy domyślnej 192.168.0.1 (R2) - R2 określa, że pakiet kierowany do 93.184.216.34 ma iść do internetu i go tam kieruje - R2 po wykonaniu trasowania sprawdza, czy pakiet należy do połączenia dla którego już wykonuje translację adresów. W tym przypadku tak – zamienia więc adres //źródłowy// z 192.168.0.3 na 150.254.5.114. - R2 wysyła pakiet do internetu - R1 otrzymuje pakiet * z adresu 150.254.5.114 * do adresu 93.184.216.34 - R1 wykonuje translację SNAT, wysyła pakiet do PC1
++++ === iptables i stanowość firewalla === W systemie Linux translacja adresów jest **stanowa**, stąd odpowiedzi zawsze znajdą drogę powrotną. === Translacja źródłowa (Source NAT, SNAT) === Pozwala na dostęp do sieci z adresacją publiczną (np. internet) urządzeniom z sieci z adresacją prywatną. Uproszczony tryb translacji źródłowej – maskarada: \\ ''iptables --table nat --append POSTROUTING --out-interface wlan0 -j MASQUERADE'' \\ Przy użyciu maskarady adres źródłowy jest automatycznie ustawiany na adres interface'u którym pakiet opuszcza router Klasyczny SNAT wymaga podania adresu (lub adresów) na jakie ma być zmieniane źródło: \\ ''iptables -t nat -A POSTROUTING -j SNAT --to-source 150.254.130.41 [--out-interface wlan0]'' === Translacja docelowa (Destination NAT, DNAT) === Pozwala na dostęp świata do urządzeń znajdujących się w sieci prywatnej, np:\\ ''iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2''\\ ''iptables -t nat -A PREROUTING -p tcp ! --dport 22 -j DNAT --to-destination 10.0.0.2'' **[[sk1:nf_nat|NAT w systemie Linux - ćwiczenia]]** ===== [Ekstra] nftables ===== Na początku 2014 roku do jądra Linuksa włączono nową implementację kontroli ruchu sieciowego, **nftables** [[http://wiki.nftables.org/wiki-nftables/index.php/Main_Page|[1]]] nftables jest nastawiony na zwiększenie wydajności, poprawienie czytelności i jakości kodu oraz wygodę użytkowania (w tej kolejności). \\ Reguły w nftables nie są interpretowane, a wykonywane po uprzednim przygotowaniu bytecode. \\ Polecenia ''.*tables'' zastąpiono jednym poleceniem ''nft'' o "prostszej" składni. ===== [Ekstra] Appendix ===== Dobry artykuł o nftables, z wstępem opisującym historię filtrowania pakietów w Linuksie:https://randomseed.pl/pub/analizy/nftables-nowy-firewall-linuksa/ ([[http://www.cs.put.poznan.pl/jkonczak/archive/Nftables_nowy_firewall_Linuksa_BADSECTOR_PL.html|kopia]]) Inne moduły: *'' recent'' pozwala filtrować biorąc pod uwagę wcześniejszą aktywność danego IP/ danej sieci, np: \\ ''iptables -A INPUT -p tcp --dport 139 -m recent --name unwanted --set --seconds 15 -j DROP'' \\ ''iptables -A INPUT -m recent --update --seconds 15 -j DROP'' * ''string'' pozwalający dopasowywać tekst i moduł ''u32'' pozwalający dopasowywać dana na podanej pozycji, np: \\ ''iptables -A FORWARD -p udp --dport domain -m string --algo bm --hex-string '|08|facebook|03|com|00|' -j LOG --log-prefix 'facebook ' '' * ''mac'' pozwala filtrację adresów MAC, np: \\ ''iptables -A input -m mac ! --mac-source 00:12:34:56:78:ab -j DROP'' *''-p icmp'' pozwala na filtrowania icmp, np: \\ ''iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT'' API systemów Windows do tworzenia firewalli: https://msdn.microsoft.com/en-us/library/aa366510%28v=vs.85%29.aspx