FreeBSD kézikönyv
Előző | Fejezet 30. Tűzfalak | Következő

# 30.5. Az IPFILTER (IPF) tűzfal

Az IPFILTER szerzője Darren Reed. Az IPFILTER nem kötődik egyik rendszerhez sem: ez egy olyan nyílt forráskódú alkalmazás, amelyet átírtak FreeBSD, NetBSD, OpenBSD, SunOS™, HP/UX és Solaris™ operációs rendszerekre. Az IPFILTER karbantartása és támogatása pillanatnyilag is aktív, folyamatosan jelennek meg újabb változatai.

Az IPFILTER egy rendszermag oldalán működő tűzfalazási és egy címfordítási mechanizmusra alapszik, amelyet felhasználói programokkal tudunk felügyelni és vezérelni. A tűzfal szabályai az ipf(8) segédprogrammal állíthatóak be vagy törölhetőek. A hálózati címfordításra vonatkozó szabályokat az ipnat(1) segédprogrammal állíthatjuk be vagy törölhetjük. Az ipfstat(8) segédprogram képes futás közben statisztikákat készíteni az IPFILTER rendszermagban elhelyezkedő részeinek viselkedéséről. Az ipmon(8) program pedig az IPFILTER cselekvéseit képes a rendszernaplókba feljegyezni.

Az IPF eredetileg olyan szabályfeldolgozási módszer szerint készült, amelyben “az utolsó egyező szabály nyer” és csak állapotnélküli szabályokat ismert. Az idő múlásával az IPF részévé vált a “quick” opció és a “keep state” opción keresztül az állapottartás is, melyek drámai mértékben korszerűsítették a szabályok feldolgozásának elvét. Az IPF hivatalos dokumentációja csak a régi szabályok létrehozását és azok feldolgozásának leírását tartalmazza. A korszerűsített funkciók csak kiegészítésképpen jelennek meg, és az általuk felkínált előnyök megértése egy sokkal magasabb szintű és biztonságosabb tűzfal megépítését teszik lehetővé.

A szakaszban szereplő utasításokban olyan szabályok szerepelnek, amelyek kihasználják a “quick” és “keep state” opciókat. Ezek az inkluzív tűzfalszabályok létrehozásának alapjai.

A régi típusú szabályokról a http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1 és http://coombs.anu.edu.au/~avalon/ip-filter.html címeken olvashatunk (angolul).

Az IPF gyakran ismételt kérdései a http://www.phildev.net/ipf/index.html címen érhetőek el (angolul).

A nyílt forrású IPFILTER levelezési lista kereshető archívumait a http://marc.theaimsgroup.com/?l=ipfilter címen találjuk (angolul).

## 30.5.1. Az IPF engedélyezése

Az IPF megtalálható a FreeBSD alaptelepítésében mint menet közben külön betölthető modul. Ha az `rc.conf` állományba beírjuk a `ipfilter_enable="YES"` sort, akkor ez a modul dinamikusan betöltődik. A betölthető modul alapból naplóz és a `default pass all` beállítást tartalmazza. Ha helyette a `block all` szabályt akarjuk használni, akkor emiatt még nem kell feltétlenül újrafordítanunk a FreeBSD rendszermagját, elég ha egyszerűen csak a szabályrendszerünk végére beszúrjuk.

## 30.5.2. A rendszermag beállításai

Az IPF használatához nem kötelező a következő beállításokkal újrafordítani a FreeBSD rendszermagját, itt csupán háttérinformációként szerepel. Amikor az IPF a rendszermagba kerül, a betölhető modulra nem lesz szükség.

Az IPF a rendszermag forrásai között található `/usr/src/sys/conf/NOTES` állományban megadott beállításai a következő módon foglalhatóak össze:

    options IPFILTER
    options IPFILTER_LOG
    options IPFILTER_DEFAULT_BLOCK

Az `options IPFILTER` engedélyezi az “IPFILTER” tűzfal támogatását.

Az `options IPFILTER_LOG` hatására az IPF az `ipl` csomagnaplózó pszeudo eszközre jegyzi fel a forgalmat -- minden olyan szabály esetén, ahol megjelenik a `log` kulcsszó.

Az `options IPFILTER_DEFAULT_BLOCK` megváltoztatja az alapértelmezett viselkedést, tehát minden olyan csomag, amely nem illeszkedik a tűzfal valamelyik `pass` típusú (átengedő) szabályára, blokkolásra kerül.

Ezek a beállítások csak azt követően érvényesülnek, ha fordítottunk és telepítettünk velük egy új rendszermagot.

## 30.5.3. Az `rc.conf` állomány beállításai

Az `/etc/rc.conf` állományban a következő utasításokra lesz szükségünk az IPF működésbe hozására a rendszer indítása során:

    ipfilter_enable="YES"             # az ipf tűzfal indítása
    ipfilter_rules="/etc/ipf.rules"   # betölti a szabályokat tartalmazó szöveges állományt
    ipmon_enable="YES"                # elindítja az IP monitor naplózását
    ipmon_flags="-Ds"                 # D = indítás démonként
                                      # s = naplózás a syslog használatával
                                      # v = a tcp ablak, ack, seq csomagok naplózása
                                      # n = az IP-címek és portok feloldása

Ha olyan helyi hálózat áll meg a tűzfal mögött, amely egy fenntartott privát IP-címtartományt használ, akkor még a következő utasításokra is szükségünk lesz a címfordítás bekapcsolásához:

    gateway_enable="YES"              # a helyi hálózat átjárója
    ipnat_enable="YES"                # az ipnat funkció elindítása
    ipnat_rules="/etc/ipnat.rules"    # az ipnat működéséhez szükséges definíciók

## 30.5.4. IPF

Az ipf(8) parancs használható a szabályokat tartalmazó állomány betöltésére. Általában egy állományba írjuk össze a tűzfal szabályait és ezzel a paranccsal cseréljük le egyszerre a tűzfalban levő jelenlegi szabályokat:

    # ipf -Fa -f /etc/ipf.rules

Az `-Fa` az összes belső szabály törlését jelenti.

Az `-f` jelzi, hogy egy állományból kell beolvasni a betöltendő szabályokat.

Ezzel mintegy lehetőségünk van változtatni a korábban összeállított szabályainkon, futtatni a fenti IPF parancsot és ezen keresztül úgy frissíteni a szabályok friss másolatával a már működő tűzfalat, hogy nem is kell újraindítanunk a rendszert. Ez a módszer igen kényelmes az új szabályok kipróbálásához, mivel bármikor tetszőlegesen végrehajtható.

Az ipf(8) man oldala tartalmazza a parancsnak megadható további beállításokat.

Az ipf(8) parancs a szabályokat tároló állományt egy szabványos szöveges állománynak tekinti, semmilyen szimbolikus helyettesítést alkalmazó szkriptet nem fogad el.

Lehetőségünk van azonban olyan IPF szabályokat készíteni, amelyek kiaknázzák a szkriptek szimbolikus helyettesítésének lehetőségeit. Erről bővebben lásd 30.5.9 Szakasz.

## 30.5.5. Az IPFSTAT

Az ipfstat(8) alapértelmezés szerint a arra használatos, hogy le tudjuk kérdezni és megjeleníteni a tűzfalhoz tartozó számlálók értékeit, amelyek a legutóbbi indítás vagy az `ipf -Z` parancs által kiadott lenullázásuk óta a bejövő vagy kimenő forgalomból a megadott szabályoknak megfelelő csomagok alapján gyűjtenek össze statisztikákat.

A parancs működésének részleteit az ipfstat(8) man oldalon olvashatjuk.

Az ipfstat(8) meghívása alapból így néz ki:

    input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
     output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
     input packets logged: blocked 99286 passed 0
     output packets logged: blocked 0 passed 0
     packets logged: input 0 output 0
     log failures: input 3898 output 0
     fragment state(in): kept 0 lost 0
     fragment state(out): kept 0 lost 0
     packet state(in): kept 169364 lost 0
     packet state(out): kept 431395 lost 0
     ICMP replies: 0 TCP RSTs sent: 0
     Result cache hits(in): 1215208 (out): 1098963
     IN Pullups succeeded: 2 failed: 0
     OUT Pullups succeeded: 0 failed: 0
     Fastroute successes: 0 failures: 0
     TCP cksum fails(in): 0 (out): 0
     Packet log flags set: (0)

Az `-i` mint bejövő (inbound), vagy az `-o` mint kimenő (outbound) forgalomra vonatkozó paraméterek megadásával a rendszermagban az adott oldalon jelenleg telepített és alkalmazott szabályokat kérhetjük le és jeleníthetjük meg.

Az `ipfstat -in` parancs így a bejövő forgalomra vonatkozó belső szabályokat mutatja a szabályok számával.

Az `ipfstat -on` parancs a kimenő forgalmat érintő belső szabályokat mutatja a szabályok számával.

Az eredmény körülbelül ilyen lesz:

    @1 pass out on xl0 from any to any
    @2 block out on dc0 from any to any
    @3 pass out quick on dc0 proto tcp/udp from any to any keep state

Az `ipfstat -ih` a bejövő forgalomhoz tartozó belső szabályokat mutatja és mindegyik elé odaírja, hogy eddig mennyi csomag illeszkedett rájuk.

Az `ipfstat -oh` ugyanígy a kimentő forgalom esetén mutatja a belső szabályokat és mindegyik előtt feltünteti, hogy az adott pillanatig mennyi csomag illeszkedett rájuk.

A kimenete nagyjából ilyen lesz:

    2451423 pass out on xl0 from any to any
    354727 block out on dc0 from any to any
    430918 pass out quick on dc0 proto tcp/udp from any to any keep state

Az `ipfstat` parancs talán egyik legfontosabb funkciója a `-t` kapcsolóval csalható elő, melynek hatására a rendszerben aktív állapotok táblázatát mutatja meg ugyanúgy, ahogy a top(1) a FreeBSD rendszerben futó programokat. Amikor a tűzfalunk támadás alatt áll, ezzel a funkcióval tudjuk a problémát beazonosítani, leásni a mélyébe és látni a támadótól érkező csomagokat. A kiegészítésképpen megadható alkapcsolók megadásával kiválaszthatjuk azt a cél vagy forrás IP-címet, portot vagy protokollt, amelyet valós időben meg akarunk figyelni. Ennek részleteit az ipfstat(8) man oldalán láthatjuk.

## 30.5.6. Az IPMON

Az `ipmon` megfelelő működéséhez be kell kapcsolnunk a rendszermag `IPFILTER_LOG` beállítását. Ez a parancs két különböző módban használható. Ha parancsot a `-D` opció nélkül gépeljük be, akkor ezek közül alapból a natív módot kapjuk meg.

A démon mód abban az esetben hasznos, ha folyamatosan naplózni akarjuk a rendszerben zajló eseményeket, majd később ezeket átnézni. Így képes egymással együttműködni a FreeBSD és az IPFILTER. A FreeBSD beépítve tartalmaz olyan lehetőséget, aminek révén magától cseréli a rendszernaplókat. Ezért ha átküldjük a syslogd(8) démonnak a naplózandó üzeneteket, akkor sokkal jobban járunk, mintha egyszerűen csak mezei állományba naplóznánk. Az `rc.conf` alapértelmezései között az `ipmon_flags` beállítás a `-Ds` kapcsolókat rögzíti:

    ipmon_flags="-Ds" # D = indítás démonként
                      # s = naplózás a syslog használatával
                      # v = a tcp ablak, ack, seq csomagok naplózása
                      # n = az IP-címek és portok nevének feloldása

Ennek a viselkedésnek az előnyei minden bizonnyal egyértelműek. Segítségével képesek vagyunk az esetek megtörténte után átnézni, hogyan milyen csomagokat dobott el a rendszer, azok milyen címekről érkeztek és hova szánták. Ez egy komoly fegyver a támadók lenyomozásában.

Hiába engedélyezzük a naplózást, az IPF önszántából semmilyen naplózási szabályt nem fog gyártani. A tűzfal gazdájának kell eldöntenie, hogy a szabályokat közül melyiket akarja naplózni, és így neki kell megadnia a `log` kulcsszót ezekben az esetekben. Normális esetben csak a `deny` szabályokat naplózzák.

Egyáltalán nem ritka, hogy a szabályrendszer végén egy alapértelmezés szerint mindent eldobó szabály áll, amely naplóz. Ezzel lehetőségünk nyílik rögzíteni azokat a csomagokat, amelyek egyetlen szabályra sem illeszkedtek.

## 30.5.7. Naplózás az IPMON használatával

A syslogd egy saját módszert alkalmaz a naplózott adatok elkülönítésére. Egy “funkciók” (facility) és “szintek” (level) segítségével kialakított speciális csoportosítást alkalmaz. Az IPMON `-Ds` módja a `security` (biztonság) “funkciót” használja. Tehát az IPMON által naplózott összes adat a `security` csoportjába kerül. Ezen túl a következő szinteken különíthetjük el igényeinknek megfelelően a naplózott adatokat:

    LOG_INFO - az átengedés vagy blokkolás helyett a "log" kulcsszóval ellátott csomagok
    LOG_NOTICE - az át is engedett csomagok
    LOG_WARNING - a blokkolt csomagok
    LOG_ERR - a naplózott csomagok közül azok, amelyek túlságosan kicsik (hibás a fejlécük)

Az IPFILTER csak akkor tud naplózni a `/var/log/ipfilter.log` állományba, ha előtte létrehozzuk. Az alábbi parancs erre tökéletesen megfelelő:

    # touch /var/log/ipfilter.log

A syslogd(8) működését az `/etc/syslog.conf` állományban szereplő definíciók vezérlik. A `syslog.conf` állomány számottevő mértékben képes meghatározni azt, ahogy a syslog az IPF és a hozzá hasonló alkalmazásoktól kapott rendszerszintű üzeneteket kezeli.

Az `/etc/syslog.conf` állományba az alábbi sor kell felvennünk:

    security.* /var/log/ipfilter.log

A `security.*` megadásával az összes ilyen típusú üzenet egy előre rögzített helyre kerül.

Az `/etc/syslog.conf` állományban elvégzett módosításokat úgy léptethetjük érvénybe, ha újraindítjuk a számítógépet vagy az `/etc/rc.d/syslogd reload` paranccsal megkérjük a syslogd(8) démont, hogy olvassa újra az `/etc/syslog.conf` állományt.

Az imént létrehozott naplót ne felejtsük el megadni az `/etc/newsyslog.conf` állományban sem, és akkor ezzel a cseréjét is megoldjuk.

## 30.5.8. A naplózott üzenetek formátuma

Az `ipmon` által létrehozott üzenetek whitespace karakterekkel elválasztott adatmezőkből állnak. A következő mezők az összes üzenet esetében megjelennek:

1. A csomag megérkezésének dátuma

2. A csomag megérkezésének időpontja. ÓÓ:PP:MM.E alakban jelennek meg az órák, percek, másodpercek és ezredmásodpercek (ez több számjegy hosszú is lehet) szerint

3. Azon interfész a neve, ahol a csomag feldolgozásra került, például `dc0`

4. A szabályhoz tartozó csoport és sorszám, például `@0:17`

Ezek az `ipfstat -in` paranccsal nézhetőek meg.

1. Cselekvés: a p mint átment (passed), b mint blokkolt (blocked), S mint rövid csomag (short packet), n mint egyik szabályra sem illeszkedett (not match), L mint naplózás (log). A módosítók megjelenítésének sorrendje: S, p, b, n, L. A nagybetűs P és B azt jelzi, hogy a csomagot egy felsőbb szintű beállítás miatt naplózták, nem egy szabály hatására.

2. Címek: ez tulajdonképpen három mezőt takar: a forrás címet és portot (melyet egy vessző választ el), a -> jelet és cél címet és portot. Például: `209.53.17.22,80 -> 198.73.220.17,1722`.

3. A `PR` után a protokoll neve vagy száma olvasható, például `PR tcp`.

4. A `len` csomaghoz tartozó fejléc és törzsének teljes hosszát jelöli, például `len 20 40`.

Amennyiben a csomag TCP, egy kötőjellel kezdődően további mezők is megjelenhetnek a beállított opcióknak megfelelő betűk képében. A betűket és beállításaikat az ipmon(8) man oldalán olvashatjuk.

Amennyiben a csomag ICMP, a sort két mező zárja, melyek közül az első tartalma mindig “ICMP”, és ezt egy perjellel elválasztva az ICMP üzenet típusa és altípusa követi. Tehát például az ICMP 3/3 a “nem elérhető port” üzenetet hordozza.

## 30.5.9. A szabályok felírása szimbolikus helyettesítéssel

Az IPF használatában gyakorlott felhasználók közül néhányan képesek olyan stílusú szabályrendszert készíteni, ahol szimbolikus helyettesítést használnak. Ennek az egyik legnagyobb előnye az, hogy ilyenkor elég csak a szimbolikus névhez tartozó értéket megváltoztatni és amikor a szkript lefut, akkor az összes rá hivatkozó szabályba ez kerül be. Szkript lévén a szimbolikus helyettesítéssel ki tudjuk emelni a gyakran használt értékeket és behelyettesíteni ezeket több helyre. Ezt a most következő példában láthatjuk.

Az itt alkalmazott felírás kompatibilis az sh(1), csh(1) és tcsh(1) parancsértelmezőkkel.

A szimbolikus helyettesítést egy dollárjellel fejezzük ki: `$`.

A szimbolikus mezőkben nem szerepel a $ jelölés.

A szimbolikus mező tartalmát kettős idézőjelbe (`"`) tesszük.

Kezdjük így el a szabályok írását:

    ######### Az IPF szabályait tartalmazó szkript eleje ###########

    oif="dc0"            # a kimenő interfész neve
    odns="192.0.2.11"    # az internet szolgáltató névszerverének IP-címe
    myip="192.0.2.7"     # a szolgáltatótól kapott statikus IP-címünk
    ks="keep state"
    fks="flags S keep state"

    # Választhatunk, hogy az /etc/ipf.rules állományt ebből a szkriptből
    # hozzuk létre vagy futtathatjuk "magát" a szkriptet.
    #
    # Egyszerre csak az egyik sort használjuk.
    #
    # 1) Ezzel gyárhatjuk le az /etc/ipf.rules állományt:
    #cat > /etc/ipf.rules << EOF
    #
    # 2) Ezzel futtathajuk "magát" a szkriptet:
    /sbin/ipf -Fa -f - << EOF

    # Engedélyezzük a szolgáltató névszerverének elérését.
    pass out quick on $oif proto tcp from any to $odns port = 53 $fks
    pass out quick on $oif proto udp from any to $odns port = 53 $ks

    # Engedélyezzük kifelé a titkosítatlan www funkciót.
    pass out quick on $oif proto tcp from $myip to any port = 80 $fks

    # Engedélyezzük kifelé a TLS SSL felett üzemelő titkosított www funkciót.
    pass out quick on $oif proto tcp from $myip to any port = 443 $fks
    EOF
    ################## Itt az IPF szkript vége ########################

Ennyi lenne. A példában szereplő szabályok most nem annyira lényegesek, a hangsúly most igazából a szimbolikus helyettesítésen és annak használatán van. Ha a fenti példát az `/etc/ipf.rules.script` állományba mentjük, akkor ezeket a szabályokat a következő paranccsal újra tudjuk tölteni:

    # sh /etc/ipf.rules.script

Egyetlen aprócska gond van a beágyazott szimbólumokat tartalmazó állományokkal: az IPF maga nem képes megérteni a helyettesítéseket, azért közvetlenül nem olvassa a szkriptet.

Ez a szkript két módon hasznosítható:

- Vegyük ki megjegyzésből a `cat` paranccsal kezdődő sort, és tegyük megjegyzésbe az `/sbin/ipf` kezdetűt. A megszokottak szerint tegyük az `ipfilter_enable="YES"` sort az `/etc/rc.conf` állományba, majd minden egyes módosítása után futtassuk le a szkriptet az `/etc/ipf.rules` állomány létrehozásához vagy frissítéséhez.

- Tiltsuk le az IPFILTER aktiválását a rendszerindításkor, tehát írjuk bele az `ipfilter_enable="NO"` sort (ami mellesleg az alapértelmezett értéke) az `/etc/rc.conf` állományba.

  Tegyünk egy, az alábbi szkripthez hasonlót az `/usr/local/etc/rc.d/` könyvtárba. A szkriptnek adjuk valamilyen értelmes nevet, például `ipf.loadrules.sh`. Az `.sh` kiterjesztés használata kötelező.

      #!/bin/sh
      sh /etc/ipf.rules.script

  A szkript engedélyeit állítsuk be úgy, hogy a `root` tulajdonában legyen és képes legyen olvasni, írni valamint végrehajtani.

      # chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh

Most miután a rendszer elindult, az IPF szabályai be fognak töltődni.

## 30.5.10. Szabályrendszerek az IPF-ben

Az IPF esetében a szabályrendszer olyan szabályokból áll, amelyek a csomagokról tartalmuk alapján eldöntik, hogy át kell engedni vagy vissza kell tartani. A gépek közt két irányban áramló csomagok egy munkamenet alapú társalgást képeznek. A tűzfalhoz tartozó szabályrendszer egyaránt feldolgozza a internetről a hálózatunk felé igyekvő csomagokat, illetve a hálózatunk ezekre adott válaszait. Az egyes TCP/IP szolgáltatásokat (mint például telnet, www, levelezés stb.) a hozzájuk tartozó protokol és szabványos (fogadó) portszám írja le. Ezekre a forrásról általában valamilyen nem szabványos (magasabb értékű) portról érkeznek csomagok. Ekkor a kommunikáció összes paramétere (vagyis a portok és címek) bármelyike alapján definiálhatunk blokkolást vagy továbbengedést leíró szabályokat.

Az IPF eredetileg úgy íródott, hogy a szabályokat “az utolsó illeszkedő szabály nyer” stílusban dolgozza fel és csak állapot nélküli szabályokat ismert. Az idők folyamán az IPF szabályai kiegészültek a “quick” és az állapottartásra vonatkozó “keep state” opciókkal, amelynek köszönhetően óriási mértékben korszerűsödött a szabályok feldolgozása.

A szakaszban szereplő utasítások olyan szabályokat alkalmaznak, amelyekben egyaránt szerepel a “quick” és az állapottartásért felelős “keep state” beállítás. Ez az inkluzív tűzfalak létrehozásának egyik alapeszköze.

> Figyelem: A tűzfal szabályainak összeállítása során nagyon óvatosnak kell lennünk! Bizonyos beállítások hatására akár ki is zárhatjuk magunkat a szerverünkről. Az ebből fakadó esetleges kellemetlenségek elkerülése érdekében javasoljuk, hogy a tűzfal alapjait először helyi konzolról építsük fel, ne pedig távolról, például ssh segítségével.

## 30.5.11. A szabályok felépítése

A szabályok felépítésének bemutatását itt most leszűkítjük a modern állapottartó szabályokra és az “első illeszkedő szabály nyer” típusú feldolgozásra. A szabályok felírásának régebbi módjai az ipf(8) man oldalon találhatóak.

A `#` karakterrel egy megjegyzés kezdetét jelezzük, és általában a sor végén vagy egy külön sorban bukkan fel. Az üres sorokat a rendszer nem veszi figyelembe.

A szabályok kulcsszavakat tartalmaznak. Ezeknek a kulcsszavaknak balról jobbra haladva adott sorrendben kell szerepelniük. A kulcsszavakat kiemeltük. Egyes kulcsszavakhoz további beállítások is tartozhatnak, amelyek maguk is kulcsszavak lehetnek, és még további opciókkal rendelkezhetnek. Az alábbi nyelvtan mindegyik elemét kiemeltük és az alábbiakban egyenként kifejtjük a részleteiket.

`CSELEKVÉS BE-KI OPCIÓK SZŰRÉS ÁLLAPOTTARTÓ PROTOKOLL FORRÁS_CÍM,CÉL_CÍM OBJEKTUM PORTSZÁM TCP_BEÁLLÍTÁS ÁLLAPOTTARTÓ`

`CSELEKVÉS` = block | pass

`BE-KI` = in | out

`OPCIÓK` = log | quick | on `interfész`

`SZŰRÉS` = proto `érték` | `forrás/cél IP` | port = `szám` | flags `beállítás`

`PROTOKOLL` = tcp/udp | udp | tcp | icmp

`FORRÁS_CÍM,CÉL_CÍM` = all | from `objektum` to `objektum`

`OBJEKTUM` = `IP-cím` | any

`PORTSZÁM` = `portszám`

`TCP_BEÁLLÍTÁS` = S

`ÁLLAPOTTARTÓ` = keep state

### 30.5.11.1. CSELEKVÉS

A cselekvés határozza meg, hogy mit kell tenni azokkal a csomagokkal, amelyek illeszkednek a szabály többi részére. Minden szabályhoz tartoznia kell egy cselekvésnek. A következő cselekvések közül választhatunk:

A `block` megadásával a szabályban szereplő szűrési feltételre illeszkedő csomagot eldobjuk.

A `pass` megadásával a szabályban szereplő szűrési feltételre illeszkedő csomagot átengedjük a tűzfalon.

### 30.5.11.2. BE-KI

Az összes szűrési szabály esetében kötelező egyértelműen nyilatkozunk arról, hogy a bemenő vagy a kimenő forgalomra vonatkozik. Ezért a következő kulcsszó vagy az `in` vagy pedig az `out`, de közülük egyszerre csak az egyiket szabad használni, máskülönben a szabály hibásnak minősül.

Az `in` jelenti, hogy a szabályt az internet felől az adott interfészen beérkező csomagokra kell alkalmazni.

Az `out` jelenti, hogy a szabályt az internet felé az adott interfészen kiküldött csomagokra kell alkalmazni.

### 30.5.11.3. OPCIÓK

> Megjegyzés: Ezek az opciók csak a lentebb bemutatott sorrendben használhatók.

A `log` jelzi, hogy illeszkedés esetén a csomag fejlécét az `ipl` eszközön keresztül naplózni kell (lásd a naplózásról szóló szakaszt).

A `quick`jelzi, hogy illeszkedés esetén ez lesz a legutolsónak ellenőrzött szabály és így egy olyan “rövidzárat” tudunk képezni a feldolgozásban, amellyel elkerüljük a csomagra egyébként vonatkozó többi szabály illesztését. Ez az opció a korszerűsített szabályfeldolgozás kihasználásához elengedhetetlen.

Az `on` használatával a szűrés feltételei közé bevonhatjuk a csomaghoz tartozó hálózati interfészt. Itt az interfészek az ifconfig(8) által megjelenített formában adhatóak meg. Az opció megadásával csak az adott interfészen az adott irányba (befelé/kifelé) közlekedő csomagokra fog illeszkedni a szabály. Ez az opció a korszerűsített szabályfeldolgozás kihasználásához nélkülözhetetlen.

Amikor naplózunk egy csomagot, akkor a hozzátartozó fejléc az IPL csomagnaplózó pszeudo eszközhöz kerül. A `log` kulcsszó után közvetlenül a következő minősítők szerepelhetnek (a következő sorrendben):

A `body` jelzi, hogy a csomag tartalmának első 128 byte-ját még jegyezzük fel a fejléc mellé.

A `first` minősítőt akkor érdemes használnunk, amikor a `log` kulcsszót a `keep state` opcióval együtt alkalmazzuk, mivel ilyenkor csak a szabályt kialakító csomag kerül naplózásra és nem minden olyan, ami illeszkedik az állapottartási feltételekre.

### 30.5.11.4. SZŰRÉS

Ebben a szakaszban olyan kulcsszavak jelenhetnek meg, amelyekkel a csomagok különféle tulajdonságai alapján ítélkezhetünk azok illeszkedéséről. Itt adott egy kiinduló kulcsszó, amelyhez további kulcsszavak is tartoznak, és amelyek közül csak egyet választhatunk. Az alábbi általános tulajdonságok alapján tudjuk szűrni a csomagokat, ebben a sorrendben:

### 30.5.11.5. PROTOKOLL

A `proto` egy olyan kulcsszó, amelyhez hozzá kell rendelnünk még valamelyik opcióját is. Ez az opció segít az adott protokolloknak megfelelően válogatni a csomagok között. A korszerűsített szabályfeldolgozás lehetőségeinek kihasználásához nélkülözhetetlen.

Opcióként a `tcp/udp | udp | tcp | icmp`, vagy bármelyik, az `/etc/protocols` állományban megtalálható kulcsszó felhasználható. A `tcp/udp` ebből a szempontból speciálisnak tekinthető, mivel hatására egyszerre illeszthetőek a szabályra a TCP és UDP csomagok, és így a protokolltól eltekintve azonos szabályok felesleges többszörözését kerülhetjük el.

### 30.5.11.6. FORRÁS_CÍM/CÉL_CÍM

Az `all` kulcsszó gyakorlatilag a “from any to any” (“bárhonnan bárhova”) szinonímája és nem tartozik hozzá paraméter.

A `from `forrás` to `cél`` felépítése: a `from` és `to` kulcsszavak az IP-címek illesztésére használhatóak. Ilyenkor a szabályokban a forrás és a cél paramétereknek is szerepelniük kell. Az `any` egy olyan speciális kulcsszó, amely tetszőleges IP-címre illeszkedik. Néhány példa az alkalmazására: `from any to any` vagy `from 0.0.0.0/0 to any`, `from any to 0.0.0.0/0`, `from 0.0.0.0/0 to any` vagy `from any to 0.0.0.0`.

Az IP-címek megadhatóak pontozott numerikus formában a hálózati maszk bitekben mért hosszával együtt, vagy akár egyetlen pontozott numerikus IP-címként.

Nincs lehetőség olyan IP-címtartományok illesztésére, amelyek nem adhatóak meg kényelmesen ponttal elválasztott számok és maszk hosszával. A `net-mgmt/ipcalc` port az ilyen számításokat könnyíti meg. A hálózati maszkok hosszának megállapításban segíthet az említett segédprogram (angol nyelvű) honlapja: http://jodies.de/ipcalc.

### 30.5.11.7. PORT

Amikor portra vonatkozó illeszkedést írunk elő, megadhatjuk a forrásra és célra, amit aztán vagy csak TCP vagy pedig csak UDP csomagokra alkalmazunk. A portok feltételeinek megfogalmazásánál használhatjuk a portok számát vagy az `/etc/services` állományban szereplő nevüket. Amikor a port egy `from` típusú objektum leírásában jelenik meg, akkor automatikusan a forrásportot jelenti, míg a `to` objektum leírásában pedig a célportot. A `to` objektumoknál a port megadása elengedhetetlen a korszerűsített szabályfeldolgozás előnyeinek kihasználásához. Példa: `from any to any port = 80`.

Az egyes portokat különböző műveletek segítségével, numerikusan hasonlíthatjuk össze, ahol akár porttartományt is megadhatunk.

port "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" | "le" | "ge".

A porttartományok megadásához használjuk a `port` "<>" | "><" felírási módot.

> Figyelem: A forrásra és célra vonatkozó paraméterek után szereplő másik két paraméter nélkülözhetetlen a korszerűsített szabályfeldolgozás működéséhez.

### 30.5.11.8. TCP_BEÁLLÍTÁS

A beállítások csak a TCP forgalom szűrésénél érvényesülnek. A betűk jelölik azokat a lehetséges beállításokat, amelyek a TCP csomagok fejlécében megvizsgálhatóak.

A korszerűsített szabályfeldolgozás a `flags S` paraméter segítségével ismeri fel a TCP munkameneteket kezdeményező kéréseket.

### 30.5.11.9. ÁLLAPOTTARTÓ

A `keep state` jelzi, hogy a szabály paramétereinek megfelelő bármely csomag aktiválja az állapottartó szűrés használatát.

> Megjegyzés: Ez a beállítás feltétlenül szükséges a korszerűsített szabályfeldolgozás megfelelő kihasználásához.

## 30.5.12. Állapottartó csomagszűrés

Az állapottartó szűrés a csomagok kétirányú áramlását egy létrejött kapcsolatba sorolja be. Amikor aktiválódik, az állapottartó szabály előre dinamikusan létrehozza a kétirányú kommunikációban megforduló csomagokhoz a megfelelő belső szabályokat. Olyan vizsgálatokat végez, amelyek segítségével ki tudja deríteni, hogy a csomag küldője és címzettje között fennálló kétirányú kapcsolat érvényes szabályok szerint zajlik-e. Minden olyan csomagot, amely nem illeszkedik megfelelően a kapcsolatra vonatkozó sémára, csalásnak tekintjük és automatikusan eldobjuk.

Az állapottartás révén lehetőségünk van a TCP vagy UDP kapcsolatokhoz tartozó ICMP csomagokat is átengedni a tűzfalon. Tehát ha kapunk egy 3-as típusú, 4-es kódú ICMP választ valamilyen böngészésre használt állapottartó szabályon keresztül kiküldött kérésre, akkor az automatikusan bejöhet. Amelyik csomagot az IPF egyértelműen képes besorolni az aktív kapcsolatba, még ha az eltérő protokollt is használ, beengedi.

Ami ilyenkor történik:

Az internethez csatlakozó interfészen keresztül kifelé haladó csomagokat először egy dinamikus állapottábla alapján illesztjük, és ha a csomag illeszkedik az aktív kapcsolatban következőként várt csomagra, akkor átmegy a tűzfalon és a dinamikus állapottáblában frissül a kapcsolat állapota. Az aktív munkameneten kívül csomagok pedig egyszerűen a kimenő szabályrendszer szerint kerülnek ellenőrzésre.

Hasonlóan az előzőhöz, az internethez csatlakozó interfészen keresztül befelé haladó csomagokat először egy dinamikus állapottábla alapján illesztjük, és ha a csomag illeszkedik az aktív kapcsolatban következőként várt csomagra, akkor átmegy a tűzfalon és a dinamikus állapottáblában frissül a kapcsolat állapota. Az aktív munkamenethez nem tartozó csomagok pedig egyszerűen a bejövő szabályrendszer szerint kerülnek ellenőrzésre.

Amikor egy kapcsolat befejeződik, automatikusan törlődik a dinamikus állapottáblából.

Az állapottartó csomagszűrés használatával az újonnan keletkező kapcsolatok elutasítására vagy engedélyezésére tudunk koncentrálni. Ha engedélyeztük egy új kapcsolat létrejöttét, akkor a rákövetkező összes többi csomag automatikusan átmegy a tűzfalon és minden más hamis csomag eldobódik. Ha tiltjuk az új kapcsolatot, akkor egyetlen rákövetkező csomag sem juthat át. Az állapottartó szűrés által felkínált fejlett elemzési lehetőségek képesek védelmet nyújtani a behatolók részéről alkalmazott megannyi különböző támadási módszer ellen.

## 30.5.13. Példa inkluzív szabályrendszerre

A most következő szabályrendszer arra mutat példát, hogyan programozzunk le egy nagyon biztonságos inkluzív tűzfalat. Az inkluzív tűzfalak csak a szabályainak megfelelő szolgáltatásokat engedik keresztül, és alapértelmezés szerint minden mást blokkolnak. Egy hálózat gépeit védő tűzfalnak, amelyet gyakran “hálózati tűzfalnak” (network firewall) is neveznek, legalább két hálózati interfésszel kell rendelkeznie. Ezeket az interfészeket általában úgy állítják be, hogy tökéletesen megbíznak az egyik oldalban (a helyi hálózatban), a másikban (az internetben) pedig egyáltalán nem. A tűzfalat egyébként úgy is beállíthatjuk, hogy csak a tűzfalat működtető gépet védje -- ezt “egyrendszeres tűzfalnak” (host based firewall) nevezik. Az ilyen típusú megoldásokat nem biztonságos hálózaton keresztül kommunikáló szervereknél alkalmaznak.

Mindegyik UNIX®-típusú rendszert, köztük a FreeBSD-t is úgy alakították ki, hogy az operációs rendszeren belüli kommunikáció az `lo0` interfészen és a `127.0.0.1` IP-címen keresztül történik. A tűzfal szabályai között feltétlenül szerepelniük kell olyanoknak, amelyek lehetővé teszik ezen a speciális intefészen a csomagok zavartalan mozgását.

Az internetre csatlakozó interfészhez kell rendelni a kifelé és befelé haladó forgalom hitelesítését é a hozzáférésének vezérlését. Ez lehet a felhasználói PPP által létrehozott `tun0` interfész vagy a DSL-, illetve kábelmodemhez csatlakozó hálózati kártya.

Ahol egy vagy több hálózati kártya is csatlakozik több különböző helyi hálózathoz, úgy kell beállítani a hozzájuk tartozó interfészeket, hogy egymás felé és az internet felé képesek legyenek küldeni és fogadni.

A szabályokat először három nagy csoportba kell szerveznünk: először jönnek a megbízható interfészek, ezeket követik az internet felé mutató interfészek, végül internet felől jövő, nem megbízható interfészeke.

Az egyes csoportokban szereplő szabályokat úgy kell megadni, hogy közülük előre kerüljenek a leggyakrabban alkalmazottak, és a csoport utolsó szabálya blokkoljon és naplózzon minden csomagot az adott interfészen és irányban.

A kimenő forgalomat vezérlő szabályrendszer csak `pass` (tehát átengedő) szabályokat tartalmazhat, amelyek bentről az interneten elérhető szolgáltatásokat azonosítják egyértelműen. Az összes ilyen szabályban meg kell jelenni a `quick`, `on`, `proto`, `port` és `keep state` beállításoknak. A `proto tcp` szabályok esetében meg kell adni a `flag` opciót is, amivel fel tudjuk ismertetni a kapcsolatok keletkezését és ezen keresztül aktiválni az állapottartást.

A bejövő forgalmat vezérlő szabályrendszerben először az eldobni kívánt csomagokat kell megadni, aminek két eltérő oka van. Először is előfordulhat, hogy a veszélyes csomagok részleges illeszkedés miatt szabályosnak tűnnek. Az ilyen csomagokat értelemszerűen nem lenne szabad beengedni a szabályok részleges megfelelése alapján. A másodszor az eleve ismerten problémás és értelmetlen csomagokat csendben el kellene vetni, mielőtt a szakaszhoz tartozó utolsó szabály fogná meg és naplózná. Ez az utolsó szabály egyébként szükség esetén felhasználható a támadók elleni bizonyítékok begyűjtésére.

A másik, amire még oda kell figyelnünk, hogy a blokkolt csomagok esetében semmilyen válasz nem keletkezzen, egyszerűen csak tűnjenek el. Így a támadó nem fogja tudni, hogy a csomagjai vajon elérték-e a rendszerünket. Minél kevesebb információt tudnak összegyűjteni a rendszerünkről a támadók, annál több időt kell szánniuk csínytevéseik kieszelésére. A `log first` opciót tartalmazó szabályok csak az illeszkedésnél fogják naplózni a hozzájuk tartozó eseményt. Erre láthatunk példát az `nmap OS fingerprint` szabálynál. Az `security/nmap` segédprogramot a támadók gyakran alkalmazzák a megtámadni kívánt szerver operációs rendszerének felderítésére.

Minden `log first` opcióval megadott szabály illeszkedésénél a `ipfstat -hio` parancs meghatározódik az eddigi illeszkedések aktuális száma. Nagyobb értékek esetében következtethetünk arra, hogy a rendszerünket megtámadták (vagyis csomagokkal árasztják éppen el).

Az ismeretlen portszámok felderítésére az `/etc/services` állomány, esetleg a http://www.securitystats.com/tools/portsearch.php (angol nyelvű) honlap használható.

Érdemes továbbá megnézni a trójai programok által használt portokat a http://www.simovits.com/trojans/trojans.html címen (angolul).

A következő szabályrendszer egy olyan biztonságos “inkluzív” típusú tűzfal, amelyet éles rendszeren is használnak. Ezt a rendszerünkön nem használt szolgáltatásokra vonatkozó `pass` szabályok törlésével könnyedén a saját igényeink szerint alakíthatjuk.

Ha nem akarunk látni bizonyos üzeneteket, akkor vegyünk fel hozzájuk egy `block` típusú szabályt a befelé irányuló forgalomhoz tartozó szabályok közé.

A szabályokban írjuk át a `dc0` interfész nevét annak a hálózati kártyának az interfészére, amelyen keresztül csatlakozunk az internethez. A felhasználói PPP esetében ez a `tun0` lesz.

Tehát a következőket kell beírni az `/etc/ipf.rules` állományba:

    #################################################################
    # A helyi hálózatunkon zajló forgalmat ne korlátozzuk.
    # Csak akkor kell, ha helyi hálózathoz is csatlakozunk.
    #################################################################

    #pass out quick on xl0 all
    #pass in quick on xl0 all

    #################################################################
    # A belső interfészen szintén ne korlátozzunk semmit.
    #################################################################
    pass in quick on lo0 all
    pass out quick on lo0 all

    #################################################################
    # Az internet felé forgalmazó interfész (kimenő kapcsolatok)
    # A saját hálózatunkról belülről vagy erről az átjáróról
    # kezdeményezett kapcsolatokat vizsgáljuk az internet felé.
    #################################################################

    # Engedélyezzük az internet szolgáltatók névszerverének elérését,
    # az "xxx" helyett a névszervet IP-címét kell megadni.
    # Másoljuk le ezeket a sorokat, ha a szolgáltatónknak több
    # névszerverét is beakarjuk állítani. A címeiket az /etc/resolv.conf
    # állományban találjuk.
    pass out quick on dc0 proto tcp from any to xxx port = 53 flags S keep state
    pass out quick on dc0 proto udp from any to xxx port = 53 keep state

    # DSL vagy kábeles hálózatoknál engedélyezzük a
    # szolgáltatónk DHCP szerverének elérését.
    # Ez a szabály nem kell, ha "felhasználói PPP"-vel
    # kapcsolódunk az internethez, ilyenkor tehát az egész
    # csoport törölhető.
    # Használjuk az alábbi szabályt és keressük meg a naplóban az
    # IP-címet. Ha megtaláltuk, akkor tegyük bele a megjegyzésben
    # szereplő szabályba és töröljük az első szabályt.
    pass out log quick on dc0 proto udp from any to any port = 67 keep state
    #pass out quick on dc0 proto udp from any to z.z.z.z port = 67 keep state

    # Kifelé engedélyezzük a szabványos nem biztonságos WWW funkciókat.
    pass out quick on dc0 proto tcp from any to any port = 80 flags S keep state

    # Kifelé engedélyezzük a biztonságos WWW funkciókat TLS SSL
    # protokollal.
    pass out quick on dc0 proto tcp from any to any port = 443 flags S keep state

    # Kifelé engedélyezzük az e-mailek küldését és fogadását.
    pass out quick on dc0 proto tcp from any to any port = 110 flags S keep state
    pass out quick on dc0 proto tcp from any to any port = 25 flags S keep state

    # Kifelé engedélyezzük az idő szolgáltatást.
    pass out quick on dc0 proto tcp from any to any port = 37 flags S keep state

    # Kifelé engedélyezzük az nntp híreket.
    pass out quick on dc0 proto tcp from any to any port = 119 flags S keep state

    # Kifelé engedélyezzük az átjáróról és a helyi hálózatról a nem
    # biztonságos FTP használatát (passzív és akív módokban is). Ez a
    # funkció a működéséhez a nat szabályokat tartalmazó állományban
    # hivatkozott FTP proxyt használja. Amennyiben a pkg_add paranccsal
    # csomagokat akarunk telepíteni az átjáróra, erre a szabályra
    # mindenképpen szükségünk lesz.
    pass out quick on dc0 proto tcp from any to any port = 21 flags S keep state

    # Kifelé engedélyezzük az ssh/sftp/scp # (biztonságos telnet/rlogin/FTP)
    # szolgáltatások # elérését az SSH (secure shell) használatával.
    pass out quick on dc0 proto tcp from any to any port = 22 flags S keep state

    # Kifelé engedélyezzük a nem biztonságos telnet elérését.
    pass out quick on dc0 proto tcp from any to any port = 23 flags S keep state

    # Kifelé engedélyezzük FreeBSD CVSUp funkcióját.
    pass out quick on dc0 proto tcp from any to any port = 5999 flags S keep state

    # Kifelé engedélyezzük a pinget.
    pass out quick on dc0 proto icmp from any to any icmp-type 8 keep state

    # Kifelé engedélyezzük a helyi hálózatról érkező whois kéréseket.
    pass out quick on dc0 proto tcp from any to any port = 43 flags S keep state

    # Minden mást eldobunk és naplózzuk az első előfordulásukat.
    # Ez a szabály blokkol alapértelmezés szerint mindent.
    block out log first quick on dc0 all

    #################################################################
    # Az internet felőli interfész (bejövő kapcsolatok)
    # A saját hálózatunk felé vagy erre az átjáróra
    # nyitott kapcsolatokat vizsgáljuk az internet felől.
    #################################################################

    # Eldobjuk az összes olyan bejövő forgalmat, amit hivatalosan nem
    # lehetne továbbítani vagy fenntartott címterülethez tartozik.
    block in quick on dc0 from 192.168.0.0/16 to any    #RFC 1918: privát IP
    block in quick on dc0 from 172.16.0.0/12 to any     #RFC 1918: privát IP
    block in quick on dc0 from 10.0.0.0/8 to any        #RFC 1918: privát IP
    block in quick on dc0 from 127.0.0.0/8 to any       #helyi
    block in quick on dc0 from 0.0.0.0/8 to any         #helyi
    block in quick on dc0 from 169.254.0.0/16 to any    #DHCP
    block in quick on dc0 from 192.0.2.0/24 to any      #dokumentációs célokra fenntartva
    block in quick on dc0 from 204.152.64.0/23 to any   #Sun klaszterek összekötésére használt
    block in quick on dc0 from 224.0.0.0/3 to any       #D és E osztályú multicast

    ##### Itt eldobunk egy rakás csúf dolgot ############
    # Ezeket nem akarjuk a naplóban látni:

    # Eldobjuk a töredékcsomagokat.
    block in quick on dc0 all with frags

    # Eldobjuk a túlságosan rövid TCP csomagokat.
    block in quick on dc0 proto tcp all with short

    # Eldobjuk a forrás által közvetített (source routed) csomagokat.
    block in quick on dc0 all with opt lsrr
    block in quick on dc0 all with opt ssrr

    # Elutasítjuk az "OS fingerprint" kéréseket.
    # Naplózzuk az első előfordulást, így nálunk lesz a kíváncsiskodó
    # egyén IP-címe.
    block in log first quick on dc0 proto tcp from any to any flags FUP

    # Eldobunk mindent, aminek speciális beállításai vannak.
    block in quick on dc0 all with ipopts

    # Elutasítjuk a publikus pinget.
    block in quick on dc0 proto icmp all icmp-type 8

    # Elutasítjuk az ident kéréseket.
    block in quick on dc0 proto tcp from any to any port = 113

    # Blokkoljuk az összes Netbios szolgáltatást: 137=név, 138=datagram,
    # 139=session. A Netbios az MS Windows megosztását implementálja.
    # Blokkoljuk az MS Windows hosts2 névszerver kéréseit is a 81-es
    # porton.
    block in log first quick on dc0 proto tcp/udp from any to any port = 137
    block in log first quick on dc0 proto tcp/udp from any to any port = 138
    block in log first quick on dc0 proto tcp/udp from any to any port = 139
    block in log first quick on dc0 proto tcp/udp from any to any port = 81

    # Engedélyezzük a szolgáltatónk DHCP szerverétől érkező forgalmat.
    # Ebben a szabályban meg kell adnunk a szolgáltató DHCP szerverének
    # IP-címét, mivel itt csak a hiteles forrásból fogadunk el csomagokat.
    # Erre csak DSL- és kábelmodemes kapcsolat esetében van szükség, a
    # "felhasználói PPP" alkalmazása során szükségtelen. Ez az IP-cím
    # megegyezik a kimenő kapcsolatoknál megadott címmel.
    pass in quick on dc0 proto udp from z.z.z.z to any port = 68 keep state

    # Befelé engedélyezzük a szabványos WWW funkciót, mivel webszerverünk
    # van.
    pass in quick on dc0 proto tcp from any to any port = 80 flags S keep state

    # Befelé engedélyezzük az internetről érkező nem biztonságos telnet
    # kapcsolatokat. Azért nem biztonságos, mert az azonosítókat és
    # jelszavakat titkosítatlan formában közli az interneten keresztül.
    # Töröljük ezt a szabályt, ha nem használunk telnet szervert.
    #pass in quick on dc0 proto tcp from any to any port = 23 flags S keep state

    # Befelé engedélyezzük az internetről # érkező ssh/sftp/scp (biztonságos
    # telnet/rlogin/FTP) # kapcsolatokat az SSH (secure shell) használatával.
    pass in quick on dc0 proto tcp from any to any port = 22 flags S keep state

    # Minden mást dobjuk el és naplózzuk az első előfordulásukat.
    # Az első alkalom naplózásával elejét tudjuk venni a "Denial of
    # Service" típusú támadásoknak, amivel egyébként lehetséges lenne a
    # napló elárasztása.
    # Ez a szabály blokkol alapértelmezés szerint mindent.
    block in log first quick on dc0 all
    ################### Itt van a szabályok vége ##############################

## 30.5.14. NAT

A NAT jelentése Network Address Translation, vagyis hálózati címfordítás. A Linux® esetében ezt “IP masqueradingnak”, vagyis IP maszkolásnak hívják. A hálózati címfordítás és az IP maszkolás lényegben ugyanazt takarja. Az IPF címfordításért felelős funkciójának köszönhetően képesek vagyunk a tűzfal mögött elhelyezkedő helyi hálózat számára megosztani az internet-szolgáltatól kapott publikus IP-címet.

Sokakban felmerülhet a kérdés, hogy erre vajon mi szükségünk lehet. Az internet-szolgáltatók a magánszemélyeknek általában dinamikus IP-címeket osztanak ki. A dinamikus itt arra utal, hogy a címünk minden alkalommal változik, amikor betárcsázunk a szolgáltatóhoz vagy amikor ki- és bekapcsoljuk a modemünket. Ez a dinamikus IP-cím fog azonosítani minket az interneten.

Most tegyük fel, hogy öt gépünk van otthon, viszont csak egyetlen előfizetéssel rendelkezünk. Ebben az esetben öt telefonvonalat kellene használnunk és mindegyik géphez előfizetni az internetre.

A hálózati címfordítás alkalmazásával azonban mindössze egyetlen előfizetés kell. A gépek közül négyet hozzákötünk egy switch-hez és a switch-et pedig a fennmaradó géphez, amelyen FreeBSD fut. Ez utóbbi lesz az így kialakított helyi hálózatunk átjárója. A tűzfalban működő címfordítás segítségével a helyi hálózaton található gépek IP-címeit észrevétlenül át tudjuk fordítani a hálózatunk publikus IP-címére, ahogy a csomagok elhagyják az átjárót. A beérkező csomagok esetében mindez visszafelé történik meg.

Az IP-címek közül adott egy tartomány, amit a címfordítást használó helyi hálózatok részére tartanak fenn. Az RFC 1918 szerint az alábbi IP-címtartományok használhatók a helyi hálózatban, mivel ezeken keresztül közvetlenül sosem lehet kijutni az internetre:

Kezdő IP: `10.0.0.0` | - | Záró IP: `10.255.255.255`
Kezdő IP: `172.16.0.0` | - | Záró IP: `172.31.255.255`
Kezdő IP: `192.168.0.0` | - | Záró IP: `192.168.255.255`

## 30.5.15. IPNAT

A címfordításra vonatkozó szabályokat az `ipnat` paranccsal tudjuk betölteni. Az ilyen típusú szabályokat általában az `/etc/ipnat.rules` állományban találjuk. A részleteket lásd az ipnat(1) man oldalán.

Amikor a címfordítás üzembe helyezése után meg akarjuk változtatni a címfordítás szabályait, először a címfordítás szabályait tartalmazó állományt módosítsuk, majd a belső címfordítási szabályok és a címfordítási táblázatban szereplő aktív bejegyzések törléséhez futassuk le az `ipnat` parancsot a `-CF` beállítással.

A címfordítási szabályok újratöltését egy ehhez hasonló paranccsal tudjuk elvégezni:

    # ipnat -CF -f /etc/ipnat.szabályok

A címfordításhoz tartozó statisztikákat ezzel a paranccsal tudjuk lekérdezni:

    # ipnat -s

A címfordítási táblázatban pillanatnyilag szereplő összerendeléseket a következő paranccsal tudjuk listázni:

    # ipnat -l

A szabályok feldolgozásával és az aktív szabályokkal/bejegyzésekkel kapcsolatos információk részletezését így engedélyezhetjük:

    # ipnat -v

## 30.5.16. A címfordítási szabályok

A címfordítási szabályok nagyon rugalmasak és rengeteg olyan funkciót meg tudunk velük valósítani, ami az üzleti és otthoni felhasználók számára egyaránt hasznos.

Itt most a szabályok felépítését csak egyszerűsítve mutatjuk be, leginkább a nem üzleti környezetek tekintetében. A szabályok komplett formai leírását az ipnat(5) man oldalán találjuk.

Egy címfordítási szabály tehát valahogy így néz ki:

    map INTERFÉSZ HELYI_IP_TARTOMÁNY -> PUBLIKUS_CÍM

A szabályt a `map` kulcsszó kezdi.

A `INTERFÉSZ` helyére az internet felé mutató külső interfész nevét írjuk be.

A `HELYI_IP_TARTOMÁNY` lesz az, amelyben a kliensek címeznek. Ez például a `192.168.1.0/24`.

A `PUBLIKUS_CÍM` lehet egy külső IP-cím vagy a `0/32` speciális kulcsszó, amellyel a `FELÜLET`-hez rendelt IP-címre hivatkozunk.

## 30.5.17. Hogyan működik a hálózati címfordítás

A publikus cél felé haladó csomag megérkezik a helyi hálózatról. Miután a kimenő kapcsolatokra vonatkozó szabályok átengedik, a címfordítás kapja meg a szerepet és fentről lefelé haladva nekilát alkalmazni a saját szabályait, ahol az első egyező szerint cselekszik. A címfordítás a szabályokat a csomaghoz tartozó interfészre és a forrás IP-címére illeszti. Amikor a csomag interfészének neve illeszkedik egy címfordítási szabályra, akkor ezután a csomag forrás (vagyis a helyi hálózaton belüli) IP-címéről igyekszik eldönteni, hogy a szabály nyilának bal oldalán szereplő tartományba esik-e. Ha erre is illeszkedik, akkor a forrás IP-címét átírjuk a `0/32` kulcsszó alapján felderített publikus IP-címre. A címfordító rutin ezt feljegyzi a saját belső táblázatába, így amikor a csomag visszatér az internetről, akkor képes lesz visszafordítani az eredeti belső IP-címére és feldolgozásra átadni a tűzfal szabályainak.

## 30.5.18. A címfordítás engedélyezése

A címfordítás életre keltéséhez a következőket kell beállítanunk az `/etc/rc.conf` állományban.

Először engedélyezzük a gépünknek, hogy közvetítsen forgalmat az interfészek között:

    gateway_enable="YES"

Minden alkalommal indítsuk el a címfordításért felelős IPNAT programot:

    ipnat_enable="YES"

Adjuk meg az IPNAT számára a betöltendő szabályokat:

    ipnat_rules="/etc/ipnat.rules"

## 30.5.19. Hálózati címfordítás nagyon nagy helyi hálózatok esetében

Az olyan helyi hálózatokban, ahol rengeteg PC található vagy több alhálózatot is tartalmaz, az összes privát IP-cím egyetlen publikus IP-címbe tömörítése igen komoly problémává tud dagadni és az azonos portok gyakori használata a helyi hálózatra kötött számítógépek között ütközéseket okoz. Két módon tudunk megoldást nyújtani erre a problémára.

### 30.5.19.1. A használható portok kiosztása

Egy normális címfordítási szabály valahogy így nézne ki:

    map dc0 192.168.1.0/24 -> 0/32

A fenti szabályban a csomag forrásportját az IPNAT változatlanul a feldolgozás után hagyja. Ha ehhez még hozzátesszük a `portmap` kulcsszót, akkor ezzel utasítani tudjuk az IPNAT-ot, hogy csak az adott tartományban képezze le a forrásportokat. Például a következő szabály hatására az IPNAT a forrásportokat egy adott tartományon belül fogja módosítani:

    map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:60000

Ha viszont még inkább meg akarjuk könnyíteni a dolgunkat, akkor itt egyszerűen csak adjuk meg az `auto` kulcsszót, amellyel az IPNAT önmagától megállapítja, hogy milyen portokat tud használni:

    map dc0 192.168.1.0/24 -> 0/32 portmap tcp/udp auto

### 30.5.19.2. Több publikus cím használata

Minden nagyobb helyi hálózat esetében elérkezünk ahhoz a ponthoz, ahol már egyetlen publikus cím nem elég. Ha több publikus IP-címmel is rendelkezünk, akkor ezekből a címekből egy “közös készletet” hozhatunk létre, amiből majd az IPNAT válogathat miközben a csomagok címeit átírja kifelé menetben.

Például ahelyett, hogy a csomagokat egyetlen publikus IP-címre képeznénk le, ahogy itt tesszük:

    map dc0 192.168.1.0/24 -> 204.134.75.1

A hálózati maszk segítségével meg tudjuk adni IP-címek egy tartományát is:

    map dc0 192.168.1.0/24 -> 204.134.75.0/255.255.255.0

CIDR-jelöléssel:

    map dc0 192.168.1.0/24 -> 204.134.75.0/24

## 30.5.20. A portok átirányítása

Gyakran előfordul, hogy van webszerverünk, levelező szerverünk, adatbázis szerverünk és névszerverünk, melyek a helyi hálózat különböző gépein futnak. Ebben az esetben a szerverekhez tartozó forgalmat is fordítanunk kell, illetve valamilyen módon a bejövő forgalmat is át kell irányítanunk a helyi hálózat megfelelő gépeihez. Az IPNAT ezt a gondot a hálózati címfordítás átirányítást támogató funkcióival szünteti meg. Tegyük fel, hogy a `10.0.10.25` belső címen van egy webszerverünk, amelyhez a `20.20.20.5` publikus IP tartozik. Ilyenkor a következő szabályt adjuk meg:

    rdr dc0 20.20.20.5/32 port 80 -> 10.0.10.25 port 80

vagy:

    rdr dc0 0.0.0.0/0 port 80 -> 10.0.10.25 port 80

Így tudjuk beállítani a `10.0.10.33` címmel rendelkező névszervert a kintről érkező névfeloldási kérések fogadására:

    rdr dc0 20.20.20.5/32 port 53 -> 10.0.10.33 port 53 udp

## 30.5.21. Az FTP és a címfordítás

Az FTP egy olyan őskövület, amely még az internet egy régi korszakából maradt fenn, amikor az egyetemek között még bérelt vonal létezett és az FTP szolgált a kutatók közt az állományok megosztására. Ez még abban az időben történt, amikor a biztonság egyáltalán nem volt lényeges szempont. Az évek előrehaladtával az FTP protokoll beleivódott a feltörekvő internet gerincébe és a titkosítatlanul küldött azonosítóival és jelszavaival továbbra is ugyanolyan védtelen maradt. Az FTP két változatban, aktív és passzív módban képes működni. Az eltérés kettejük között az adatcsatorna megállapításában van. A passzív mód sokkal biztonságosabb, mivel ilyenkor az adatcsatornát az FTP kapcsolatot kezdeményező állítja be. Az FTP különböző módjainak magyarázatát és a köztük levő különbséget a http://www.slacksite.com/other/ftp.html címen ismerhetjük meg részleteiben (angolul).

### 30.5.21.1. Az IPNAT szabályai

Az IPNAT egy speciális beépített FTP proxyval rendelkezik, amelyre a hálózati címfordítás leképezései között hivatkozhatunk. Képes figyelni az összes aktív vagy passzív FTP kapcsolathoz tartozó kimenő kérést és ezekhez dinamikusan létrehozni olyan ideiglenes szűrési szabályokat, amelyek valóban csak az adatcsatornához felhasznált portokat tartalmazzák. Ezzel ki tudjuk küszöbölni az FTP azon káros hatását a tűzfalra nézve, hogy egyszerre túlságosan sok magasabb tartománybeli port legyen nyitva.

Ez a szabály a belső hálózat összes FTP forgalmát lekezeli:

    map dc0 10.0.10.0/29 -> 0/32 proxy port 21 ftp/tcp

Ez a szabály pedig az átjáróról érkező FTP forgalommal bírkózik meg:

    map dc0 0.0.0.0/0 -> 0/32 proxy port 21 ftp/tcp

Ez a szabály kezeli a belső hálózatról érkező összes nem FTP típusú forgalmat:

    map dc0 10.0.10.0/29 -> 0/32

Az FTP leképzésére vonatkozó szabály a szokásos leképzési szabály elé kerül. Az összes csomag fentről haladva az első illeszkedő szabály alapján kerül feldolgozásra. Először az interfész nevét vizsgáljuk, majd a belső hálózatbeli forrás IP-t, végül azt, hogy a csomag egy FTP kapcsolat része. Ha minden paraméterében megfelel, akkor az FTP proxy készít egy ideiglenes szűrési szabályt hozzá, amellyel az FTP kapcsolathoz tartozó csomagok mind a két irányba képesek lesznek vándorolni, természetesen a címfordítással együtt. Az összes többi bentről érkező csomag átlép ezen a szabályon és megáll a harmadiknál, ahol az interfésznek és forrás IP-nek megfelelően átfordítjuk a címét.

### 30.5.21.2. Az IPNAT szűrési szabályai FTP-re

Az FTP esetében csak egyetlen szűrési szabályra van szükségünk a hálózati címfordításba épített FTP proxy használatához.

FTP proxy nélkül az alábbi három szabály kellene:

    # Kifelé engedélyezzük a belső gépek FTP elérést az internet irányába,
    # aktív és passzív módokban.
    pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state

    # Kifelé engedélyezzük a passzív módhoz tartozó magasabb tartománybeli
    # adatcsatornákat.
    pass out quick on rl0 proto tcp from any to any port > 1024 flags S keep state

    # Aktív módban beengedjük az FTP szervertől érkező adatcsatornát.
    pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state

Előző | Tartalom | Következő
Az OpenBSD csomagszűrője (PF) és az ALTQ | Fel | IPFW

Ha kérdése van a FreeBSD-vel kapcsolatban, a következő címre írhat (angolul): <freebsd-questions@FreeBSD.org>.
Ha ezzel a dokumentummal kapcsolatban van kérdése, kérjük erre a címre írjon: <gabor@FreeBSD.org>.