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ě:
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ů)).
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ů.
Sedí na aplikační i síťové vrstvě. Řeší transparentní 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).
Sedí na spojové vrstvě.
Nejdostupnější je podpora packetového filtru zabudovaná do jádra Linuxu (od verze 1.1).
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.
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 ------
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.
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.
Adresy k parametrům -s (-source) a -d (-destination) lze zadávat čtyřmi způsoby:
Protokol specifikujeme parametrem -p jmeno protokolu. Tj. např. -p ! TCP zn. všechny protokoly mimo TCP.
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 smyslné oba dva parametry. Např. -i ! ppp+ zn. všechna rozhraní mimo libovolné ppp rozhraní.
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.
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):
# iptables -A FORWARD -m limit -j LOGTímto se prvně přijme 5 paketů (default limit-burst je 5). Potom se čeká 20min než uběhne limit, případné pakety jsou odmítnuty, nedojde-li žádný, limit-burst se o jedničku nabije. Pokud do 100min nedojde paket, limit-burst je plně nabit a jsme opět v počátečním stavu.
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
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 DROP | Pr1: -s 192.168.1.1 |
Pr2: -p TCP -j vlastni | Pr2: -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.
Pouze pro implicitní řetězy INPUT, OUTPUT a FORWARD. Může být nastavena na ACCEPT nebo DROP pomocí parametru -P.
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 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.4Lze 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).
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 MASQUERADETí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ě.
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:8080Př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
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í: