()

Wstęp

Iptables to program, który powinien być znany każdemu „linuksiarzowi”. Pozwala on na stworzenie filtrowanie i przekierowywanie pakietów, określanie dozwolonych portów i protokołów, przekierowywanie portów czy stworzenie prostej zapory sieciowej (ang. firewall).

Pierwsza wersja tego narzędzie została napisana w 1998 roku. Iptables jest domyślnie wbudowane w jądro Linuksa od wersji 2.4. Przez wzgląd na to, że może narobić niemałych szkód w ruchu sieciowym, do jego uruchomienia wymagane są uprawnienia roota.

Na początek przejdę do omówienia tego, co o programie mówi jego instrukcja.

Instrukcja Iptables (man iptables)

Iptables, tak jak zdecydowana większość poleceń w Linuksie, posiada instrukcję (ang. manual), która znacząco pomaga w korzystaniu w programu. Można ją wywołać za pomocą polecenia man iptables.

Podstawowe łańcuchy w iptables:

  • INPUT – odnosi się do ruchu przychodzącego, czyli pakietów trafiających do urządzenia
  • FORWARD – odnosi się do pakietów, które są routowane (przekazywane na inne urządzenia)
  • OUTPUT – odnosi się do ruchu wychodzącego, czyli pakietów wysyłanych przez urządzenie

Wybrane parametry:

  • -A – dodanie nowej reguły
  • -D – usunięcie reguły
  • -P – zmiana reguły
  • -F – wyczyszczenie reguł z danego łańcucha

Wybrane opcje filtrowania pakietów:

  • -s – wskazanie adresu, z którego pochodzi pakiet (od angielskiego source)
  • -d – wskazanie adresu, do którego kierowany jest pakiet (od angielskiego destination)
  • -p – wskazanie konkretnego protokołu
  • -i – wskazanie konkretnego interfejsu sieciowego (np. eth0)
  • –sport – skrót od angielskiego source port, oznaczającego port źródłowy
  • –dport – skrót od angielskiego destination port, oznaczającego port docelowy

Wyjątkowym parametrem jest parametr –j, dodawany na końcu polecenia. Wraz z dodaniem poniższych opcji pozwala na następujące operacje:

  • ACCEPT – akcepuje pakiety
  • DROP – „upuszcza” pakiety, czyli odrzuca je bez powiadamiania o tym adresu źródłowego
  • REJECT – odrzuca pakiety powiadamiając o tym adres źródłowy
  • LOG – zapisuje w logach określone informacje o pakietach
  • REDIRECT – przekierowuje porty
  • TTL – modyfikowanie TTL (ang. Time To Live) pakietu

Źródła: http://members.upcpoczta.pl/a.bogacz19/iptables/rozne/iptablesi.htm, https://manpages.debian.org/unstable/iptables/iptables.8.en.html, https://pl.wikipedia.org/wiki/Iptables, http://www.faqs.org/docs/iptables/targets.html

Przykładowe polecenia w iptables

Do przykładowej konfiguracji iptables wykorzystałem maszynę wirtualną o adresie IP 192.168.15.37. Host maszyny wirtualnej to komputer z Windowsem o adresie 192.168.15.33.

Sprawdźmy najpierw czy komunikacja między urządzeniami jest możliwa. Użyłem do tego polecenia ping.

Dla uproszczenia, wszystkie zrzuty ekranu z czarnym tłem pochodzą z komputera z Windowsem (hosta maszyny), a z białym – z maszyny wirtualnej (Debiana).

Terminal hosta maszyny wirtualnej.

Terminal Debiana z maszyny wirtualnej.

Jak widać powyżej, urządzenia mogą komunikować się między sobą. Stwórzmy namiastkę zapory ogniowej (ang. firewall).

„Firewall”

Ten nagłówek celowo umieściłem w cudzysłowie, ponieważ nie można tej konfiguracji nazwać firewallem w pełnym tego słowa znaczeniu. Spełnia jednak ona pewne założenie, które jest ważne w firewallach – nie pozwala pakietom przychodzącym na komunikację z urządzeniem (w naszej konfiguracji – wszystkim pakietom), zaś zezwala na wysyłanie pakietów wychodzących.

Pokażę w jaki sposób spowodować, że wszystkie pakiety przychodzące będą odrzucane przez iptables. W pierwszym wariancie będziemy informować o tym urządzenie, które nas odpytuje (REJECT). W drugim nie pozwolimy na informowanie o tym odpytującego urządzenia i będziemy udawać, że takie urządzenie nie istnieje w sieci (DROP).

Wariant pierwszy

Aby spełnić wspomniane wymagania, należy użyć trzech poleceń:

sudo iptables –A INPUT –j REJECT

sudo iptables –A OUTPUT –j ACCEPT

sudo iptables –A FORWARD –j REJECT

Pierwsze polecenie sprawia, że ruch przychodzący jest odrzucany z powiadomieniem o tym adresu źródłowego pakietu. Podobną funkcjonalność pełni trzecie polecenie, lecz dotyczy ono pakietów, które są routowane przez urządzenie. Drugie polecenie to zezwolenie na wysyłanie pakietów przez urządzenie (ruch wychodzący).

Pora na sprawdzenie poprawności działania konfiguracji iptables. W tym celu spinguję adres IP maszyny wirtualnej.

Jak widać na powyższym zrzucie ekranu, dostajemy informację zwrotną o treści Destination port unrechable. Można również zauważyć w ostatniej linijce, że na cztery wysłane zapytania (Sent) wszystkie dostały odpowiedź (Received), co skutkuje zerową utratą pakietów (0% loss). Oznacza to, że konfiguracja iptables działa poprawnie, ponieważ:

  1. Zapytania trafiły do urządzenia (0% loss)
  2. Iptables odrzuciło pakiety, informując o tym źródło pakietów (Destination port unreachable)

Co jednak w wypadku, gdy nie chcemy informować innych o tym, że odrzuciliśmy ich pakiety lub po prostu chcemy wyłączyć odpowiedzi na ping?

Wariant drugi

W tym przypadku chcemy odrzucić pakiety bez informowania o tym urządzenia, z którego pochodzą zapytania. W tym celu wystarczy zmienić parametr REJECT na DROP dla ruchu przychodzącego (INPUT).

Jeżeli nie ma żadnych ustawień wprowadzonych ręcznie do iptables, użyj poleceń:

sudo iptables –A INPUT –j DROP

sudo iptables –A OUTPUT –j ACCEPT

sudo iptables –A FORWARD –j DROP

W moim przypadku edytowałem poprzednią konfigurację, zostawiając opcję REJECT dla ruchu routowanego przez urządzenie (FORWARD). Aby to zrobić, musiałem użyć dwóch poleceń:

sudo iptables –F INPUT

sudo iptables –A INPUT –j DROP

Terminal po edytowaniu opcji dla ruchu wychodzącego. Na zrzucie znajduje się również poprzednia konfiguracja.

Pierwsze polecenie czyściło poprzednią konfigurację dotyczącą ruchu przychodzącego (parametr –F), zaś drugie odpowiada za odrzucanie pakietów bez informowania o tym nadawcy.

Ważne – wyczyszczenie (parametr –F) musi znajdować się przed ponownym określeniem zasady dla danego rodzaju ruchu (DROP/REJECT/ACCEPT dla INPUT/OUTPUT/FORWARD). Bez tego iptables może korzystać z poprzedniego ustawienia, nie uwzględniając nowego.

Sprawdźmy zatem poprawność działania nowego ustawienia. W tym celu ponownie użyłem polecenia ping. Aby pokazać różnice w odpowiedziach, na zrzucie znajduje się poprzednie zapytanie dla opcji REJECT i zapytanie wysłane po wprowadzeniu nowych ustawień.

Porównanie zapytań. Na górze – REJECT, na dole – DROP.

Tak jak widać powyżej – pierwsze zapytanie dało odpowiedź o treści Destination port unreachable i 0% utraconych pakietów (0% loss), zaś drugie zapytanie dało jedynie informacje o braku odpowiedzi (Request timed out.) i o tym, że wszystkie pakiety nie dostały odpowiedzi (100% loss). Oznacza to, że parametr DROP działa zgodnie z planem, co widać na zrzucie ekranu.

Za pomocą tych dwóch parametrów możemy decydować o tym, jaką odpowiedź dostaną urządzenia wysyłające zapytania. Oczywiście, produkcyjne wykorzystanie iptables nie może być takie uproszczone, ponieważ odrzucalibyśmy wszystkie zapytania, przez co dane urządzenie nie mogłoby w pełni funkcjonować w sieci. Możemy jednak tworzyć reguły dostępu do danych usług czy portów, co pozwala na praktyczne wykorzystanie iptables w zwiększaniu bezpieczeństwa w danej organizacji.

SSH

Odpowiednie zabezpieczenie SSH to dość obszerny temat. Nie należy bazować jedynie na wyłączeniu pingów i okrojeniu dostępu do portu – odpowiednie zabezpieczenie może wymagać np. zmiany portu SSH (domyślnie 22) lub wymuszenia dodania klucza prywatnego podczas logowania przy wyłączonej możliwości logowania hasłem.

Pora na uruchomienie SSH. Można to zrobić za pomocą polecenia:

sudo systemctl start sshd.service

Status usługi możemy zobaczyć za pomocą polecenia:

sudo systemctl status sshd.service

Jak na dłoni widać, że usługa jest aktywna – świadczy o tym zielone active (running).

Sprawdźmy teraz czy SSH działa na porcie 22 i czy ten port jest otwarty. Wykorzystam do tego narzędzie nmap i bardzo intuicyjne polecenie:

nmap localhost

Jak widać powyżej, port 22 jest otwarty i działa na nim usługa ssh. Sprawdźmy, czy możemy za pomocą ssh zalogować się do systemu. Można to zrobić w windowsowym wierszu poleceń (popularnie znanym jako cmd) za pomocą polecenia:

ssh [login]@[adres_ip]

W moim przypadku polecenie wygląda następująco:

ssh stefan@192.168.15.37

Udało się zalogować do ssh. Zobaczmy co się stanie, gdy zablokujemy ruch przychodzący. Możemy tego dokonać za pomocą poleceń:

sudo iptables –F INPUT

sudo iptables –A INPUT –j REJECT

W tym momencie nie powinniśmy mieć możliwości zalogować się do SSH, bo zablokowaliśmy cały ruch przychodzący. Zobaczmy, czy to nam się uda.

Zgodnie z planem, nie możemy połączyć się z urządzeniem za pomocą SSH. Aby to zrobić, należy wprowadzić regułę dotyczącą SSH.

Zabezpieczenie SSH

Pora na praktyczne wykorzystanie iptables, jakie mogłoby znaleźć zastosowanie na serwerze. Moim celem jest ograniczenie ruchu przychodzącego, pozwalając na działanie SSH w sieci lokalnej. Tak jak poprzednio, są dwa warianty tego rozwiązania.

Wariant pierwszy

W tym wariancie urządzenie będzie odrzucać zapytania z poinformowaniem o tym nadawcy, pozwalając na połączenie SSH w sieci lokalnej. Można to zrobić za pomocą poleceń:

sudo iptables –F INPUT

sudo iptables –A INPUT –s 192.168.25.15.0/24 –p tcp –dport 22 –j ACCEPT

sudo iptables –A INPUT –j REJECT

Taka konfiguracja powinna zapewniać to, że podczas wysyłania pingów host odpowie o tym, że odrzuca zapytanie, lecz pozwoli na zalogowanie się do systemu z wykorzystaniem SSH. Sprawdźmy, czy konfiguracja działa poprawnie.

Do wysłania pingów i próby połączenia po SSH wykorzystałem poprzednio używane polecenia.

Jak widać powyżej, konfiguracja działa poprawnie. Sprawdźmy teraz, czy możliwe jest zalogowanie się do systemu z wykorzystaniem SSH odrzucając pingi bez informowania o tym nadawcy (DROP).

Wariant drugi

W tym wariancie będziemy logować się z wykorzystaniem SSH do systemu, który zgodnie z ustawieniami iptables będzie odrzucał ruch przychodzący, lecz zezwalał na logowanie po SSH dla urządzeń w sieci lokalnej. Możemy tego dokonać za pomocą poleceń:

sudo iptables –F INPUT

sudo iptables –A INPUT –s 192.168.25.15.0/24 –p tcp –dport 22 –j ACCEPT

sudo iptables –A INPUT –j DROP

Na zrzucie ekranu widoczna jest również poprzednia konfiguracja.

Sprawdźmy, czy logowanie po SSH jest możliwe pomimo odrzucania ruchu przychodzącego.

Do wysłania pingów i próby połączenia po SSH wykorzystałem poprzednio używane polecenia.

Jak widać powyżej, udało się! Można zalogować się do systemu z wykorzystaniem SSH w przypadku, gdy odrzucany jest ruch przychodzący – wystarczy wcześniej sformułować odpowiedni warunek.

Jak sprawdzić obecną konfigurację iptables?

Do sprawdzenia konfiguracji iptables można wykorzystać proste polecenie, które wylistuje obecne ustawienia. Aby to zrobić, należy użyć polecenia:

sudo iptables -S

Warto zwrócić uwagę na przedostatnią linijkę na zrzucie ekranu (-A FORWARD –j REJECT –reject-with icmp-port-unreachable). To właśnie to ustawienie odpowiada za to, jaki komunikat jest widoczny po wysłaniu zapytania ping, jeżeli używamy opcji REJECT. Można ustawić tam inną opcję, na przykład icmp-net-prohibited lub icmp-host-prohibited.

Podsumowanie

Na podstawie powyższych przykładów dobrze widać, że iptables to wielofunkcyjne narzędzie, które może zwiększyć poziom bezpieczeństwa w danej organizacji lub pomóc w zarządzaniu ruchem sieciowym. Jeżeli jeszcze nie był to Twój obiekt zainteresowania, polecam zapoznać się z iptables w środowisku testowym (lub na produkcji – nie odpowiadam jednak za konsekwencje tego działania ).

SSH to tylko jedna z usług, której bezpieczeństwo może zwiększyć iptables. Można go również używać np. regulując dostęp do zasobów sieciowych.

Pisał dla Was Oskar Klimczuk.

Jak przydatny był ten Artykuł

Kliknij gwiazdke by zagłosować

Średni / 5. Liczba głosów

Doceń naszą prace

Przepraszam że ten post nie był dla Ciebie przydatny

Popraw ten post!

Napisz mi co mogę poprawić