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).
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.
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.
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
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.
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.
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.
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
alapértelmezés szerint a local0
“funkciót” használja. 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:
local0.* /var/log/ipfilter.log
A local0.* 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.
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:
A csomag megérkezésének dátuma
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
Azon interfész a neve, ahol a csomag feldolgozásra került, például dc0
A szabályhoz tartozó csoport és sorszám, például @0:17
Ezek az ipfstat -in paranccsal nézhetőek meg.
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.
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.
A PR után a protokoll neve vagy száma olvasható, például PR tcp.
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 ipf(5) 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.
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.
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.
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
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.
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.
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 quickjelzi, 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.
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:
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.
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.
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.
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.
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.
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.
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 ##############################
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:
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
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.
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.
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"
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.
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
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
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
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).
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.
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
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>.