Az iptables aprólékosan részletezett manual oldalakkal rendelkezik (man iptables
) arra az esetre, ha további részletezésre vagy sajátosságokra lennél kiváncsi. Ha az ipchains-szel állsz bizalmasabb kapcsolatban, elég egy pillantást vetned a Különbségek az iptables és az ipchains között részre; nagyon hasonlóak.
Az iptables
egy sor különböző funkcióval rendelkezik.
Három beépített lánccal indul, az INPUT
, OUTPUT
és FORWARD
láncokkal, melyeket nem tudsz törölni.
Nézzük a lehetséges műveleteket a láncokkal:
A szabályok módosítására is több lehetséges mód van:
Az iptables lehet modulban (`iptable_filter.o'), ez automatikusan betöltődik az iptables
első futásakor. És lehet állandóan a kernelbe építve.
A számítógép indulásakor, mielőtt bármilyen iptables parancsot lefuttattunk volna (ne feledd: néhány disztribúció incializáló scriptből indítja őket), a három beépített láncban nincsenek szabályok, és valamennyi beépített lánc irányelve ACCEPT. A FORWARD lánc irányelvét meg tudod változtatni a "forward=0" opció használatával az iptable_filter modulon.
Ez a csomagszűrés sava-borsa: a szabályok alkotása és módosítása. A leggyakrabban a szabály hozzáfűzése (-A) és a szabály törlése (-D) parancsokat fogod használni. A többi parancs (-I a beszúrásra és -R a cserére) egyszerű kiterjesztése ezeknek.
Minden szabály meghatároz bizonyos tulajdonságokat, melyeknek illeszkedniük kell a csomagra, és persze meghatározza azt is, hogy mit kell tenni a csomaggal, ha a tulajdonság illeszkedik (ez a szabály "célpontja"). Például tételezzük fel, hogy minden, a 127.0.0.1 címről érkező ICMP csomagot el akarsz dobni. Ez esetben a tulajdonságok közül kettőnek kell illeszkednie: a protokollnak ICMP-nek kell lennie, a csomag forráscímének pedig 127.0.0.1-nek. A szabály célpontja pedig "DROP" lesz.
A 127.0.0.1 a visszacsatolt interfész, mely akkor is működik, ha nincs tényleges hálózati kapcsolatod. Adatcsomagok generálására a "ping" parancsot tudod használni (ez egy 8-as típusú ICMP csomagot küld (echo request) melyre az ellenállomás egy 0-ás típusú ICMP csomaggal válaszol (echo reply)). Ezért igen alkalmas hálózati kapcsolatok tesztelésére.
# 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
#
Láthattuk, hogy az első ping eredményes volt (a "-c 1" azt jelenti, hogy a ping csak 1 csomagot küld).
Aztán hozzáfűztünk (-A) az "INPUT" lánchoz egy szabályt, mely azt mondta, hogy a 127.0.0.1 címről érkező ("-s 127.0.0.1") ICMP protokollal rendelkező ("-p icmp") csomagokat el akarjuk dobni ("-j DROP").
Ezek után leteszteltük a szabályt a második ping használatával. Itt még egy kis szünetet is kaptunk, mert a ping egy darabig még várt a csomagra, mielőtt feladta volna a próbálkozást.
Két módon tudjuk a szabályokat törölni a láncból. Először is, mivel tudjuk, hogy ez az egyetlen szabály az INPUT láncban, használhatunk számozott törlést, mégpedig:
# iptables -D INPUT 1
#
Ezzel az INPUT lánc 1. szabályát töröltük.
A második mód az -A (hozzáfűzés) parancs tükörképe, de az -A parancsot -D -re cseréltük. Ezt akkor használjuk, ha egy komplexebb láncunk van és nem akarjuk egyesével megszámolni benne a szabályokat hogy kitaláljuk, hanyadik szabály ez. Ez esetben használhatjuk a
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
parancsot a szabály törlésére.
A -D szintaxisának pontosan egyeznie kell az -A (vagy -I, vagy -R) szintaxisával. Ha több erre a szabályra illeszkedő szabály van a láncban, csak az első fog törlődni.
Láthattuk, hogy a "-p" kapcsoló határozza meg a protokollt, és az "-s" való a forráscím meghatározására. Vannak azonban további opciók, melyekkel pontosabban meghatározhatjuk a csomagokat. Ez most következik összefoglalva:
A forrás ("-s", "--source" vagy "--src") és cél ("-d", "--destination" vagy "--dst") IP címeit 4 módon határozhatjuk meg. A legnépszerűbb a teljes név használata, mint például a "localhost" vagy "www.linuxhq.com". A második mód az IP cím meghatározása, pl. "127.0.0.1".
A harmadik és negyedik móddal IP címek csoporjait tudjuk meghatározni, mint például "199.95.207.0/24" vagy "199.95.207.0/255.255.255.0". Mindkettő meghatározás 199.95.207.0 tól 199.95.207.255-ig terjedő IP címeket határoz meg; a "/" jel utáni számok azt mutatják, hogy mekkora részét kell az IP-címnek figyelembe venni (bitben). (a TCP-csomagok fejlécében szereplő IP-cím 32 bites, azaz 4 byte-os - a ford.) "/32" vagy "/255.255.255.255" azt jelenti, hogy csak az az egy IP-cím érvényes (mind a 32 bitet figyelembe vettük). Ha minden IP-címre érvényes szabályt akarunk, használjuk a "/0" meghatározást, mint pl.:
[ MEGJEGYZÉS: a "-s 0/0" e példában felesleges ]
# iptables -A INPUT -s 0/0 -j DROP
#
Ezt ritkán használjuk, mivel a fenti példa ugynaz, mintha a szabályt "-s 0/0" nélkül alkottuk volna meg.
Néhány kapcsoló, közöttük a "-s" (vagy "--source") és a "-d" ("--destination") flagek tartalmazhatják argumentumukat "!" előtaggal is. (ez a logikai "nem"-nek felel meg) azon csomagok meghatározására, melyek egy adott tulajdonságnak NEM felelnek meg. Példa. "-s ! localhost" minden csomagra illeszkedik, melyek nem a helyi gépről származnak.
A protokollt a "-p" (vagy "--protocol") kapcsolóval határozzuk meg. A protokoll lehet egy szám (ha ismered a számszerű protokoll-értéket) vagy névvel, mint például "TCP", "UDP" vagy "ICMP". A kis- és nagybetű nem számít, a "-tcp" ugyanúgy működik, mint a "-TCP".
A protokoll neve elé tehetsz "!"-t is, ami az illeszkedést megfordítja. Tehát egy "-p ! TCP" opció minden olyan csomagra illeszkedni fog, melynek protokollja nem TCP.
Az "-i" (vagy "--in-interface") és az "-o" (vagy "--out-interface") kapcsolók
egy interfész nevével való egyezést határoznak meg. Az interfész a fizikai eszköz, melyen keresztül a csomag bejön ("-i") vagy kimegy ("-o"). "Fent" levő interfész megtekintésére az ifconfig
parancs használható ("fent" levőnek a pillanatnyilag működő interfészt tekintjük).
Az INPUT
láncra érkező csomagoknak nincs kimeneti interfészük ("-o"), ezért az INPUT
láncon ilyen szabály semmilyen csomagra nem fog illeszkedni.
És hasonlóképp, az OUTPUT
láncon kimenő csomagok bemeneti interfésszel nem rendelkeznek ("-i"), ezért ezen a láncon az "-i" kapcsolókkal meghatározott szabályokra nem fog illeszkedni csomag.
Csak a FORWARD
láncon átfutó csomagok rendelkeznek mind kimeneti, mind bemeneti interfésszel.
Ha jelenleg nem működő interfészt határozunk meg egy szabályban, az nem hibás szabály, viszont csak akkor lép életbe, ha az interfészt felhúzzuk, addig a szabály semmilyen csomagra nem fog illeszkedni. Ez igen jól használható PPP-s interfészek esetén. (általában
ppp0
vagy hasonló).
Egy speciális opció: ha az interfész név után "+"-et teszünk, az valamennyi interfészre illeszkedni fog (függetlenül attól, hogy az interfész fent van-e, vagy sem), melynek a neve a "+" előtti szöveggel kezdődik. Például egy olyan szabályt, mely az összes ppp interfészre illeszkedni fog, az -i ppp+
kapcsolóval használjuk.
Az interfész neve egy "!"-vel maga előtt azokra a csomagokra fog illeszkedni, melyek nem az adott interfészre érkeznek vagy nem az adott interfészről távoznak.
Néha egy csomag túl nagy ahhoz, hogy egyszerre továbbítsuk. Ez esetben a csomagot töredékekre bontjuk, és több, különálló csomagban küldjük el. A végponton ezek összeállnak, és újból rendelkezésünkre áll az eredeti csomag.
Ezekkel a töredékekkel az a baj, hogy csak az első csomag tartalmazza a komplett fejlécmezőket (IP + TCP, UDP és ICMP) a többi csomag pedig csak egy "kivonatát" a fejlécnek (IP a hozzáadott protokoll-mezők nélkül). Ezért ezeknek a csomagoknak a fejlécét nem tudjuk protokoll-szempontból megvizsgálni.
Ha NAT (Network Address Translation) használatával kapcsolódsz fel az Internetre, a csomagok újból összeállnak, mielőtt elérnék a csomagszűrőt. Ez esetben tehát nem kell a töredékektől tartanod.
Minden más esetben fontos megértened, hogy hogy bánnak a csomagszűrők a töredékekkel. Minden olyan szabály, mely nem létező tulajdonságot vizsgál, nem illeszkedőnek tekintendő. Ez azt jelenti, hogy - mivel az első csomagot ugyanúgy kezeli a csomagszűrő, mint a többit - a második és további töredékeket a csomagszűrő nem tudja vizsgálni. Így a szabály (-p TCP --sport www
) (forrás port meghatározása www-ként a "--sport www" segítségével) sosem fog illeszkedni egy töredékre (legalábbis az elsőtől különbözőre).
Csakúgy, mint az ellentétes szabály (-p TCP --sport ! www
) sem.
Mégis meg tudunk határozni szabályt a második és azt követő töredékekre, az "-f" (vagy "--fragment") kapcsolóval. Az is jó, ha olyan szabályt határozunk meg, amely nem a második és azt követő töredékekre illeszkedik, ez esetben a "-f" kapcsolót "!"-vel együtt használjuk.
Általában biztonságosnak tekinthetjük a második és további töredékek átengedését a csomagszűrőn, mivel a szűrés az első töredék alapján is egyértelműen meghatározza a csomag sorsát. Ennek ellenére vannak olyan hibák, melyek kihasználásával a töredékek alkalmasak lehetnek számítógépek feltörésére. Mindenesetre ez a te döntésed.
Megjegyzés rendszergazdáknak: az elformázott csomagokat (TCP, UDP és ICMP csomagok, melyek túl rövidek ahhoz hogy a tűzfal elolvassa a portokat vagy ICMP kódot és típust) a kernel eldobja ahogy vizsgálatokat kísérelne meg rajtuk. Így a TCP töredékek a 8-as pozíciótól kezdődnek.
Példánk szerint, a következő szabály valamennyi 192.168.1.1 IP-címre érkező töredéket eldob:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
Az iptables
kiterjeszthető, azaz mind a kernel, mind az iptables alkalmazás alkalmassá tehető újabb tulajdonságok vizsgálatának ellátására.
Ezek némelyike szokványos (vannak közöttük olyanok, melyeket már az ipchains
-ben is használtunk, csak nem kiterjesztésként), a többi pedig egzotikus.
A kiterjesztéseket mások írták, és különállóan terjesztik a felhasználók felé.
A kernel kiterjesztések általában a kernel modulok alkönyvtárában találhatók, mint például a /lib/modules/2.3.15/net. Ezek maguktól betöltődnek, ha a kernelt a CONFIG_KMOD beállítással konfiguráltad, így nem kell kézzel betöltened őket.
Az iptables program kiterjesztései megosztott könyvtárfileok (libraryk), melyek általában az /usr/local/lib/iptables/ könyvtárban vannak, bár néhány disztribúciónál a /lib/iptables vagy a /usr/lib/iptables könyvtárban találhatók meg.
A kiterjesztéseknek két típusa van: új célpontok, és új illeszkedések (az új célpontokról kicsit később mi is fogunk beszélni). Néhány protokoll kiterjesztéseit külön is megvizsgáljuk majd, jelenleg ezek a TCP, az UDP és az ICMP, ahogy azt lejjebb is látni fogjuk.
Ezért képes leszel arra, hogy új vizsgálatokat végezz parancssorból, a "-p" kapcsoló után, mely betölti a kiterjesztést. Hogy világos legyen, használd az "-m" kapcsolót a kiterjesztés betöltéséhez, minek következtében a kiterjesztett opciók elérhetővé válnak.
Kiterjesztéshez segítséget őgy kaphatsz, hogy betöltöd a kiterjesztést a "-p", "-j" vagy "-m" kapcsolók egyikével, mégpedig "-h" vagy "--help" kapcsolóval utána. Például:
# iptables -p tcp --help
#
A tcp kiterjesztések automatikusan betöltődnek, amint a "-p tcp" kapcsoló ezt meghatározza. Ez a következő opciókat teszi lehetővé: (a töredékek kezelésének kivételével)
esetleg "!"-vel utána, majd két szöveg a flagekről lehetővé teszi, hogy speciális vizsgálatokat végezz egy TCP csomagon. Az első szöveg a flagekről a maszk: egy lista azokról a flagekről, melyeket vizsgálni akarsz. A második szöveg a flegekről megmondja, melyik hogy legyen beállítva. Például,
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DROP
Ez azt jelenti, hogy valamennyi flaget vizsgáljuk ("ALL" ugyanaz, mint a "SYN,ACK,FIN,RST,URG,PSH"), de csak a SYN és az ACK flag lehet beállítva. Van itt még egy beállítási lehetőség, a "NONE" azt jelenti hogy egy flag sincs beállítva.
esetleg "!"-vel előtte, ez a rövidítés ugyanazt jelenti, mint a "--tcp-flags SYN,RST,ACK SYN".
esetleg "!"-vel utána, majd vagy egy port, vagy egy TCP port tartomány. A portok megadhatók számmal vagy névvel, ahogy az az /etc/services fileban le van írva. A tartomány két portnév vagy portszám, egy ":"-vel elválasztva, vagy (ha a porttal egyenlő vagy annál nagyobb portokat akarjuk meghatározni) a port neve ":"-vel utána, vagy (ha a porttal egyenlő vagy annál kisebb portokat akarjuk meghatározni) a port neve ":"-vel előtte.
ugyanaz, mint a "--source-port".
és
ugyanazt jelenti mint feljebb, csak ezek nem a csomag forrását, hanem célját határozzák meg porttal együtt.
esetleg egy "!"-val és egy számmal utána, egy erre a számra illeszkedő TCP opciót határoz meg. A nem teljes TCP fejléccel rendelkező csomagok automatikusan eldobásra kerülnek, amint kísérlet történik TCP tulajdonságaik vizsgálatára.
Néha hasznos, ha egyik irányban engedélyezzük a TCP forgalmat, a másik irányban pedig nem. Például, ha el akarunk fogadni csomagokat egy külső www szerver felé, de nem akarjuk, hogy a szerverről hozzánk kapcsolódjanak.
Elsőre azt gondolnánk, elég blokkolni a szerverről felénk érkező TCP csomagokat. Azonban sajnos a TCP kapcsolatok a működéshez mindkét irányban adatforgalmat igényelnek.
A megoldás az, ha csak azokat a csomagokat blokkoljuk, melyek kapcsolat igénylésére szolgálnak. Ezeket a csomagokat SYN csomagoknak hívjuk (OK, technikailag ők olyan csomagok, melyeknél a SYN flag beállított, és a FIN és ACK flagek nem, de a rövidség kedvéért ezeket SYN csomagoknak hívjuk). Ezen csomagok tiltásával meg tudjuk állítani a gépünkre való kapcsolódást.
A "--syn" kapcsolót a következőkre használjuk: csak olyan szabályokban érvényes, ahol a protokollt TCP-ként határoztuk meg. Például olyan TCP kapcsolat meghatározására mely a 192.168.1.1 IP-címről jön,
-p TCP -s 192.168.1.1 --syn
Ez a flag invertálható, ha "!"-t teszünk elé, ez minden olyan csomagra érvényes lesz, mely nem kapcsolat kezdeményezésére irányul.
Ezek a kiterjesztések automatikusan betöltődnek, ha a "-p udp" kapcsolót meghatároztuk. Lehetővé teszi a "--source-port", "--sport", "--destination-port" és "--dport" használatát, ahogy azt a TCP protokollnál taglaltuk.
Ezek a kiterjesztések automatikusan betöltődnek, ha a "-p icmp" kapcsolót meghatároztuk. Csak egy új opcióval szolgál:
esetleg "!"-vel utána, majd egy ICMP típus nevével (pl. "host-unreachable"), vagy számmal (pl. "3"), vagy számmal és kóddal, melyeket "/"-vel választunk el. Az elérhető ICMP típusok neveit a "-p icmp --help" paranccsal tudhatjuk meg.
A netfilter csomag többi kiterjesztése demonstrációs célokat szolgál, ezeket (amennyiben installálva vannak) az "-m" kapcsolóval hívhatod segítségül.
Ezt a modult önállóan kell betölteni a "-m mac" vagy a "--match mac" kapcsolókkal. Azt jelenti, hogy a bejövő csomag címét nem IP alapján vizsgáljuk, hanem az Ethernet (MAC) címük alapján és csak azokon a csomagokon használjuk, melyek a PREROUTING és INPUT láncokat érintik. Egy új opcióval szolgál:
esetleg "!"-vel utána, majd egy ethernet címmel (kettősponttal elválasztott hexabyte formában), pl.: "--mac-source 00:60:08:91:CC:B7".
Ezt a modult önállóan kell betölteni a "-m limit" vagy a "--match limit" kapcsolókkal. Az illeszkedések számának korlátozására használjuk, például naplózás elnyomására. Csak egy adott időt fog megfeleltetni adott gyakorisággal (alapesetben 3 megfelelés óránként, 5 csomagra). Két új opciót tesz elérhetővé:
és utána egy szám; meghatározza a másodpercenkénti maximális illeszkedések számát. A szám meghatározható kifejezésekkel, a "/second", "/minute", "/hour" és "/day" használatával, vagy részeikkel (például a "5/second" ugyanazt jelenti, mint a "5/s").
és utána egy szám, meghatározza a maximális csomagszámot mielőtt a felső limit korlátozna.
Ezt a megfelelést a LOG célponttal együtt használjuk, hogy arány-korlátolt naplózást használjunk. Hogy megértsük, hogy is működik ez, vessünk egy pillantást a következő szabályra, mely az alapérték szerinti beállításokkal naplózza a csomagokat:
# iptables -A FORWARD -m limit -j LOG
Először, mikor e szabályt alkalmazzuk, a csomag naplózásra kerül és az alapértelmezett csomagszámot a kernel egyel csökkenti. Valójábban, mivel az alapértelmezett csomagszám 5, az első 5 csomag kerül naplózásra. Ezután 20 perc fog eltelni, míg a következő csomag naplózásra kerül e szabály alapján, tekintet nélkül arra, hogy hány csomag illeszkedett e szabályra. Ezen túl minden 20 percben, mely anélkül telik el, hogy illeszkedő csomagot kapnánk, az alapértelmezett csomagszám visszanyer egyet értékéből, és így ha 100 percig nincs olyan csomag, mely a szabályra illeszkedne, a csomagszám visszanyeri eredeti értékét, és visszatér oda, ahonnan indultunk. (ide talán kell még egy kis magyarázat: vezessünk be három változót, a "t", a "p" és a "b" változókat. A "t" és a "p" változót a --limit kapcsolóval állítjuk be, a "b" változót a --limit-burst kapcsolóval. A "t" szám gyakorlatilag akármennyi lehet, a "p" lehet másodperc, perc, óra vagy nap, a "b" pedig megint csak akármennyi. A csomagok szép sorban érkeznek a csomagszűrőre. Ha egy csomagra illeszkedik a szabály, a szabály célpontjára küldi a kernel a csomagot, egyben a "b" változó értékét egyel csökkenti. Ezzel egyidőben elindít egy számlálót, mely a "p"/"t" értékénél egyel megnöveli a "b" értékét. Ez a gyakorlatban annyit jelent, hogy ha folyamatosan illeszkedő csomagok érkeznek a kernelhez, akkor az első "b" számú csomara illeszkedni fog az adott szabály, ezek után minden "p"/"t" időintervallum letelte után 1 csomagra. Ha nem jönnek illeszkedő csomagok, minden "p"/"t" idő eltelte után egyel nagyobb lesz az az érték, ahány csomagra a szabály illeszkedni fog. - a ford.)
Megjegyzés: jelenleg nem tudsz olyan szabályt generálni, melynek visszatöltési ideje nagyobb lenne 59 óránál, így ha az átlag rátát napi egyre állítod, a csomagszám mindenképp kisebb kell, hogy legyen 3-nál.
Ezen kívül arra is használhatod ezt a modult, hogy számítógépedet megvédd a Denial of Service (DoS) támadásoktól. Ehhez gyorsabb visszatöltést kell alkalmaznunk.
Syn-flood védelem:
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
Alattomos portscan elleni védelem:
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
A halál pingje elleni védelem:
# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
Ez a modul úgy működik, mint egy hiszterézis ajtó, ahogy azt az alábbi grafikonon meg is mutatjuk:
rate (pkt/s)
^ .---.
| / DoS \
| / \
Edge of DoS -|.....:.........\.......................
= (limit * | /: \
limit-burst) | / : \ .-.
| / : \ / \
| / : \ / \
End of DoS -|/....:..............:.../.......\..../.
= limit | : :`-' `--'
-------------+-----+--------------+------------------> time (s)
LOGIC => Match | Didn't Match | Match
Mondjuk azt, hogy másodpercenként egy csomag illeszkedhet ötös csomagszámlálóval, de a csomagok másodpercenként négyesével érkeznek három másodpercig, majd újabb három másodperc szünet után az egész folyamat ismétlődik.
<--Flood 1--> <---Flood 2--->
Total ^ Line __-- YNNN
Packets| Rate __-- YNNN
| mum __-- YNNN
10 | Maxi __-- Y
| __-- Y
| __-- Y
| __-- YNNN
|- YNNN
5 | Y
| Y Key: Y -> Illeszkedő szabály
| Y N -> Nem illeszkedő szabály
| Y
|Y
0 +--------------------------------------------------> Time (seconds)
0 1 2 3 4 5 6 7 8 9 10 11 12
Láthatod, hogy az első öt csomagra illeszkedik a szabály, azután a kernel korlátoz (itt éri el "b" változó értéke a 0-t. - a ford). Ha itt van egy kis szünet, utána újabb csomagokra fog a szabály illeszkedni, de itt sem haladhatjuk meg a csomagszámláló értékét (1 csomag másodpercenként, ha ezt a számlálást alkalmazzuk).
Ez a modul a helyileg generált csomagok esetén megpróbál illeszkedni a csomag alkotójának bizonyos tulajdonságaira. Csak az OUTPUT láncon érvényes, és ott is éppen akkor, ha bizonyos csomagoknak (például ICMP visszajelzéseknek) nincs tulajdonosuk és ezért az illeszkedés nem lenne megállapítható.
Akkor illeszkedik, ha a csomagot egy, ezen opció után (User ID) megjelölt tulajdonsággal rendelkező process generálja.
Akkor illeszkedik, ha a csomagot egy, ezen opció után (Group ID) megjelölt tulajdonsággal rendelkező process generálja.
Akkor illeszkedik, ha a csomagot a megadott PID-del rendelkező process generálta.
Akkor illeszkedik, ha a megadott session groupban levő process generálta.
Ez a kísérleti modul kézzel, a "-m unclean" vagy a "-match unclean" opciókkal töltendö be. Különböző "egészségi" (sanity) teszteket hajt végre a csomagokon. Ez a modul még nincs bevizsgálva, és nem ajánljuk biztonsági eszközként való alkalmazását (lehet hogy elront valamit, tekintve hogy lehetnek még benne bugok). Nem támogat semmilyen további opciót.
A leghasznosabb illeszkedési kritériumot a "state" kiterjesztés szolgáltatja, mely az "ip_conntrack" modul kapcsolat-követő analízisét interpretálja. Melegen ajánljuk.
Az "-m state" bejegyzése egy további "--state" opciót engedélyez, mely vesszővel elválasztott listája az illeszkedő állapotoknak (a "!" flag a nem megfelelést jelzi ezekre az állapotokra). Ezek az állapotok lehetnek:
Új kapcsolatot létesítő csomag.
Egy csomag, mely létező kapcsolatot jelez (egy visszajelző csomag, vagy egy visszajelzett kapcsolaton kimenő csomag).
Egy létező kapcsolathoz tartozó, de annak részét nem képező csomag, mint például egy ICMP hibaüzenet, vagy (beépített FTP modullal) egy ftp adatkapcsolatot létesítő csomag.
Egy valamilyen okból nem azonosítható csomag: ez magában foglalja a memória túlcsordulásokat és az ICMP hibaüzeneteket, melyek nem felelnek meg egyetlen ismert kapcsolatnak sem. Általában ezek a csomagok eldobandók.
Most már tudjuk, milyen vizsgálatokat végezhetünk egy csomagon, de tudnunk kell azt is, hogy mit csináljunk azokkal a csomagokkal, melyek a szabályainkra illeszkednek. Ez a szabály célpontja.
Két nagyon egyszerű beépített célpontunk van: a DROP és az ACCEPT. Már megismertünk mindkettejüket. Ha egy szabály illeszkedik egy csomagra és a szabály célpontja e két célpont valamelyike, további hajcihők nélkül a csomag sorsa eldöntetett.
Két típusa van a beépítetteken túlmenő célpontoknak: a kiterjesztések és a felhasználó által definiált láncok.
A három beépített láncon (INPUT, FORWARD, OUTPUT) túl a felhasználónak lehetősége van arra, hogy saját láncot vagy láncokat definiáljon. Ez egyike azon erősségeknek, melyeket az iptables
átvett az ipchains
-től. Hagyományok szerint a saját láncok neveit kisbetűvel írjuk, hogy megkülönböztessük őket a beépített láncoktól. (hamarosan megmutatjuk az új láncok definiálását, a Műveletek egy beépített láncon részben).
Ha egy csomag illeszkedik egy olyan szabályra, melynek célpontja egy saját lánc, a csomag elkezd sorban vándorolni a saját lánc szabályain. Ha a saját lánc nem dönti el a csomag sorsát, a csomag visszakerül az eredeti láncra és a következő szabállyal folytatja a vándorlást.
Itt az idő még egy kis ASCII művészetre. Két (meglehetősen leszőkített) láncot veszünk figyelembe: az INPUT
láncot (ez a beépített lánc) és a test
láncot (ez egy saját lánc).
`INPUT' `test'
---------------------------- ----------------------------
| Rule1: -p ICMP -j DROP | | Rule1: -s 192.168.1.1 |
|--------------------------| |--------------------------|
| Rule2: -p TCP -j test | | Rule2: -d 192.168.1.1 |
|--------------------------| ----------------------------
| Rule3: -p UDP -j DROP |
----------------------------
Nézzünk egy TCP csomagot, mely a 192.168.1.1 címről utazna a 1.2.3.4 címre. Ez a csomag keresztezi az INPUT
láncot, és annak első szabályára nem illeszkedik. A második szabály illeszkedik, és annak célpontja a test
lánc, így a következő vizsgálatot a test
lánc végzi. Itt, a test
lánc első szabálya illeszkedik, de nincs a szabálynak célpontja, így a csomag a második szabályra kerül. A második szabály viszont nem illeszkedik, és már el is értük a lánc végét. Visszatérünk tehát az
INPUT
láncra, ahol a 2. szabály küldte el a csomagot, most tehát a következő, 3. szabállyal folytatjuk. Ez szintén nem illeszkedik.
Így a csomag útja a következőképp alakul:
v __________________________
`INPUT' | / `test' v
------------------------|--/ -----------------------|----
| Rule1 | /| | Rule1 | |
|-----------------------|/-| |----------------------|---|
| Rule2 / | | Rule2 | |
|--------------------------| -----------------------v----
| Rule3 /--+___________________________/
------------------------|---
v
A saját láncokról további saját láncokra ugorhatunk (de ne tegyünk a konstrukcióba hurkot, mert ha a kernel ezt érzékeli, a hurokban keringő csomagot eldobja).
A célpontok másik típusa egy kiterjesztés. Egy célpont-kiterjesztés kernel-modulként létezik, és egy további, parancssorból vezérelhető opciókat ellátó kiterjesztése az iptables
nek. Az alap netfilter disztribúcióban különböző kiterjesztéseket találunk:
Ez a modul az illeszkedő csomagok kernelszintű naplózását látja el. További hozzáadott opciókkal is szolgál:
Egy számmal vagy névvel követve. A használható nevek (kis- vagy nagybetűsek egyaránt): "debug", "info", "notice", "warning", "err", "crit", "alert" és "emerg", a számok az előbbi felsorolás számai 7-0-ig. Ha ezen naplózási szintek részleteire vagy kiváncsi, tekintsd meg a syslog.conf manual oldalait.
Egy maximum 29 karakteres szöveggel követve, ez az üzenet a log üzenetek elejére kerül az egyedi azonosítás érdekében.
Ez a modul leghasználhatóbb bizonyos határok túllépésének naplózására. Vigyázz, hogy ne szemeteld tele a logfájljaidat.
Ez a modul ugyanazt eredményezi mind a "DROP" célpont, annyi különbséggel, hogy a csomag küldője "port unreachable" hibaüzenetet kap. Gondolj arra is, hogy bizonyos esetekben ez az ICMP hibaüzenet nem kerül elküldésre (lásd: RFC 1122):
A "REJECT" egy "--reject-with" opcióval is szolgál, mely változtatja a használt visszajelzés-csomagot is: további részleteket a manual oldalakban találsz.
Két speciális beépített célpontot különböztetünk meg: a RETURN
és
QUEUE
célpontokat.
A RETURN
ugyanazt játsza el, mintha a csomag illeszkedés nélkül végigvándorolt volna az egész láncon: beépített lánc esetén a lánc irányelve (policy) kerül alkalmazásra, saját lánc esetén a csomag visszkerül az előző láncra és annak következő szabályaival folytatja útját.
A QUEUE
egy különleges célpont, mely a felhasználói térbe sorolja a csomagot. Hogy ez az opció használható is legyen, két további összetevőre van szükségünk:
ip_queue
modul, melyet a kernel forrásával együtt szállítanak és kísérleti modulként van megjelölve.
Lássunk egy gyors példát arra, hogy irányítja az iptables
a csomagokat a felhasználói térbe:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
Ezzel a szabállyal a helyben generált ICMP csomagok eljutnak az ip_queue modulig, mely ezután megpróbálja eljutatni azokat egy felhasználói alkalmazáshoz. Ha felhasználói alkalmazás nem várakozik, a csomagot eldobja.
Felhasználói alkalmazás írásához használd a libipq API-t. Ezt az iptables-szel együtt forgalmazzák. Egy példakód megtalálható a kísérőeszközök között (pl. redirect.c) a CVS-ben.
Az ip_queue állapota lekérdezhető a következő fájlon:
/proc/net/ip_queue
A queue maximális hossza (a felhasználói térbe utasítás nélkül visszatérő csomagok száma) állítható a következő fájlon:
/proc/sys/net/ipv4/ip_queue_maxlen
A queue hosszának alapbeállítás szerinti értéke 1024. Az ez után következő csomagok eldobásra kerülnek egészen addig, míg a queue hossza ismét a limit alá csöken.A jobb protokollok, mint a TCP torlódásként kezelik az eldobott csomagokat, és a queue feltöltése után reményteljesen háttérbe vonulnak. Szóval igényel némi kísérletezgetést a queue ideális hosszának beállítása egy adott szituációra, ha az alapbeállítás szerinti hossza rövidnek bizonyulna.
Az iptables
egyik igen hasznos tulajdonsága, hogy a fontosabb szabályokat láncba szedjük. Úgy kereszteled el ezeket a láncokat, ahogy akarod, én a kisbetűs elnevezést ajánlom, nehogy összekeverd őket a beépített láncokkal vagy a célpontokkal. A láncok nevei maximum 31 karakter hosszúak lehetnek.
Nosza, alkossunk új láncot! Mivel rendkívül találékonyak vagyunk, test
-nek fogjuk hívni. Használjuk a "-N" vagy a "--new-chain" parancsok egyikét:
# iptables -N test
#
Ilyen egyszerű ez. Most már szabályokat fűzhetünk ebbe a láncba, ahogy azt feljebb megtanultuk.
Egy lánc törlése ugyanilyen egyszerű, csak a "-X" vagy a "--delete-chain" parancsot kell használni. De miért pont az "-X"? Nos azért, mert az összes többi jó betűt már előbb felhasználtuk.
# iptables -X test
#
Van egy pár szabály láncok törlésére: a láncnak üresnek kell lennie (lásd a Lánc kiürítése pontot lejjebb) és nem lehet semmilyen létező szabály célpontja. A három beépített lánc nem törölhető.
Ha nem határozod meg a törlendő láncot, az összes saját láncod törlődni fog (már amennyiben ez lehetséges)
Legegyszerűbben a "-F" vagy a "--flush" paranccsal üríthetünk ki egy láncot.
# iptables -F FORWARD
#
Ha nem határozod meg a kiürítendő láncot, az összes lánc összes szabálya törlődni fog..
Egy lánc összes szabályát kilistázhatod a "-L" vagy a "--list" paranccsal.
A "refcnt" minden saját láncra kilistázza azoknak a szabályoknak a számát, melyeknek célpontja az adott saját lánc. Ennek 0-nak kell lennie a lánc törlése előtt.
A lánc nevének elhagyásával az összes lánc összes szabályát kilistázzuk.
Az "-L" paranccsal 3 opciót használhatsz: az "-n" (numeric) opció megóvja az iptablest
attól, hogy a szabályokban szereplő IP-címek feloldása érdekében esetleg külső névszerverhez forduljon, ezzel megakadályozza a hosszú várakozásokat. Természetesen ez az opció azt is jelenti, hogy a TCP és UDP portok is inkább számokként jelennek meg mint nevekként.
A "-v" opció megmutatja neked a szabályokhoz tartozó valamennyi adatot (például a szabályra illeszkedő csomagok száma és ezek együttes mérete, az interfészek, a TOS összehasonlítás). Egyébként ezek nem kerülnének listázásra.
Jegyezd meg, hogy a csomag és byteszámlálók kapcsoló nélkül a "K", "M" vagy "G" utótaggal mutatják meg értéküket, jelezve annak 1000-szeres, 1 000 000-szoros vagy 1 000 000 000-szoros voltát. Az "-x" (expand numbers) kapcsolóval az értékek teljes számokként lesznek megmutatva.
Hasznos, ha képes vagy a számlálók lenullázására bizonyos időközönként. Erre a "-Z" parancsot alkalmazhatod.
Tételezzük fel a következőt:
# iptables -L FORWARD
# iptables -Z FORWARD
#
A fenti példában a csomagok átgyalogoltak az "-L" és a "-Z" parancsokon is. Hogy ezt elkerüld, és lehetővé tedd a számlálók olvasás közbeni nullázását, használd a két parancsot együtt.
A csomagoknak láncok közötti vándorlása kapcsán már említettük, mi történik, ha a csomag eléri egy beépített lánc végét. Ez esetben a lánc irányelve határozza meg a csomag sorsát. Csak a beépített láncoknak (INPUT
, OUTPUT
and
FORWARD
) van irányelvük, mivel ha a csomag egy beépített lánc végét éri el, nincs lehetősége rá, hogy az előző lánc következő szabályára ugorjon, mint ahogy erről feljebb beszéltünk.
Az irányelv lehet: ACCEPT
vagy DROP
, például:
# iptables -P FORWARD DROP
#