Paketové filtry

Aleš Zelinka, xzelinka@fi.muni.cz


Obsah


1. Z admina hasičem aneb co to je firewall

Firewally obecně jsou systémy sídlící na hranici mezi několika sítěmi, které zpracovávají provoz jdoucí přes tuto hranici (z obou směrů). Firewally umožňují filtraci a monitorování provozu. Pokročilejší implementace do síťového provozu i aktivně zasahují. Nejčastější nasazení firewallu bývá mezi LAN a Internetem, kdy chceme "hodnou" lokální síť chránit před "zlým" Internetem.

2. Druhy firewallů

Pojmem firewally označujeme poměrně širokou skupinu systémů. Liší se tím zda se primárně zaměřují na filtrování nebo monitoring, na jaké úrovní síťový provoz sledují nebo třeba zda podporují autentizaci uživatelů.

2.1 Proxy, aplikační brány

Aplikační proxy pracují na úrovni protokolů jednotlivých služeb. Pěkným příkladem je http proxy Squid (
http://www.squid-cache.org). Ta například dokáže filtrovat požadavky klienta podle adresy (žádné porno, warez a pokémony) a odpovědi serveru podle velikosti (nebudeš stahovat nic většího než 10MB). Hlavně ale vytváří záznamy o tom, kdo co odkud stáhl. Některé aplikační proxy servery udržují cache často požadovaných objektů, čímž zvětšují propustnost sítě. Viz o5 squid.

Aplikační proxy dokáží rozlišit/filtrovat požadavky jednotlivých uživatelů.
Nepotřebují podporu v jádře. To je vyváženo nutností podpory klientských aplikací.

2.2 Paketové filtry

Paketové filtry sledují pohyb dat po síti po jednotlivých paketech. Podle daných pravidel posuzují jednotlivé pakety a rozhodují o jejich dalším osudu. Minimálně určují zda se paket propustí nebo zahodí. Paketové filtry nerozumějí vyšším vrstvám než síťové a nedokáží se podle nich rozhodovat. To co mají k dispozici jsou atributy paketů jako zdrojová/cílová adresa, rozhraní, ze kterého paket přišel, zdrojový/cílový port, etc.

Samotný paketový filtr je rychlý, nenáročný na systémové zdroje. (floppyfw běžící z diskety na 386 8MB RAM)
Celý proces se odehrává v jádře.
Nepotřebuje podporu v jednotlivých aplikacích.

Paketové filtry se v posledních letech dostávají do mody. Jsou tím oblíbenější, čím víc user-friendly prográmků na skenování/nabourávání počítačů je na Internetu k dispozici. Pokud dnes někdo říká, že firewall je základ bezpečnosti a neměl by chybět na žádné síti, dokonce na žádném PC připojeném k Internetu, tak má
a) pravdu
b) na mysli paketový filtr

Proto budu v dalším textu považovat termíny paketový filtr a firewall za ekvivalentní. Pokud má být operační systém považován za (více či méně )bezpečný, tak by měl kromě jiného obsahovat nějaký firewall. To dnes splňují všechny, od komerčních Unixů, přes open source BSD, až po MacOS X a WindowsXP. Linux nevyjímaje. A právě paketovému filtru v Linuxu se budeme věnovat v následujících kapitolách.


3. Paketový filtr a Linux

Paketový filtr je v Linuxu od nepaměti. V každé nové řadě jádra je o něco lepší, konfigurovatelnější, modulárnější,.. Souběžně s ním se vyvíjely i nástroje na jeho konfiguraci z uživatelského prostoru.

Na cestě paketu linuxovým jádrem se nachází několik záchytných bodů. V každém nich lze definovat seznam filtrovacích pravidel. Sady filtrovacích pravidel pak tvoří řetězce(chains), kterými paket prochází. Filtrovací pravidlo je tvořeno popisem atributů paketu a akcí, která se vykoná, pokud paket odpovídá popisu. Pokud neodpovídá, je předán dalšímu pravidlu. Jestliže paket projde až na konec řetězce, je vykonána implicitní akce - tzv politika řetězce.

Kromě základních filtrovacích pravidel pustit/zahodit existují další typy pravidel:


3.1 Linux <= 2.0.x - ipfw + ipfwadm

Takto staré kernely se dnes už IMHO příliš nepoužívají, takže následující řádky berte jako odrazový můstek do problematiky. Já jsem takto starý kernel nikdy neviděl a vycházím pouze z materiálů na webu.

Kernely 2.0.x podporovaly čtyři vestavěné řetězce:

A tři akce které se daly s paketem provést: Jednotlivé filtry se daly vyskládat z následujících atributů: Následující schéma ukazuje cestu paketu jádrem.

   ___________________________________________________________________________
  |        ______________________________________________________________     |
  |        |                                                            |     |
  |account |                                   _______                  |     |
--| chain  |---> ______ --------> ~~~~~~~~ -->|forward|------> _______--|     |-> 
  |--------|    |input |   d     {Routing }   |Chain  |       |output | |-----|      
                |Chain |   e     {Decision}   |_______|   --->|Chain  |         
                |______|   m      ~~~~~~~~                |   |_______|         
                           a        |                     |    ^                
                           s        v                     |    |                
                           q    Local Process             |    |                
                           |        |                     |    |                
                           |        -----------------------    |                
                           |                                   |                
                           -------------------------------------                
Jádra 2.0.x podporovala i účtovací a přesměrovávací pravidla a maškarádu. Firewall se nastavoval pomoci utility
ipfwadm. (případně u ještě starších verzí ipfw, které má kořeny někde v BSD...). Protože se všechna nastavení po restartu ztratí, je dobré je mít pěkně pohromadě v jednom skriptu a ten spouštět před nahozením sítě.
Na osvětlení malý příklad, který hodně zhruba naznačuje, jak se s firewally v Linuxu pomoci ipfwadm pracovalo. Pozor, skript jako celek je prakticky nepoužitelný.
#!/bin/sh

#politika retezce forward je bez varovani zahazuj - defakto zakaz forwardovani
ipfwadm -F -p deny
#nastav default policy pro retezce input a output tak aby poustely pakety dal
ipfwadm -I -p accept
ipfwadm -O -p accept

#vyprazdnime vsechny retezce (-f = flush)(-I = input, -O = output, -A = accounting)
ipfwadm -F -f
ipfwadm -I -f
ipfwadm -O -f
ipfwadm -A -f

#vytvorime novy retezec
ipchains -N icmp_all
ipchains -F icmp_all

#do retezce putuje cele icmp z input chainu
ipchains -A input -p ICMP -j icmp_all
#poustime icmp jine nez type 5
ipchains -A icmp_all -p icmp --icmp-type ! 5 -j ACCEPT
#zakazeme(-j DENY) fragmentovane ICMP (-f) - ping of death
ipchains -A icmp_all -f -l -j DENY

#v retezci forward (-F) povolime (-a accept) pakety protokolu TCP/IP (-P TCP)
#jdouci ze zdrojove adresy 1.2.3.* a ze zdrojoveho portu v rozmezi
#1024 az 65535 (-S 1.2.3.0/24 1024:65535) na cilovou adresu 192.1.12.10 a
#a cilovy port 25
ipfwadm -F -a accept -b -P tcp -S 1.2.3.0/24 1024:65535 -D 192.1.2.10 25

#pocitame pakety/bajty (-A ) prenesene prez rozhrani eth1 (-W eth1)
#jdouci prez adresu 192.168.37.1 (-S ... a -D ... ) a port www
ipfwadm -A in -a -W eth1 -P tcp -D 192.168.37.1 www
ipfwadm -A out -a -W eth1 -P tcp -S 192.168.37.1 www

#presmerovani prichoziho www na lokalni www proxy port (-r 8080)
ipfwadm -I -a accept -r 8080 -P tcp -S 0.0.0.0/0 -D any/0 www
    

3.2 Linux 2.2.x - ipchains

Balík ipchains je používaný na jádrech 2.2.x.Je vylepšenou verzí ipfwadm s mírně změněnou syntaxí a s podporou pro nové funkce paketového filtru v 2.2.x kernelech. Z nich určitě stojí za zmínku tyto: Přes všechny nové funkce je vytváření firewallů s ipchains přehlednější a vůbec zábavnější práce než s ipfwadm. Aby byla jasnější syntaxe ipchains, tak o5 malá ukázka:
#logovat veskere SYN pakety, zadna akce
ipchains -A input -i ! lo -p TCP -y -l

#We don't like the NetBIOS and Samba leaking..
ipchains -A input -p TCP --dport 137:139 -j REJECT
ipchains -A input -p UDP --dport 137:139 -j REJECT

#ciste uctovani prichozich dat (eth0 je outside_device), zdna akce
ipchains -A input -i eth0 -d 172.16.1.1

#maskarada forwardovaneho provozu
ipchains -A forward -i eth1 -s 10.0.0.0/8 -j MASQ 

V prvním pravidle používáme logování paketů. To funguje tak, že všechny informace z hlavičky paketů vyhovujících danému pravidlu jsou předány démonu klogd a ten je nejčastěji předá dál démonu syslog. Ukázka syntaxe logů z ipchains:

Sep 28 15:09:46 172.16.1.10 kernel: Packet log: input - eth1 PROTO=6 172.16.1.4:1036 212.80.76.18:80 L=48 S=0x00 I=29952 F=0x4000 T=128 SYN (#3)

kde význam položek je následující: Pokud chcete vědět o ipchains více, pak doporučuji přečíst manuálovou stránku (man 8 ipchains),
IPChains HOWTO a číst firewall skripty, kterých je na internetu plno.

3.3 Linux 2.4.x - iptables

V jádrech řady 2.4 se poprvé objevil netfilter . Je to vlastně kostra, po které putuje paket. Na této kostře leží pět záchytných bodů. Pokud chce nějaký jaderný modul pracovat s pakety, zaregistruje se u netfiltru = zachytí se jednoho nebo víc záchytných bodu. Když pak paket do takového bodu dorazí, netfilter ho předá postupně všem zaregistrovaným modulům.

netfilter, jeho pět záchytných bodů a na nich pověšené moduly :

--->PREROUTING--->[ROUTE]--->FWD---------->POSTROUTING--->
   Conntrack         |       Mangle   ^    Mangle
   Mangle            |       Filter   |    NAT (Src)
   NAT (Dst)         |                |    Conntrack
                     |             [ROUTE]
                     v                |
                     IN Filter       OUT Conntrack
                     |  Conntrack     ^  Mangle
                     |  Mangle        |  NAT (Dst)
                     v                |  Filter
                     --local process--^
pozn. Mangle se drží všech pěti záchytných bodů až od kernelu 2.4.18.

Paketový filtr je pak modulem, který se registruje u netfiltru a "přilepí" se na FORWARD, LOCAL_IN a LOCAL_OUT. NAT je další modul. Pomocí NATu se řeší maškaráda, port forwarding a transparentní proxy. Na změnu jiných atributů než adres a portů je tu modul mangle. Ten umí například přepsat TOS, TTL nebo označkovat paket (MARK). V jádře 2.4 přibyla možnost stavové filtrace, která využívá znalosti příslušnosti paketu k určitému spojení. O tabulku aktivních spojení se stará modul conntrack(connection tracking). Toho pak využívá modul filter, který kromě běžných atributů paketů a jejich kombinací může filtrovat i podle stavu spojení. Conntrack rozlišuje čtyři stavy:

U iptables, nástupce ipchains, se samozřejmě zase změnila syntax a přibylo spousta nových voleb. Iptables umí všechny výše jmenované moduly obsluhovat. Co je potřeba udělat navíc, je specifikovat modul (neboli tabulku), se kterým pracujeme. Každý modul dělá něco jiného, používá specifické volby pro iptables a nabízí specifické akce. Ty pak nemůžeme použít s jinými moduly. Tyto závislosti ale přesahují samotné moduly a týkají se i řetězců, protokolů a dalších ( SYN flag má cenu kontrolovat pouze u TCP, u ICMP neexistuje port ale type/code, akci MASQUERADE můžeme použít pouze v tabulce (modulu) NAT,...).

3.3.1 filter

Modul filter prodělal spoustu změn, filtrování je možno definovat jemněji, návaznost na další moduly (conntrack) umožňuje dělat dříve nemožné ;) Akce prováděné s paketem: Logy iptables vypadají podobně jako u ipchains, i význam položek je stejný. Malý příklad:
Nov 27 12:03:14 holomraz kernel: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=84 TOS=0x00 PREC=0x00 TTL=255 ID=29235 PROTO=ICMP TYPE=0 CODE=0 ID=5390 SEQ=768

3.3.2 NAT

Network Adderss Translation podporuje čtyři akce:

3.3.3 mangle

mangle tabulka zavádí nový přepínač pro výběr paketu: a několik akcí: Víc o netfiltru, iptables a filtrování paketů obecně se můžete dočíst v
man iptables
netfilter homepage
IPtables tutorial
Netfilter hacking HOWTO

3.4 Pár tipů na psaní firewallu

3.4.1 procfs

Z /proc/sys/net můžete nejen spoustu věcí o nastavení firewallu vyčíst ale i nastavit. například

echo "1" > /proc/sys/net/ipv4/ip_forward
zapíná forwardování paketů. Bez tohohle si jako router/gateway ani neškrtnete.

echo "1" > /proc/sys/net/ipv4/ip_dynaddr
zapne podporu dynamickych IP adress. Hodí se když používáte PPP, DHCP, etc a chcete aby fungovalo.

a SPOUSTA dalších. Pokud znáte detailní popis, ozvěte se mi na mail.

3.4.2 protokoly bránící se filtrování

Některé protokoly nechtějí/neumějí/nemůžou dodržovat klasické klient-server schéma, kdy se klient ptá a vytváří spojení zatímco server odpovídá a spojení nevytváří. To pak působí problémy například při maškarádě. Řeší se to pomocí speciálních jaderných modulu, které danému protokolu rozumí. Pro aktivní FTP je tu ip_conntrack_ftp a ip_nat_ftp(v 2.2.x ip_masq_ftp). Pro IRC ip_conntrack_irc a ip_nat_irc (pro 2.2.x ip_masq_irc). Problémy dělají taky všechny možné on-line hry, icq, streamované audio/video, net konference a další.

3.4.3 testování firewallu

Jestliže máte napsaný a zavedený firewall a chcete ho otestovat, nemusíte čekat až na nás bude někdo útočit, ale můžete útočné pakety nasimulovat pomocí ipchains -C. Jestliže máte iptables, tak si ověřte, zda už je iptables -C implementováno (man iptables, sekce BUGS). Na RH7.3 není.

3.4.4 DNAT záludnosti

Pokud používáte DNAT na přesměrování požadavků na server s neveřejnou IP a chcete aby byl přez firewall přístupný pro počítače "venku" i pro počítače "uvnitř", tak nestačí pouze jedno DNAT pravidlo. Je potřeba ještě přepsat zdrojovou adresu na adresu firewallu, jinak interní server pošle odpověď přímo klientovi, který bude zmatený, protože dotaz poslal na firewall, ale odpověď přišla od jinud. Podobně je to s dotazy přímo z firewallu.

3.4.5 conntrack a stav NEW

Modul conntrack neurčuje zda paket bude NEW nebo nebude podle SYN flagů. To vede k tomu, že i obyčejný ACK-only paket může vytvořit nové spojení. Je to feature a ne bug. Pokud chcete tohle chování změnit, použijte pravidlo jako je tohle:
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:"
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

27.11.2002,
xzelinka@fi.muni.cz