No to zaczynamy, na początek postanowiłem napisać o iptables.
Docelowo ten wpis, ma pomóc w zrozumieniu podstaw działania tego filtra pakietów. Piszę to howto, z myślą o kilku znajomych osobach, które mnie o to poprosiły. Część z tych osób musi oddać na uczelnię projekt, przedstawiający podstawową konfigurację firwalla w oparciu o iptables, pozostali na co dzień używają Linuksa. Być może wpis ten, przyda się również innym początkującym użytkownikom Linuksa, dlatego też zdecydowałem się zmieścić go na blogu.

Podstawowa konfiguracja firewalla, na przykładzie iptables w systemie Debian GNU/Linux.

Ludzie często sądzą, że firewall zapewnia pełną ochronę. Są w błędzie. W większości przypadków źle skonfigurowany firewall zapewnia mniej ochrony niż nie posiadanie firewalla w ogóle. Ponadto każdy firewall należy traktować jak zwykły, podatny na błędy program.
Należy zatem poważnie przemyśleć jego używanie i dokładnie sprawdzić czy jest nam potrzebny. Należy również spisać dokładnie jakiego typu ma to być firewall, określić reguły jego działania oraz użytkowników jacy będą z niego korzystać. 1

Autor tego howto, nie bierze odpowiedzialności, za skorzystanie z poniżej zaprezentowanego skryptu. Pamiętaj że robisz to na własną odpowiedzialność.

Iptables jest filtrem pakietów (głównie używanym jako firewall bądź router) dla systemu operacyjnego GNU/Linux.2

Co to jest filtr pakietów?

Filtr pakietów, to oprogramowanie, które sprawdza nagłówki pakietów w trakcie przechodzenia przez maszynę i decyduje o tym czy pakiet zostanie „upuszczony na podłogę” (ang. DROP), zaakceptowany (ang, ACCEPT), czy też odrzucony (REJECT). Gdy pakiet zostaje odrzucony, zostaje on odesłany z powrotem do źródła, powiadamiając o tym nadawcę.

Dlaczego warto filtrować pakiety?

Najprostsza odpowiedź, jaka przychodzi mi do głowy to, z powodu bezpieczeństwa.

O co w tym chodzi?

Kernel rozpoczyna pracę z trzema listami reguł w tabeli filtrującej. INPUT – opisuje działania dla pakietów przychodzących, OUTPUT – dla wychodzących i FORWARD (ang. przekazywanie) – dla pakietów przechodzących pomiędzy kilkoma interfejsami.

Każda reguła mówi, jeśli nagłówek pakietu wygląda tak, to zrobimy z tym pakietem następującą rzecz. Jeśli reguła nie pasuje do pakietu, sprawdzana jest następna. Na koniec, jeśli nie ma więcej reguł, kernel sprawdza politykę (ang. policy) danego łańcucha (listy reguł). W systemie w którym dba się o bezpieczeństwo, polityka mówi zwykle kernelowi by odrzucał (DROP) pakiet.

  1. Gdy pakiet dociera do maszyny (np. przez kartę Ethernetową), kernel sprawdza najpierw adres przeznaczenia pakietu (operację tą nazywamy routingiem.)
  2. Jeśli pakiet przeznaczony jest do tego komputera, zostaje przepuszczony do łańcucha INPUT. Jeżeli zostanie zaakceptowany, otrzyma go proces do którego był adresowany.
  3. W innym przypadku, jeśli kernel nie ma włączonego przekazywania, lub nie wie jak przekazać pakiet, jest on odrzucany. Natomiast jeśli przekazywanie jest włączone i pakiet jest przeznaczony do innego interfejsu sieciowego (jeśli w ogóle masz jeszcze jeden), pakiet przechodzi do łańcucha FORWARD. Jeśli zostaje zaakceptowany, zostanie wysłany dalej.
  4. Na koniec, program pracujący na tym komputerze może również wysyłać własne pakiety. Przejdą one od razu do łańcucha OUTPUT, jeśli stwierdzi on że zaakceptuje pakiet, przechodzi on do właściwego interfejsu sieciowego. 3

Tworzymy podstawowy skrypt firewalla.

Uruchamiamy terminal.
Sprawdzamy czy mamy ip tables zainstalowane w systemie, wpisując polecenie:

dpkg -l iptables

Jeśli w naszym systemie brakuje iptables, przechodzimy na konto administratora (root) Kod: su
Następnie instalujemy, iptables wpisując poniższe polecenie:

aptitude update && aptitude install iptables

Wszystkie poniższe polecenia, należy wykonywać jako root.

Aby sprawdzić, jakie są ustawione domyślne reguły w systemie, wpisujemy:

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Jak widzimy powyżej, domyślnym ustawieniem firewalla w Debianie Etch jest polityka akceptowania wszystkich pakietów przychodzących, forwardowanych (routowanych) oraz wychodzących. Aby zmienić ten stan rzeczy, stwórzmy teraz, podstawowy skrypt:

touch /etc/init.d/firewall && chmod +x /etc/init.d/firewall && pico /etc/init.d/firewall

Powyższe polecenie tworzy w podanej ścieżce plik firewall, nadaje mu prawo do wykonywania, oraz zostaje on otworzony w prostym edytorze pico.

Teraz grzecznie przepiszmy poniższy kod:

iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

Zapiszmy zmiany, oraz sprawmy aby nasz firewall uruchamiał się od razu po inicjalizacji kernela.

update-rc.d firewall defaults 90

Teraz omówimy sobie powyższy skrypt.
//*************************************************************
Poniższe polecenia oczyszczają tablicę, z poprzednio wpisanych reguł.

Opcja (-F) usuwa wszystkie reguły z łańcucha, natomiast (-X) usuwa wszystkie dowiązania do innych tablic, utworzone przez użytkownika.

iptables -F
iptables -X

//*************************************************************
Poniższe komendy, domyślnie blokują wszystkie przychodzące, przechodzące pakiety które nie zaznaczymy jako pożądane, oraz akceptują wychodzące pakiety.

Komenda -P [łańcuch] [polityka] – ustawia domyślną politykę w danym łańcuchu.

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

//*************************************************************
Podstawowe wyjątki w łańcuchu INPUT.

IP tables pozwala nam na sprawdzenie stanów połączeń, np. czy jest to nowepołączenie, istniejące czy może połączenie powiązane z już istniejącym? Poprzez poniższe polecenie, pozwalamy na wszystkie istniejące już połączenia, oraz połączenia które są powiązane z istniejącymi już połączeniami.

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

//*************************************************************
Następna reguła, dopuszcza przychodzące lokalne pakiety. W poniższym poleceniu widzimy „lo”. Lo to skrót który w Linuksie oraz Uniksach, przypisywany jest do narzędzia która nazywa się pętla zwrotna (ang. loopback) jej adres to 127.0.0.1, posiadasz go nawet wtedy gdy nie masz żadnego połączenia sieciowego. Kiedy korzystamy z loopback? Gdy uzyskujemy dostęp do lokalnych serwisów, jak np. przeglądanie swojego własnego serwera. Czyli jeśli chcemy mieć dostęp do swoich własnych usług, (do których zazwyczaj chcemy mieć dostęp) musimy dodać regułę „trusts” do urządzenia loopback.

-A [łańcuch] [reguła] – dodaje nową regułę do łańcucha. W naszym przypadku dodajemy nową regułę do łańcucha INPUT.
-i [interfejs] – sprawia że, dana reguła dotyczy tylko pakietów przychodzących z danego interfejsu. Interfejs to fizyczne urządzenie do którego pakiety przychodzą (-i) i z którego wychodzą (-o). Należy zwrócić uwagę że, pakiety które podróżują w łańcuchu INPUT, nie mają interfejsu wyjściowego, tylko wejściowy.

iptables -A INPUT -i lo -j ACCEPT

//*************************************************************
Powyższy kod, służy do ustawienia dość mocnej zapory, która pewnie niektórym użytkownikom będzie odpowiadać. Jednakże, zapewne wielu z was, korzysta z dodatkowych usług, takich jak sieci p2p, czy też np. mysql. Aby móc nadal wykorzystywać te i inne usługi, musimy rozbudować ten skrypt.

Zezwalamy na dostęp.

Najbardziej użyteczne według mnie są dwa sposoby:

	1. Podanie adresu IP ( "-s" opcje)
	2. Podanie portu ("--dport" opcje)

Gdy chcę, aby wszyscy użytkownicy sieci, mieli dostęp do mojego serwera (port 80, TCP) piszę następującą regułkę:

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Jeśli chcę otworzyć port 22 (obsługa zdalnych bezpiecznych połączeń ssh) piszę:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Natomiast jeśli chcę, żeby port 22, był otwarty tylko dla wybranego numeru IP piszę:

iptables -A INPUT -p tcp -s (adres_ip) -j ACCEPT

Natomiast Bittorent, wykorzystuje zarówno tcp jak i udp.
Zatem nasze regułka będzie wyglądała następująco: (stosuje założenie, że potrzebne porty które powinny być otwarte będą z przedziału 10000 – 10020)

iptables -A INPUT -p tcp --dport 10000:10020 -j ACCEPT
iptables -A INPUT -p udp --dport 10000:10020 -j ACCEPT

Uruchamianie zapory siecowej.

/etc/init.d/firewall

Po wykonaniu powyższego polecenia, zapora będzie aktywna. Natomiast wyniki naszej pracy możemy obejrzeć, korzystając z polecenia:

iptables -L -n --line-numbers

Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT 0 — 0.0.0.0/0 0.0.0.0/0
2 ACCEPT 0 — 0.0.0.0/0 0.0.0.0/0 state RELATED, ESTABLISHED
3 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
5 ACCEPT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpts:10000 :10020
6 ACCEPT udp — 0.0.0.0/0 0.0.0.0/0 udp dpts:10000 :10020
Chain FORWARD (policy DROP)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination

Pisząc to howto korzystałem z:

  1. Dokumentacji Gentoo
  2. Wikipedii
  3. HOWTO Rusty Russella

Warto również zapoznać się z:

man iptables
Netfilter FAQ
Iptables Tutorial 1.2.2
ROPE – IpTables Scripting Language

Powyższe howto, jest pierwszym jakie napisałem, z czasem będzie ono ulepszane.

Pozdrawiam.