Firewall - paketový filtr

David Šafránek, xsafran1@fi.muni.cz


Obsah


K čemu je firewall aneb proč stavět hradbu?

Běžné routery směrují pakety na určená místa pasivně bez jakékoliv kontroly, tj. jsou směrovány i "škodlivé" pakety. Chceme-li kontrolovat pakety přícházející do naší sítě, můžeme mezi naši síť a okolní svět postavit firewall, který zabrání proniknutí zlomyslných útočníků ke strojům v naší síti. Tato hradba však stojí přirozeně v cestě i paketům cestujícím ven z naší sítě.
V užším smyslu lze firewall považovat za chytrý router, který se dívá dovnitř příchozích paketů a dále se rozhoduje, co se bude s paketem dít. Paket může být doručen na cílovou adresu, zahozen nebo dokonce firewall může přepsat hlavičku paketu např. za účelem překladu adres (Network Adress Translation). Firewall může také řešit autentizaci uživatelů nebo strojů.

Celkem lze možnosti firewallu shrnout následovně:



Typy firewallů

Aplikační filtr

Sedí na aplikační vrstvě. Střeží tedy jednotlivé aplikace. Veškerá komunikace probíhá prostřednictvím proxy serverů (klient chce kontaktovat server venku => místo toho kontaktuje proxy server na firewallu, který se chová vůči klientu transparentně a přitom komunikuje se skutečným serverem dle daných pravidel určujících oprávněnost požadavků (i na úrovni uživatelů)).

Paketový filtr

Sedí na síťové vrstvě. Chová se jako částečně propustný router. Zkoumá hlavičky procházejících paketů a podle sady pravidel se rozhoduje, zda paket propustí či nikoliv. V zásadě definuje odkud kam a kterou službou je povolen přístup. Nemá sice takové možnosti jako aplikační firewall, nepotřebujeme však pro každou službu proxy server. Autentizaci nelze dělat na úrovni uživatelů.

Network adress translation (NAT)

Sedí na aplikační i síťové vrstvě. Řeší transparent proxy, IP masquarading, více serverů ve vnitřní síti (IP forwarding) a např. rozdělení zátěže (load-balancing). Pro některé služby musí operovat i na aplikační vrstvě (např. ftp, pokud nechceme jen pasivní ftp).

Bridging firewall

Sedí na spojové vrstvě.


Software pro firewally

Aplikační filtry

Paketové filtry

Nejdostupnější je podpora packetového filtru zabudovaná do jádra Linuxu (od verze 1.1).



Paketový filtr v Linuxu s jádrem 2.4

Paketový filtr (netfilter) je zabudován v jádře, ovládá se pomocí modulu iptables. Před kompilací jádra je nutné zadat parametr CONFIG_NETFILTER v konfiguraci jádra. Dále je nutné zkompilovat ovládací program iptables z jeho aktuálních zdrojů.
iptables umožňuje vkládat a odstraňovat pravidla z tabulky paketového filtru v jádře. Nastavení nepřežije reboot, proto je nutné tabulku filtru plnit ve startovacích skriptech. Implicitně jsou k dispozici tři seznamy pravidel (řetězy) ve filtrovací tabulce - INPUT, OUTPUT a FORWARD.

                             -----
Vstupní pakety              /     \         Výstupní pakety
  ------->[Směrování]----->|FORWARD|------------->
          [Rozhodnutí]      \_____/        ^
               |                           |
               v                          ____
              ___                        /    \
             /   \                      |OUTPUT|
            |INPUT|		         \____/
             \___/                         ^
               |                           |
                -----> místní proces ------

Pokud je paket na své cestě konfrontován s pravidlem, které žádá jeho zahození (DROP), potom paket skončí svoji pouť v daném chainu. V opačném případě je paket propuštěn (ACCEPT) a pokračuje svoji cestu výše uvedeným diagramem.
  1. Rozhodnutí routeru, zda paket přicházející přes vstupní rozhraní je určen pro lokální stanici.
  2. V kladném případě je podroben testu s pravidly v INPUT řetězu.
  3. V záporném případě je podroben FORWARD řetězu pravidel, pokud je přesměrování na tomto stroji povoleno a existuje cílový stroj, jinak je paket zamítnut.
  4. Každý paket vycházející z procesu na tomto stroji je podroben OUTPUT řetězu pravidel.

Každý řetěz (chain) je seznam pravidel, z nichž každé říká, co se má s odpovídajícím paketem udělat (podmínka příslušnosti se interpretuje na hlavičce paketu). Pokud paket aktuálnímu pravidlu neodpovídá, je konfrontován s pravidlem následujícím. Pokud žádné z pravidel neodpovídá paketu, aplikuje se na něj tzv. chain policy. V bezpečném systému by měl být takovýto paket zahozen.

Každé pravidlo je množina podmínek, jež musí paket splňovat a dále specifikuje co se má v tomto případě s paketem dělat.

Operace nad řetězy:

  1. Vytvoření nového řetězu (-N).
  2. Odstranění prázdného řetězu (-X).
  3. Změna chain policy pro INPUT, OUTPUT nebo FORWARD řetěz (-P).
  4. Zobrazení pravidel v daném řetězu (-L).
  5. Odstranění pravidel z řetězu (-F).

Operace nad pravidly v řetězu:

  1. Přidání nového pravidla na konec řetězu (-A).
  2. Vložení nového pravidla do řetězu na určitou pozici (-I).
  3. Přepsání pravidla na určité pozici v řetězu (-R).
  4. Odstranění pravidla z určité pozice v řetězu (-D).
  5. Odstranění prvního pravidla splňujícího dané podmínky (-D).

iptables může být instalován jako modul (iptable_filter.o), při startu iptables by měl být automaticky zaveden. iptables lze také zakompilovat přímo do jádra.

Po prvním spuštění iptables po nabootování stroje jsou implicitní řetězy INPUT, OUTPUT a FORWARD prázdné s chain policy nastavenou na ACCEPT.

# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms

# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP

# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
Voláním iptables v předchozím příkladu jsme přidali pravidlo na konec řetězu pro ICMP (parametr -p) pakety přicházející z lokálního stroje (zdrojová adresa je adresa loopback rozhraní). Parametrem -j specifikujeme jejich zamítnutí. Celkový efekt této konfigurace je tedy zamítnutí všech ICMP paketů přicházejících z loopback rozhraní.

Pro odstranění pravidla z řetězu máme (jak bylo uvedeno výše) dvě možnosti:

# iptables -D INPUT 1
#
Tím se odstraní pravidlo číslo 1 v INPUT řetězu.
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
Tím se vymaže první výskyt pravidla odpovídajícího daným parametrům.

Specifikace zdrojových a cílových adres

Adresy k parametrům -s (-source) a -d (-destination) lze zadávat čtyřmi způsoby:

  1. Internetové jméno stroje (z DNS)
  2. IP adresa
  3. IP adresa sítě stylu '195.48.200.0/24'
  4. IP adresa sítě/maska sítě `195.48.200.0/255.255.255.0'
Pokud není parametr -s nebo -d specifikován, uvažují se všechny IP adresy. Pomocí znaku '!' lze negovat význam. Např. -s ! localhost zn. vše mimo localhost.

Specifikace protokolu

Protokol specifikujeme parametrem -p jmeno protokolu. Tj. např. -p ! TCP zn. všechny protokoly mimo TCP.

Specifikace rozhraní

Vstupní/výstupní rozhraní specifikujeme pomocí parametrů -i/-o následovaných názvem rozhraní. Logicky pro INPUT řetěz jsou významné pouze -i rozhraní, pro OUTPUT řetěz jen -o rozhraní a pro FORWARD řetěz jsou smysluplné oba dva parametry. Např. -i ! ppp+ zn. všechna rozhraní mimo libovolné ppp rozhraní.

Specifikace fragmentů

Dojde-li k fragmentaci nějakého paketu, potom pouze v prvním fragmentu je obsažena kompletní hlavička. Fragmenty mají pouze IP adresy, není zde spec. např. protokol. Pomocí parametru -f omezujeme interpretaci konstruovaného pravidla jen na fragmenty, pomocí '! -f' naopak pouze pro první paket.

# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
Tím jsou zamítnuty všechny fragmenty odchozí na 192.168.1.1.

Rozšíření iptables

iptables je rozšiřitelný v modulárním smyslu, rozšíření iptables tedy najdeme v adresáři s moduly (např. /lib/modules/2.4.0/net). Je-li jádro zkompilováno s volbou CONFIG_KMOD, potom je není třeba explicitně zavádět.
Rozšířující volby pro testování paketů jsou specifické pro určité protokoly. Např. pro protokol TCP jsou zde mj. násl. volby (nevztahují se na fragmenty):

Další volby mohou být explicitně vyvolány použitím parametru -m. Zde jsou některé z nich:

Jako v ipchains lze vytvářet vlastní (uživatelské) řetězy. Kdykoliv paket odpovídá nějakému pravidlu, které odkazuje (pomocí '-j') na takovýto nedefaultní řetěz, vyhodnocování následuje uvnitř tohoto řetězu. Po ukončení vyhodnocování pokračuje dále v původním (mateřském) řetězu.

Příklad:
# iptables -N vlastni
#
INPUT vlastni
Pr1: -p ICMP -j DROPPr1: -s 192.168.1.1
Pr2: -p TCP -j vlastniPr2: -d 192.168.1.1
Pr3: -p UDP -j DROP 

Řetěz může být vyprázdněn a zrušen pomocí -F a -X:

# iptables -F test
# iptables -X test
#

Dále jsou jako moduly k dispozici LOG (logování při dosažení pravidla vyhovujícím paketem) a REJECT (stejně jako DROP + navíc vrací ICMP zprávu "port unreachable". Použití s parametrem -j.

Nastavení chain policy

Pouze pro implicitní řetězy INPUT, OUTPUT a FORWARD. Může být nastavena na ACCEPT nebo DROP pomocí parametru -P.


NAT pomocí iptables

NAT (Network Adress Translation) je přepis source a destination IP adres v hlavičce paketů procházejících přes firewall. V zásadě jsou dva typy NAT - překlad cílových adres a překlad zdrojových adres.

NAT se dělá před směrováním (a tedy před vlastním packet filterem) v případě překladu cílových adres a po směrování (a tedy po packet filteru) v případě překladu zdrojových adres. Jsou definovány tři řetězy - PREROUTING, POSTROUTING a OUTPUT (pro pakety vysílané lokálními procesy).

Překlad zdrojových adres

## překlad source adres u paketů odchozích přes eth0 na 1.2.3.4
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
Lze uvádět i rozsahy adres (--to 1.2.3.4-1.2.3.6) pak se dělá load-balancing (vybírá se v poslední době nejméně používané spojení). Lze uvádět i přímo porty či rozsahy portů za IP adresou (--to 1.2.3.4:1-1023).

Masquerading

Speciální případ, jako nová zdrojová adresa se bere adresa rozhraní, přes které paket odchází ven.

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
Tím se pakety odchozí z naší sítě přes firewall z nějakého stroje uvnitř jeví strojům venku jako právě tento stroj, na němž běží firewall. Při odpovědi dochází k inverznímu překladu, tj. pakety jsou doručeny správnému stroji unvnitř naší sítě.

Překlad cílových adres

Pro PREROUTING nebo OUTPUT řetěz.

## web service přesměrován na port 8080 na stroji 5.6.7.8 uvnitř sítě
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to 5.6.7.8:8080
Přesměrování

Speciální případ, přepisuje se adresa rozhraní, přes něž paket přichází.

# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128


Dovětek k bezpečnosti

Doporučuje se nepodceňovat bezpečnostní pravidla v síti za firewallem. V případě, že by hladový vetřelec pronikl do naší síťky, byla by jeho kořist, vzniknutá zanedbáním bezpečnostních opatření, zbytečně velká. Také je vhodné dbát na bezpečnost provozu vlastního stroje, na němž běží firewall. Obecně se doporučuje následující:



Odkazy