Az OpenBSD pf-ről szóló első írásban a pf rövid történetét, alapjait, a csomagszűrést igyekeztem bemutatni. Említtem azonban már az elején is az ismertetőnek, hogy ennél jóval többre is képes a pf. Ha manapság tűzfalról beszélünk, akkor ha csak a home-kategórás routereket vesszük is alapul, biztosak lehetünk abban, hogy rendelkezik a hálózati címfordítás és a portátírányítás (Network Address Translation (NAT) és port forwarding) képességével. Nincs ez másképp a pf esetében sem. Nézzük meg, hogyan történik ez – pf módra.
OpenBSD tűzfal (pf) – II. rész – NAT és redirection
A jobb megértés kedvéért itt már muszáj volt rajzolnom egy nagyon szimpla topológiát.
PC
Helyi hálózati kapcsolat: IP: 10.0.0.2/24 Gateway: 10.0.0.1 DNS: 192.168.55.1
OpenBSD:
em0: 192.168.55.13/24
em1: 10.0.0.1/24
Gateway: 192.168.55.1
DNS: 192.168.55.1
Címfordítás (NAT):
Látjuk az ábrán, hogy a PC nevű host az OpenBSD-t tűzfalat használja gatewayként. Ahhoz, hogy ez a konfiguráció működő képes legyen, a pf konfigjában szükség lesz némi módosításra. Ha az alapkonfigurációt használjuk a pf-ben, akkor a PC nem fog tudni kommunikálni más hálózatokkal, nem fog „kilátni” az internetre sem. Ezt le is ellenőriztük a PC-ről:
Sem névfeloldásunk nincs (hiszen a DNS szerver is más hálózaton van a PC számára), sem IP-t pingelve nincs válaszunk. Azt viszont látjuk, hogy a gatewayunk pingelhető. Akkor a probléma oka nagy valószínűséggel ott keresendő (fogadjuk el, hogy PC munkaállomás hálózati konfigurációja helyes).
A célunk eléréséhez OpenBSD tűzfalon szükség lesz néhány változtatásra.
1., a kernel IP stackjének meg kell mondanunk, hogy engedélyezze az interfészek között a csomagtovábbítást
2., a pf konfigurációjában létre kell hoznunk egy NAT szabályt
Nézzük, mik lesznek ezek!
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (ezt csak akkor, ha IPv6-ot is használunk)
Ha azt szeretnénk, hogy ez rendszerindítás után automatikusan megtörténjen, akkor tegyük az alábbi sort az /etc/sysctl.conf fileba:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1 (csak ha IPv6-ot is használunk)
A pf konfigfájljába pedig az alábbi sort:
pass out on em0 from 10.0.0.0/24 to any nat-to 192.168.55.13
Mentsük el a konfigurációs fájlt, és töltsük újra a tűzfal konfigurációt!
# pfctl –Fa –f /etc/pf.conf
Ha ezt megtettük, akkor próbáljuk ki újra a PC nevű hostunkról, hogy tudunk-e az internettel kommunikálni!
A szükséges módosítások után elértük, amit szerettünk volna. Egy pár szó magyarázat talán szükséges lehet a pf-ben történt módosításhoz:
pass out on em0 from 10.0.0.0/24 to any nat-to 192.168.55.13
A fenti sor egy NAT, mégpedig egy úgynevezett source-NAT szabály. Arra utasítja a tűzfalunkat, hogy az összes csomagnak, mely az em0 interface-n hagyja el a tűzfalat és a 10.0.0.0/24-es hálózatból érkezik és a célja akármi, írja át az IP fejlécét, és forrás IP-ként a saját, em0 interface-ének az IP-jét írja bele (192.168.55.13). Természetesen, ahhoz, hogy a kommunikáció visszirányban is tudjon működni, a pf-nek egy állapottáblát kell fenntartani, amelyben a forrás-cél IP- és port hozzárendelések helyezkednek el.
Az www.index.hu folyamatos pingje esetén valami ilyesmit fogunk látni ebben az állapottáblában:
Jól látszik benne, hogy a kommunikáció a 192.168.55.13 és a 217.20.130.97 között zajlik, de a zárójelek között ott látjuk az eredeti forrás IP-t, ami a valós IP-je a PC nevű hostnak.
Port-forwarding (redirection):
Nézzük most egy példát még az átirányításokra is.
A teszt kedvéért én most az OpenBSD-re felhúztam egy abszolút alapkonfigurációs webszervert (Apache). Egy böngészőbe begépelve az OpenBSD em1 interface-nek az IP-jét, ezt fogjuk látni:
Nézzünk meg egy redirection-t a pf-fel. Ehhez a következő sort kell beszúrnunk a pf konfigurációs fájljába:
pass in on em1 proto tcp from 10.0.0.0/24 to any port 80 rdr-to 10.0.0.1 port 80
Nézzük, ha az előbbi példában szereplő NAT szabályunkat is felhasználjuk, mit látunk?
Ha bármilyen weboldalt próbálunk megnyitni, a saját OpenBSD-s webszerverünk kezdődoldala töltődik be. Hogy történik ez?
A fenti sor egy NAT, mégpedig egy úgynevezett destination-NAT szabály: ennek magyarázata alapján, ha az em1-es interfészünkön (10.0.0.1) a 10.0.0.0/24-es hálózatból ha bármilyen 80-as tcp portra igyekvő csomag érkezik, azt átirányítja a 10.0.0.1 IP 80-as portjára. Ez a konfig tipikus példája annak, amikor pl. transzparens Squid proxyt építünk; ekkor az összes kimenő 80-as célportú forgalom a helyi proxyszerverre lesz irányítva.
Végezetül nézzük még meg az általános formuláját egy NAT sornak a pf.conf fájlban:
match out on interface [af] from src_addr to dst_addr nat-to ext_addr [pool_type] [static-port]
Itt ha egy csomag bejárja a szabályokat és ha egyezés van egy match szabállyal, minden opcionális paraméter ami az adott szabályban van, megjegyződik későbbi felhasználásra.
pass out [log] on interface [af] [proto protocol] from ext_addr [port src_port] to dst_addr [port dst_port]
Ez a szabály engedi a csomagok továbbítását. Ha a csomag előzőleg egy match szabályra illeszkedik, ahol paraméterek voltak specifikálva, ezek alkalmazva lesznek ezen a csomagon. A pass szabálynak lehetnek saját, egyedi paraméterei; ezek elsőbbséget fognak élvezni a match szabályban specifikáltakkal szemben.
Megjegyzendő, hogy az OpenBSD 5.x verziójában a szabályok szintaktikáját újragondolták, és a régebbi nat vagy rdr kezdetű szabályok megszűntek. A régi sor így nézett volna ki:
nat on em0 from 10.0.0.0/24 to any -> 192.168.55.13
Míg az új:
pass out on em0 from 10.0.0.0/24 to any nat-to 192.168.55.13
Összegzés:
Akárcsak a pf többi része, a NAT modul is egyértelmű beállítási opciókkal rendelkezik. Az előző részben megismert makrók, listák természetesen itt is alkalmazhatók. A konfigurációs fájl is ugyanaz, mint a csomagszűrő részben tárgyalt. A következő (és egyben utolsó) részben górcső alá vesszük a pf traffic shaping lehetőségeit, és még egy keveset a pf extrái közül.