Következő Előző Tartalom

7. Az iptables használata

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:

  1. Új lánc alkotása (-N).
  2. Üres lánc törlése (-X).
  3. Irányelv megváltoztatása beépített láncon (-P).
  4. Egy lánc szabályainak listázása (-L).
  5. A lánc összes szabályának törlése (-F).
  6. A csomag és byte-számlálók nullázása a lánc valamennyi szabályában (-Z).

A szabályok módosítására is több lehetséges mód van:

  1. Új szabály hozzáfűzése a lánchoz (-A).
  2. Új szabály beszúrása a láncba adott pozíción (-I).
  3. Az adott pozíción levő szabály cseréje újjal (-R).
  4. Adott pozíciójú szabály törlése a láncból (-D).
  5. Az első, erre illeszkedő szabály törlése a láncból (-D).

7.1 Mit fogsz látni, ha bekapcsolod a számítógépet?

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.

7.2 Műveletek egy egyszerű szabályon

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.

7.3 Szűrési beállítások

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:

Forráscím és célcím meghatározása

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.

Inverzió meghatározása

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.

Protokoll meghatározása

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.

Interfész meghatározása

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.

Töredékek meghatározása

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
#

Kiterjesztések az iptableshez: Új Illeszkedések

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
#

TCP Kiterjesztések

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)

--tcp-flags

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.

--syn

esetleg "!"-vel előtte, ez a rövidítés ugyanazt jelenti, mint a "--tcp-flags SYN,RST,ACK SYN".

--source-port

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.

--sport

ugyanaz, mint a "--source-port".

--destination-port

és

--dport

ugyanazt jelenti mint feljebb, csak ezek nem a csomag forrását, hanem célját határozzák meg porttal együtt.

--tcp-option

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.

A TCP flagek magyarázata

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.

UDP Kiterjesztések

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.

ICMP Kiterjesztések

Ezek a kiterjesztések automatikusan betöltődnek, ha a "-p icmp" kapcsolót meghatároztuk. Csak egy új opcióval szolgál:

--icmp-type

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.

Egyéb illeszkedések kiterjesztései

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.

mac

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:

--mac-source

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".

limit

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é:

--limit

é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").

--limit-burst

é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).

owner

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ó.

--uid-owner userid

Akkor illeszkedik, ha a csomagot egy, ezen opció után (User ID) megjelölt tulajdonsággal rendelkező process generálja.

--gid-owner groupid

Akkor illeszkedik, ha a csomagot egy, ezen opció után (Group ID) megjelölt tulajdonsággal rendelkező process generálja.

--pid-owner processid

Akkor illeszkedik, ha a csomagot a megadott PID-del rendelkező process generálta.

--sid-owner sessionid

Akkor illeszkedik, ha a megadott session groupban levő process generálta.

unclean

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 státusz-illeszkedés (State Match)

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:

NEW

Új kapcsolatot létesítő csomag.

ESTABLISHED

Egy csomag, mely létező kapcsolatot jelez (egy visszajelző csomag, vagy egy visszajelzett kapcsolaton kimenő csomag).

RELATED

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.

INVALID

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.

7.4 Célpont meghatározások

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 saját 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).

Az iptables kiterjesztései: Új célpontok

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 iptablesnek. Az alap netfilter disztribúcióban különböző kiterjesztéseket találunk:

LOG

Ez a modul az illeszkedő csomagok kernelszintű naplózását látja el. További hozzáadott opciókkal is szolgál:

--log-level

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.

--log-prefix

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.

REJECT

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.

Speciális beépített célpontok

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:

A standard queue kezelő az IPv4 iptables-hez az 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.

7.5 Műveletek egy beépített láncon

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.

Új lánc alkotása

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.

Lánc törlése

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)

Lánc kiürítése

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..

Lánc szabályainak listázása

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.

Számlálók nullázása

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.

Irányelv (policy) állítása

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
#


Következő Előző Tartalom