OpenBSD PF

A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
(Egyéb szolgáltatások)
 
(egy szerkesztő 4 közbeeső változata nincs mutatva)
1. sor: 1. sor:
A [http://www.openbsd.org/faq/pf/index.html PF] (Packet Filter) az OpenBSD beépített tűzfal rendszere, az OpenBSD 3.0 óta a hivatalos kernel része. Megtalálható a legtöbb egyéb BSD rendszerben is, így a FreeBSD, a NetBSD és a DragonFlyBSD is támogatja.
+
A [http://www.openbsd.org/faq/pf/index.html PF] (Packet Filter) az OpenBSD beépített tűzfal rendszere, az OpenBSD 3.0 óta a hivatalos kernel része. Megtalálható a legtöbb BSD rendszerben, így a FreeBSD, a NetBSD és a DragonFlyBSD is támogatja.
   
 
== A PF aktiválása ==
 
== A PF aktiválása ==
   
A PF boot idejű elindításához a /etc/rc.conf.local fájlba a pf=YEY bejegyzést kell rögzíteni, mely beállítás a következő reboot hatására lép életbe.
+
A PF boot idejű indításához a /etc/rc.conf.local fájlba a pf=YES bejegyzést kell rögzíteni, mely beállítás a következő reboot hatására lép életbe.
   
A PF az operációs rendszer működése közben is aktiválható és deaktiválható az általános sedédprogram a pfctl segítségével:
+
A PF az operációs rendszer működése közben is aktiválható és deaktiválható az általános segédprogram a pfctl segítségével:
 
<pre>
 
<pre>
 
# pfctl -e
 
# pfctl -e
11. sor: 11. sor:
 
</pre>
 
</pre>
   
== Konfiguráláció ==
+
== Konfiguráció ==
   
 
=== A konfigurációs fájl betöltése ===
 
=== A konfigurációs fájl betöltése ===
   
Az tűzfal beállításai a /etc/pf.conf fájlban találhatók, ahonnan a PF a konfigurációt az indulása közben beolvassa. A konfiguráció módosítása a fájl szerkesztésével történhet, mely a pfctl -f /etc/pf.conf parancs hatására kerül a működő rendszerbe betöltésre. A parméter módosításával természetesen más konfigurációs fájl is használható.
+
Az tűzfal beállításai a /etc/pf.conf fájlban találhatók. A konfiguráció módosítása a fájl szerkesztésével történhet, mely a pfctl -f /etc/pf.conf parancs hatására kerül a működő rendszerbe betöltésre. A paraméter módosításával természetesen más konfigurációs fájl is használható.
   
 
=== A pf.conf felépítése ===
 
=== A pf.conf felépítése ===
   
A pf.conf fájl hét részből áll, melyek opcionáliask, de az első kettőt kivéve a sorrend rögzített:
+
A pf.conf fájl hét részből áll, melyek opcionálisak, de az első kettőt kivéve a sorrend rögzített:
   
* Makrók: a felhasználó által definiált változók: IP címek és tartományok, interfész nevek...
+
* Makrók: a felhasználó által definiált változók (IP címek és tartományok, interfész nevek...)
* Táblázatok: (nagy számú) IP cím tárolására kitalált struktúrák, melyekben a keresés nagyon gyors
+
* Táblázatok: (nagyszámú) IP cím tárolására kitalált struktúrák, melyekben a keresés nagyon gyors
 
* Beállítások: általános beállítások a PF viselkedésével kapcsolatban
 
* Beállítások: általános beállítások a PF viselkedésével kapcsolatban
* Forgalom tisztítás: a csomagok darabjainak összeállítása, hibás (illegális tartalmú) csomagok eldobása
+
* Forgalomtisztítás: a csomagok darabjainak összeállítása, hibás (illegális tartalmú) csomagok eldobása
 
* Várakozási sorok: a sávszélesség elosztása, illetve csomagok prioritásának beállítása
 
* Várakozási sorok: a sávszélesség elosztása, illetve csomagok prioritásának beállítása
* Címfordítás és port-forwarding: a NAT beállításai és port-forwarding továbbítási szabályok
+
* Címfordítás és port-forwarding: a NAT beállításai és port-forwarding szabályok
 
* Szűrési szabályok: a csomagok szűrése a megadott szabályok alapján
 
* Szűrési szabályok: a csomagok szűrése a megadott szabályok alapján
   
 
==== Listák és makrók ====
 
==== Listák és makrók ====
   
Listák és makrók segítéségvel egy szabály több IP-cmíre vagy interfészre is alkalmazható:
+
Listák és makrók segítségével egy szabály több IP-címre vagy interfészre is alkalmazható:
 
<pre>
 
<pre>
 
block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
 
block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
 
</pre>
 
</pre>
   
A listák a szabályok betöltése során felbontásra kerülnek, így az előző sor a betöltés után két szabályt eredményez majd:
+
A listák a szabályok betöltése során felbontásra kerülnek, így az előző sor a betöltés után két szabályt eredményez:
 
<pre>
 
<pre>
 
block out on fxp0 from 192.168.0.1 to any
 
block out on fxp0 from 192.168.0.1 to any
42. sor: 42. sor:
 
</pre>
 
</pre>
   
A makrók segítségével a listáknak nevek adhatók, illetve listák egymásba ágyazására is lehetőség nyílik. A makrók a későbbiek során a beállítások között bárhol felhasználhatóak, így nagyban egyszerüsítik a konfiguráció átláthatóságát, illetve a módosításokat is csak a makró definíciójában kell végrehajtani.
+
A makrók segítségével a listáknak nevek adhatók, illetve listák egymásba ágyazására is lehetőség nyílik. A makrók a későbbiek során a beállítások között bárhol felhasználhatóak, így nagyban egyszerűsítik a konfiguráció átláthatóságát, illetve a módosításokat is csak a makró definíciójában kell végrehajtani.
 
<pre>
 
<pre>
 
host1 = "192.168.1.1"
 
host1 = "192.168.1.1"
52. sor: 52. sor:
 
==== Táblázatok ====
 
==== Táblázatok ====
   
A táblázatok célja nagy mennyiségű IP címet hatékonyan tárolni. Táblázat használata esetén a keresés nagyon gyors, a tábla méretétől szinte függetlenül. Amennyiben a táblákat a konfiguráció során a persist paraméterrel hozzuk létre, akkor lehetőség van a tábla tartalmát futási időben módosítani is.
+
A táblázatok célja nagy mennyiségű IP címet hatékonyan tárolni. Táblázat használata esetén a keresés a tábla méretétől szinte függetlenül nagyon gyors. Amennyiben a táblákat a konfiguráció során a persist paraméterrel hozzuk létre, akkor lehetőség van a tábla tartalmát futási időben módosítani.
 
<pre>
 
<pre>
 
table <goodguys> { 192.0.2.0/24 }
 
table <goodguys> { 192.0.2.0/24 }
73. sor: 73. sor:
 
</pre>
 
</pre>
   
Amennyiben egy interfész neve zárójelben szerepel egy szabályban, akkor a PF minden alkalommal az interfész aktuális IP címét fogja halsználni, így a helyi dinamikus IP címek könnyen kezelhetőek.
+
Amennyiben egy interfész neve zárójelben szerepel egy szabályban, akkor a PF minden alkalommal az interfész aktuális IP címét fogja használni, így a helyi dinamikus IP címek könnyen kezelhetőek.
   
Az utolsó előtti paraméterrel a TCP flag-ek ellenőrzése kapcsolható be. Egy tipikus beállítás az alábbi, amely csak a kapcsolat kezdeményezű üzenetváltáshoz hajlandó állapotot létrehozni:
+
Az utolsó előtti paraméterrel a TCP flag-ek ellenőrzése kapcsolható be. Egy tipikus beállítás az alábbi, amely csak a kapcsolat kezdeményező üzenetváltáshoz hajlandó állapotot létrehozni:
 
<pre>
 
<pre>
 
pass in on fxp0 proto tcp from any to any port ssh flags S/SA
 
pass in on fxp0 proto tcp from any to any port ssh flags S/SA
 
</pre>
 
</pre>
A forgalom tiszítása (scrubbing) magától eltávolítja az érvénytelen flag-eket tartalamzó csomagokat (pl. SYN és RST egyszerre), így azokkal nem kell itt külön törődni.
+
A forgalom tisztítása (scrubbing) magától eltávolítja az érvénytelen flag-eket tartalamzó csomagokat (pl. SYN és RST egyszerre), így azokkal nem kell itt külön foglalkozni.
   
 
Az utolsó paraméter, az állapot követés. Az állapot követés célja a kiértékelés jelentős gyorsítása azáltal, hogy az összetartozó csomagok esetén csak az elsőre értékelődnek ki a szabályok, a többire az elsőre érvényes művelet hajtódik végre. A stat érteke az alábbi lehet:
 
Az utolsó paraméter, az állapot követés. Az állapot követés célja a kiértékelés jelentős gyorsítása azáltal, hogy az összetartozó csomagok esetén csak az elsőre értékelődnek ki a szabályok, a többire az elsőre érvényes művelet hajtódik végre. A stat érteke az alábbi lehet:
85. sor: 85. sor:
 
* modulate state: csak TCP esetén működik, a PF "erős" sequence number-eket generál az illeszkedő csomagokhoz
 
* modulate state: csak TCP esetén működik, a PF "erős" sequence number-eket generál az illeszkedő csomagokhoz
 
* synproxy state: az előző kettő együtt, és proxy-zza a bejövő TCP kapcsolatokat, így megvédhető egy belső szerver a TCP SYN flood-tól
 
* synproxy state: az előző kettő együtt, és proxy-zza a bejövő TCP kapcsolatokat, így megvédhető egy belső szerver a TCP SYN flood-tól
A kapcsolatok állapotának követése során a PF mindkét irányba képes a csomagokat azonosítani, így egy bejövő csomagra érkező válasz a bejövő csomaghoz tartozó állapot alapján kerül elbírálásra. Ennek köszönhetően még az adott kapcsolathoz tarotozó ICMP üzenetek is gond nélkül átjutnak a tűzfalon.
+
A kapcsolatok állapotának követése során a PF mindkét irányba képes a csomagokat azonosítani, így egy bejövő csomagra érkező válasz a bejövő csomaghoz tartozó állapot alapján kerül elbírálásra. Ennek köszönhetően még az adott kapcsolathoz tartotozó ICMP üzenetek is gond nélkül átjutnak a tűzfalon.
   
 
Az egyes szabályok kiértékelése sorban, egymás után történik. Az utolsó illeszkedő szabály határozza meg, hogy a csomaggal mi történjen. Ez alól az egyedüli kivételek a quick kulcsszóval ellátott szabályok, melyek illeszkedése esetén a PF az adott szabályt tekinti az utolsónak.
 
Az egyes szabályok kiértékelése sorban, egymás után történik. Az utolsó illeszkedő szabály határozza meg, hogy a csomaggal mi történjen. Ez alól az egyedüli kivételek a quick kulcsszóval ellátott szabályok, melyek illeszkedése esetén a PF az adott szabályt tekinti az utolsónak.
   
Lehetőség van a hamis feladójú csomagok szűrésére az antispoof segítségével. Egy tipikus ilyen bejegyzés az alábbi:
+
Lehetőség van a hamis feladójú csomagok szűrésére az antispoof segítségével. Egy tipikus ilyen bejegyzés az alábbi:
 
<pre>
 
<pre>
 
antispoof for fxp0 inet
 
antispoof for fxp0 inet
135. sor: 135. sor:
 
A PF alapvetően FIFO elven kezeli a csomagokat. Ezen sorok bevezetésével lehet változtatni. Lehetőség van Osztály alapú vagy Prioritsá alapú megoldást választani.
 
A PF alapvetően FIFO elven kezeli a csomagokat. Ezen sorok bevezetésével lehet változtatni. Lehetőség van Osztály alapú vagy Prioritsá alapú megoldást választani.
   
Az osztály alapú megoldás alkalmazása esetén a sávszélességet különböző osztályok között lehet felosztani. Az osztályok alá tartozhatnak további üzenetsorok, melyek a magasabb szint számára kiosztott sávszélességen osztoznak. Lehetőség van az egyes aktív soroknak a többiek felesleges sávszélességét is biztosítani (borrow), amennyiben a többi sornak arra nincs szüksége. Az azonos szinten lévő sorok között prioritásokat lehet kiosztani. Egy minta konfiguráció:
+
Az osztály alapú megoldás alkalmazása esetén a sávszélességet különböző osztályok között lehet felosztani. Az osztályok alá tartozhatnak további üzenetsorok, melyek a magasabb szint számára kiosztott sávszélességen osztoznak. Lehetőség van az egyes aktív soroknak a többiek felesleges sávszélességét is biztosítani (borrow). Az azonos szinten lévő sorok között prioritásokat lehet kiosztani. Egy minta konfiguráció:
 
<pre>
 
<pre>
 
Root Queue (2Mbps)
 
Root Queue (2Mbps)
156. sor: 156. sor:
 
pass out on fxp0 from any to any port 22 queue(ssh_bulk, ssh_login)
 
pass out on fxp0 from any to any port 22 queue(ssh_bulk, ssh_login)
 
</pre>
 
</pre>
Látható, hogy az adott csomag két sorhoz is hozzá van rendelve. Ilyenkor a PF azokat a csomagokat helyezi a második sorba, melyek ToS fejlécében a low-delay áll, vagy az adott csomag egy TCP ACK. Ez akkor különösen előnyös, ha asszimetrikus a kapcsolat (pl ADSL), mivel ilyenkor ezek a csomagok elsőbbséget élvezheznek.
+
Látható, hogy az adott csomag két sorhoz is hozzá van rendelve. Ilyenkor a PF azokat a csomagokat helyezi a második sorba, melyek ToS fejlécében a low-delay áll, vagy az adott csomag egy TCP ACK. Ez akkor különösen előnyös, ha aszimmetrikus a kapcsolat (pl. ADSL), mivel ilyenkor ezek a csomagok elsőbbséget élvezhetnek.
   
   
 
==== Példa konfiguráció ====
 
==== Példa konfiguráció ====
 
<pre>
 
<pre>
# enable queueing on the external interface to control traffic going to
+
# macros
# the Internet. use the priq scheduler to control only priorities. set
+
ext_if="fxp0"
# the bandwidth to 610Kbps to get the best performance out of the TCP
+
int_if="xl0"
# ACK queue.
 
   
altq on fxp0 priq bandwidth 610Kb queue { std_out, ssh_im_out, dns_out, tcp_ack_out }
+
tcp_services="{ 22, 113 }"
  +
icmp_types="echoreq"
   
# define the parameters for the child queues.
+
comp3="192.168.0.3"
# std_out - the standard queue. any filter rule below that does not
 
# explicitly specify a queue will have its traffic added
 
# to this queue.
 
# ssh_im_out - interactive SSH and various instant message traffic.
 
# dns_out - DNS queries.
 
# tcp_ack_out - TCP ACK packets with no data payload.
 
   
queue std_out priq(default)
+
# options
queue ssh_im_out priority 4 priq(red)
+
set block-policy return
queue dns_out priority 5
+
set loginterface $ext_if
queue tcp_ack_out priority 6
 
   
# enable queueing on the internal interface to control traffic coming in
+
set skip on lo
# from the Internet. use the cbq scheduler to control bandwidth. max
 
# bandwidth is 2Mbps.
 
   
altq on dc0 cbq bandwidth 2Mb queue { std_in, ssh_im_in, dns_in, bob_in }
+
# scrub
  +
scrub in
   
# define the parameters for the child queues.
+
# nat/rdr
# std_in - the standard queue. any filter rule below that does not
+
nat on $ext_if from !($ext_if) -> ($ext_if:0)
# explicitly specify a queue will have its traffic added
+
nat-anchor "ftp-proxy/*"
# to this queue.
+
rdr-anchor "ftp-proxy/*"
# ssh_im_in - interactive SSH and various instant message traffic.
 
# dns_in - DNS replies.
 
# bob_in - bandwidth reserved for Bob's workstation. allow him to
 
# borrow.
 
   
queue std_in bandwidth 1.6Mb cbq(default)
+
rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
queue ssh_im_in bandwidth 200Kb priority 4
+
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
queue dns_in bandwidth 120Kb priority 5
 
queue bob_in bandwidth 80Kb cbq(borrow)
 
   
# ... in the filtering section of pf.conf ...
+
# filter rules
alice = "192.168.0.2"
+
block in
bob = "192.168.0.3"
 
charlie = "192.168.0.4"
 
local_net = "192.168.0.0/24"
 
ssh_ports = "{ 22 2022 }"
 
im_ports = "{ 1863 5190 5222 }"
 
   
# filter rules for fxp0 inbound
+
pass out keep state
block in on fxp0 all
 
   
# filter rules for fxp0 outbound
+
anchor "ftp-proxy/*"
block out on fxp0 all
+
antispoof quick for { lo $int_if }
   
pass out on fxp0 inet proto tcp from (fxp0) to any flags S/SA keep state queue(std_out, tcp_ack_out)
+
pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state
pass out on fxp0 inet proto { udp icmp } from (fxp0) to any keep state
 
pass out on fxp0 inet proto { tcp udp } from (fxp0) to any port domain keep state queue dns_out
 
pass out on fxp0 inet proto tcp from (fxp0) to any port $ssh_ports flags S/SA keep state queue(std_out, ssh_im_out)
 
pass out on fxp0 inet proto tcp from (fxp0) to any port $im_ports flags S/SA keep state queue(ssh_im_out, tcp_ack_out)
 
 
# filter rules for dc0 inbound
 
block in on dc0 all
 
pass in on dc0 from $local_net
 
 
# filter rules for dc0 outbound
 
block out on dc0 all
 
pass out on dc0 from any to $local_net
 
pass out on dc0 proto { tcp udp } from any port domain to $local_net queue dns_in
 
pass out on dc0 proto tcp from any port $ssh_ports to $local_net queue(std_in, ssh_im_in)
 
pass out on dc0 proto tcp from any port $im_ports to $local_net queue ssh_im_in
 
pass out on dc0 from any to $bob queue bob_in
 
 
</pre>
 
</pre>
 
   
 
== Egyéb szolgáltatások ==
 
== Egyéb szolgáltatások ==
201. sor: 200. sor:
 
A PF számos további szolgáltatást nyújt.
 
A PF számos további szolgáltatást nyújt.
   
Lehetőség van cím tartományok kezelésére, mely például akkor hasznos, ha több külső interfész felé szeretnénk NAT-olni. Iyenkor az éppen használt interfész kiválasztására több lehetőség is van:
+
Lehetőség van cím tartományok kezelésére, mely például akkor hasznos, ha több külső interfész felé szeretnénk NAT-olni. Iyenkor az éppen használt interfész kiválasztására több mód is van:
 
* A célcímhez "legközelebbi" cím használata
 
* A célcímhez "legközelebbi" cím használata
 
* Véletlenszerűen választott cím használata
 
* Véletlenszerűen választott cím használata
* A forrás alapján a legutóbb választott (hogy az egymást követő kérések azonos interfészen kereszül menjenek ki)
+
* A forrás alapján a legutóbb választott (hogy az egymást követő kérések azonos interfészen keresztül menjenek ki)
 
* Round-robin
 
* Round-robin
   
Lehetőség van policy-k alapján szűrni a csomagokat. Ehhez az egyes bejövő csomagokat cimkékkel (tag) kell elláni, majd a szabályok megfogalmazhatóak már csak a cimkékre. Például a címkék elhelyezhetők így:
+
Lehetőség van policy-k alapján szűrni a csomagokat. Ehhez az egyes bejövő csomagokat címkékkel (tag) kell elláni, majd a szabályok megfogalmazhatóak már csak a címkékre. Például a címkék elhelyezhetők így:
 
<pre>
 
<pre>
 
block all
 
block all
222. sor: 221. sor:
 
</pre>
 
</pre>
   
A PF alapértelmezetten tcpdump formátumban logolja a konfiguráció alapján logolásra érdemes üzeneteket, egy saját script (és a tcpdum) segítségével ez ASCII formátumra alakítható, így pedig már a syslog is fogadni képes a naplóbejegyzéseket.
+
A PF alapértelmezetten tcpdump formátumban logolja a konfiguráció alapján logolásra érdemes csomagokat, de egy saját script (és a tcpdump) segítségével ez ASCII formátumra alakítható, így pedig már a syslog is fogadni képes a naplóbejegyzéseket.
   
Az Authpf segítségével lehetőségünk van egy bejelentkezési shell-t létrehozni a felahsználók számára. Amikor a felhasználó bejelentkezik, akkor a tűzfalba betöltődnek a szabályok, melyek az ő kommunikációját engedélyezik. A szabályok mindaddig élnek, míg a felhasználó kijelentkezik, ilyenkor a hozzáférése a hálózathoz automatikusan megszűnki.
+
Az Authpf segítségével lehetőségünk van egy bejelentkezési shell-t létrehozni a felahsználók számára. Amikor a felhasználó bejelentkezik, akkor a tűzfalba betöltődnek a szabályok, melyek az ő kommunikációját engedélyezik. A szabályok mindaddig élnek, míg a felhasználó kijelentkezik, ilyenkor a hozzáférése a hálózathoz automatikusan megszűnik.
   
A CARP (Common Address Redundancy Protocol) segítségével lehetőségünk nyílik több számítógép között egy IP-t közösen kiosztani. Mindig van egy master, akinek a kiesése esetén egy slave veszi át a helyét. A pfsync segítségével több tűzfal között automatikussá tehető a konfiguráció szinkronizálása. A CARP-ot a pfsync-el kiegészítve igen nagy rendelkezésreállású tűzfal hozható létre.
+
A CARP (Common Address Redundancy Protocol) segítségével lehetőségünk nyílik több számítógép között egy IP-t közösen kiosztani. Mindig van egy master, akinek a kiesése esetén az egyik slave veszi át a helyét. A pfsync segítségével több tűzfal között automatikussá tehető a konfiguráció szinkronizálása. A CARP-ot a pfsync-el kiegészítve igen nagy rendelkezésreállású tűzfal hozható létre.
   
<pre>
+
--Epe 2007. november 25., 01:26 (CET)
 
</pre>
 

A lap jelenlegi, 2007. november 26., 01:52-kori változata

A PF (Packet Filter) az OpenBSD beépített tűzfal rendszere, az OpenBSD 3.0 óta a hivatalos kernel része. Megtalálható a legtöbb BSD rendszerben, így a FreeBSD, a NetBSD és a DragonFlyBSD is támogatja.

Tartalomjegyzék

[szerkesztés] 1 A PF aktiválása

A PF boot idejű indításához a /etc/rc.conf.local fájlba a pf=YES bejegyzést kell rögzíteni, mely beállítás a következő reboot hatására lép életbe.

A PF az operációs rendszer működése közben is aktiválható és deaktiválható az általános segédprogram a pfctl segítségével:

# pfctl -e
# pfctl -d

[szerkesztés] 2 Konfiguráció

[szerkesztés] 2.1 A konfigurációs fájl betöltése

Az tűzfal beállításai a /etc/pf.conf fájlban találhatók. A konfiguráció módosítása a fájl szerkesztésével történhet, mely a pfctl -f /etc/pf.conf parancs hatására kerül a működő rendszerbe betöltésre. A paraméter módosításával természetesen más konfigurációs fájl is használható.

[szerkesztés] 2.2 A pf.conf felépítése

A pf.conf fájl hét részből áll, melyek opcionálisak, de az első kettőt kivéve a sorrend rögzített:

  • Makrók: a felhasználó által definiált változók (IP címek és tartományok, interfész nevek...)
  • Táblázatok: (nagyszámú) IP cím tárolására kitalált struktúrák, melyekben a keresés nagyon gyors
  • Beállítások: általános beállítások a PF viselkedésével kapcsolatban
  • Forgalomtisztítás: a csomagok darabjainak összeállítása, hibás (illegális tartalmú) csomagok eldobása
  • Várakozási sorok: a sávszélesség elosztása, illetve csomagok prioritásának beállítása
  • Címfordítás és port-forwarding: a NAT beállításai és port-forwarding szabályok
  • Szűrési szabályok: a csomagok szűrése a megadott szabályok alapján

[szerkesztés] 2.2.1 Listák és makrók

Listák és makrók segítségével egy szabály több IP-címre vagy interfészre is alkalmazható:

block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any

A listák a szabályok betöltése során felbontásra kerülnek, így az előző sor a betöltés után két szabályt eredményez:

block out on fxp0 from 192.168.0.1 to any
block out on fxp0 from 10.5.32.6 to any

A makrók segítségével a listáknak nevek adhatók, illetve listák egymásba ágyazására is lehetőség nyílik. A makrók a későbbiek során a beállítások között bárhol felhasználhatóak, így nagyban egyszerűsítik a konfiguráció átláthatóságát, illetve a módosításokat is csak a makró definíciójában kell végrehajtani.

host1 = "192.168.1.1"
host2 = "192.168.1.2"
all_hosts = "{" $host1 $host2 "}"


[szerkesztés] 2.2.2 Táblázatok

A táblázatok célja nagy mennyiségű IP címet hatékonyan tárolni. Táblázat használata esetén a keresés a tábla méretétől szinte függetlenül nagyon gyors. Amennyiben a táblákat a konfiguráció során a persist paraméterrel hozzuk létre, akkor lehetőség van a tábla tartalmát futási időben módosítani.

table <goodguys> { 192.0.2.0/24 }
table <rfc1918> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
table <spammers> persist
block in on fxp0 from { <rfc1918>, <spammers> } to any
pass in on fxp0 from <goodguys> to any

A spammers táblához egy külső fájl is rendelhető, melynek tartalma a konfiguráció betöltése közben a táblába kerül. A pftcl segítségével lehetőség van a táblák tartalmát működés közben módosítani, elemeket felvenni és törölni.


[szerkesztés] 2.2.3 Csomagszűrés

A szabályok általános alakja az alábbi:

action [direction] [log] [quick] [on interface] [af] [proto protocol] \
[from src_addr [port src_port]] [to dst_addr [port dst_port]] \
[flags tcp_flags] [state]

Amennyiben egy interfész neve zárójelben szerepel egy szabályban, akkor a PF minden alkalommal az interfész aktuális IP címét fogja használni, így a helyi dinamikus IP címek könnyen kezelhetőek.

Az utolsó előtti paraméterrel a TCP flag-ek ellenőrzése kapcsolható be. Egy tipikus beállítás az alábbi, amely csak a kapcsolat kezdeményező üzenetváltáshoz hajlandó állapotot létrehozni:

pass in on fxp0 proto tcp from any to any port ssh flags S/SA

A forgalom tisztítása (scrubbing) magától eltávolítja az érvénytelen flag-eket tartalamzó csomagokat (pl. SYN és RST egyszerre), így azokkal nem kell itt külön foglalkozni.

Az utolsó paraméter, az állapot követés. Az állapot követés célja a kiértékelés jelentős gyorsítása azáltal, hogy az összetartozó csomagok esetén csak az elsőre értékelődnek ki a szabályok, a többire az elsőre érvényes művelet hajtódik végre. A stat érteke az alábbi lehet:

  • keep state: hagyományos állapot követés
  • modulate state: csak TCP esetén működik, a PF "erős" sequence number-eket generál az illeszkedő csomagokhoz
  • synproxy state: az előző kettő együtt, és proxy-zza a bejövő TCP kapcsolatokat, így megvédhető egy belső szerver a TCP SYN flood-tól

A kapcsolatok állapotának követése során a PF mindkét irányba képes a csomagokat azonosítani, így egy bejövő csomagra érkező válasz a bejövő csomaghoz tartozó állapot alapján kerül elbírálásra. Ennek köszönhetően még az adott kapcsolathoz tartotozó ICMP üzenetek is gond nélkül átjutnak a tűzfalon.

Az egyes szabályok kiértékelése sorban, egymás után történik. Az utolsó illeszkedő szabály határozza meg, hogy a csomaggal mi történjen. Ez alól az egyedüli kivételek a quick kulcsszóval ellátott szabályok, melyek illeszkedése esetén a PF az adott szabályt tekinti az utolsónak.

Lehetőség van a hamis feladójú csomagok szűrésére az antispoof segítségével. Egy tipikus ilyen bejegyzés az alábbi:

antispoof for fxp0 inet

Ennek hatására a konfiguráció betöltése során az alábbi két szabály jön létre, ha az fxp0 IP címe 10.0.0.1:

block in on ! fxp0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.1 to any


[szerkesztés] 2.2.4 Címfordítás

A címfordítás használatához engedélyezni kell az operációs rendszerben a csomagok továbbítását interfészek között. (Erre tűzfal esetén egyébként is szükség van.)

# sysctl net.inet.ip.forwarding=1

A NAT-ot az alábbi általános szabály segítségével lehet konfigurálni:

nat [pass] [log] on interface [af] from src_addr [port src_port] to \
dst_addr [port dst_port] -> ext_addr [pool_type] [static-port]

Az IP címek akár egy-egy megfeleltethetőek egymással a binat szabály használatával.


[szerkesztés] 2.2.5 Port-forwarding

A port-forwarding akkor válik szükségessé, ha van egy gép a tűfal mögött, amit a külvilág számára elérhetővé kell tenni. (Ez persze biztonsági rést is jelenthet, így az ilyen gépeket célszerű egy DMZ-ben összegyűjteni.) A következő példában egy webszervert üzemeltetünk a belső hálózaton, mely kívülről is elérhető:

rdr on tl0 proto tcp from any to any port 80 -> 192.168.1.20

Az rdr után a pass paramétert megadva a csomag azonnal továbbításra kerül, így nincs szükség egy szabály megadására, mely az adott kapcsolatot engedélyezi. Lehetőség van portokat és port tartományokat is továbbítani.


[szerkesztés] 2.2.6 Horgonyok használata

Lehetőség van a konfigurációban horgonyokat elhelyezni (anchor), ahová további konfigurációkat lehet bekötni. Ezeket az alkonfigurációkat a PF működése közben a pfctl segítségével lehet módosítani. A horgonyokhoz tartozhatnak feltételek is, így elágazásokat is létre lehet hozni a szabályok kiértékelésében. A legtipikusabb használat az FTP proxy beregisztrálása.


[szerkesztés] 2.2.7 Sorkezelés

A PF alapvetően FIFO elven kezeli a csomagokat. Ezen sorok bevezetésével lehet változtatni. Lehetőség van Osztály alapú vagy Prioritsá alapú megoldást választani.

Az osztály alapú megoldás alkalmazása esetén a sávszélességet különböző osztályok között lehet felosztani. Az osztályok alá tartozhatnak további üzenetsorok, melyek a magasabb szint számára kiosztott sávszélességen osztoznak. Lehetőség van az egyes aktív soroknak a többiek felesleges sávszélességét is biztosítani (borrow). Az azonos szinten lévő sorok között prioritásokat lehet kiosztani. Egy minta konfiguráció:

Root Queue (2Mbps)
    UserA (1Mbps, priority 1)
        ssh (100Kbps, priority 5)
        ftp (900Kbps, priority 3)
     UserB (1Mbps, priority 1)

A prioritásos sorkezelés az előző hierarchikus szerkezettel ellentétbe egy szinten kezeli a sorokat, minden sorhoz egy-egy prioritást rendelve. Az adott sorban várakozó csomagok mindaddig nem továbbítódnak, amíg bármelyik magasabb prioritási szinten van csomag, így könnyen kialakulhat kiéheztetés.

Root Queue (2Mbps)
    Queue A (priority 1)
    Queue B (priority 2)
    Queue C (priority 3)

Az egyes szabályok által érintett csomagok sorokba rendezését az alábbi példa szemlélteti:

pass out on fxp0 from any to any port 22 queue(ssh_bulk, ssh_login)

Látható, hogy az adott csomag két sorhoz is hozzá van rendelve. Ilyenkor a PF azokat a csomagokat helyezi a második sorba, melyek ToS fejlécében a low-delay áll, vagy az adott csomag egy TCP ACK. Ez akkor különösen előnyös, ha aszimmetrikus a kapcsolat (pl. ADSL), mivel ilyenkor ezek a csomagok elsőbbséget élvezhetnek.


[szerkesztés] 2.2.8 Példa konfiguráció

# macros
ext_if="fxp0"
int_if="xl0"

tcp_services="{ 22, 113 }"
icmp_types="echoreq"

comp3="192.168.0.3"

# options
set block-policy return
set loginterface $ext_if

set skip on lo

# scrub
scrub in

# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0)
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"

rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3

# filter rules
block in

pass out keep state

anchor "ftp-proxy/*"
antispoof quick for { lo $int_if }

pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state

[szerkesztés] 3 Egyéb szolgáltatások

A PF számos további szolgáltatást nyújt.

Lehetőség van cím tartományok kezelésére, mely például akkor hasznos, ha több külső interfész felé szeretnénk NAT-olni. Iyenkor az éppen használt interfész kiválasztására több mód is van:

  • A célcímhez "legközelebbi" cím használata
  • Véletlenszerűen választott cím használata
  • A forrás alapján a legutóbb választott (hogy az egymást követő kérések azonos interfészen keresztül menjenek ki)
  • Round-robin

Lehetőség van policy-k alapján szűrni a csomagokat. Ehhez az egyes bejövő csomagokat címkékkel (tag) kell elláni, majd a szabályok megfogalmazhatóak már csak a címkékre. Például a címkék elhelyezhetők így:

block all
pass in on $int_if from $int_net tag LAN_INET keep state
pass in on $int_if from $int_net to $dmz_net tag LAN_DMZ keep state
pass in on $ext_if proto tcp to $www_server port 80 tag INET_DMZ keep state

Ezt követően a szabályok alakja az alábbi:

pass in quick on $ext_if tagged SPAMD keep state
pass out quick on $ext_if tagged LAN_INET_NAT keep state
pass out quick on $dmz_if tagged LAN_DMZ keep state
pass out quick on $dmz_if tagged INET_DMZ keep state

A PF alapértelmezetten tcpdump formátumban logolja a konfiguráció alapján logolásra érdemes csomagokat, de egy saját script (és a tcpdump) segítségével ez ASCII formátumra alakítható, így pedig már a syslog is fogadni képes a naplóbejegyzéseket.

Az Authpf segítségével lehetőségünk van egy bejelentkezési shell-t létrehozni a felahsználók számára. Amikor a felhasználó bejelentkezik, akkor a tűzfalba betöltődnek a szabályok, melyek az ő kommunikációját engedélyezik. A szabályok mindaddig élnek, míg a felhasználó kijelentkezik, ilyenkor a hozzáférése a hálózathoz automatikusan megszűnik.

A CARP (Common Address Redundancy Protocol) segítségével lehetőségünk nyílik több számítógép között egy IP-t közösen kiosztani. Mindig van egy master, akinek a kiesése esetén az egyik slave veszi át a helyét. A pfsync segítségével több tűzfal között automatikussá tehető a konfiguráció szinkronizálása. A CARP-ot a pfsync-el kiegészítve igen nagy rendelkezésreállású tűzfal hozható létre.

--Epe 2007. november 25., 01:26 (CET)

Személyes eszközök