[Vorige: Tabellen] [Inhoud] [Volgende: Network Address Translation]
Filterregels specificeren de criteria waaraan een pakket moet voldoen en de resulterende actie, ofwel blokkeren ofwel passeren, die ondernomen wordt wanneer een overeenstemming gevonden wordt. Filterregels worden in na elkaar komende volgorde geëvalueerd, eerste tot laatste. Tenzij het pakket overeenstemt met een regel die het quick sleutelwoord bevat, zal het pakket geëvalueerd worden met alle filterregels alvorens de uiteindelijke actie ondernomen wordt. De laatste regel die overeenstemt is de "winnaar" en zal dicteren welke actie er met het pakket ondernomen moet worden. Er is een impliciete pass all bij het begin van een filterregelset, wat betekent dat als een pakket met geen enkele filterregel overeenstemt, de resulterende actie pass zal zijn.
actie [richting] [log] [quick] [on interface] [af] [proto protocol] \
[from src_addr [port src_port]] [to dst_addr [port dst_port]] \
[flags tcp_flags] [state]
Om een standaard weigeren filterbeleid te creëren, zouden de eerste twee filterregels de volgende moeten zijn:
block in all
block out all
Dit zal alle verkeer op alle interfaces in elke richting van gelijk waar naar gelijk waar blokkeren.
Enkele voorbeelden:
# Laat verkeer binnen op dc0 vanuit het lokale netwerk,
# 192.168.0.0/24, naar het IP adres van de OpenBSD machine,
# 192.168.0.1. Laat ook het terugkerende verkeer naar buiten
# op dc0.
pass in on dc0 from 192.168.0.0/24 to 192.168.0.1
pass out on dc0 from 192.168.0.1 to 192.168.0.0/24
# Laat TCP verkeer binnen op fxp0 naar de webserver die draait op
# de OpenBSD machine. De interfacenaam, fxp0, wordt gebruikt als
# het bestemmingsadres zodat pakketten enkel met deze regel
# overeenstemmen als ze bestemd zijn voor de OpenBSD machine.
pass in on fxp0 proto tcp from any to fxp0 port www
Fout:
block in on fxp0 proto tcp from any to any port ssh
pass in all
In dit geval kan de block lijn geëvalueerd worden, maar ze zal nooit enig effect hebben, aangezien ze gevolgd wordt door een lijn die alles zal doorlaten.
Beter:
block in quick on fxp0 proto tcp from any to any port ssh
pass in all
Deze regels worden een beetje verschillend geëvalueerd. Als de block overeenstemt, door de quick optie, zal het pakket geblokkeerd worden, en zal de rest van de regelset genegeerd worden.
Toestand bijhouden heeft vele voordelen waaronder eenvoudigere regelsets en betere pakketfilterpresatie. PF kan pakketten die in gelijk welke richting bewegen, in overeenstemming brengen met toestandstabel-entries, wat betekent dat filterregels die terugkerend verkeer doorlaten niet geschreven hoeven te worden. En, aangezien pakketten die overeenstemmen met stateful verbindingen niet doorheen regelsetevaluatie hoeven te gaan, kan de tijd die PF besteedt aan het verwerken van die pakketten enorm verminderd worden.
Wanneer een regel een "state" creëert, creëert het eerste pakket dat overeenstemt met de regel een "state" tussen zender en ontvanger. Nu stemmen niet alleen pakketten die van zender naar ontvanger gaan, overeen met de toestand-entry en ze gaan voorbij aan regelsetevaluatie, maar ook de antwoordpakketten van ontvanger naar zender.
Beginnend bij OpenBSD 4.1 creëren alle filterregels automatisch een "state entry" wanneer een pakket overeenstemt met de regel. In eerdere versies van OpenBSD moest de filterregel expliciet de keep state optie gebruiken.
Voorbeeld met OpenBSD 4.1 en volgende:
pass out on fxp0 proto tcp from any to any
Voorbeeld met OpenBSD 4.0 en vroeger:
pass out on fxp0 proto tcp from any to any keep state
Deze regels laten gelijk welk uitgaand TCP verkeer toe op de fxp0 interface en staan ook toe dat het antwoordverkeer terug doorheen de firewall gaat. Hoewel toestand bijhouden een leuke functionaliteit is, verbetert het gebruik ervan aanzienlijk de prestatie van uw firewall aangezien toestandsopzoekingen spectaculair sneller zijn dan een pakket doorheen de filterregels laten lopen.
De modulate state optie werkt net zoals keep state behalve dat ze alleen van toepassing is op TCP pakketten. Met modulate state wordt het Initial Sequence Number (ISN) van uitgaande verbindingen gerandomiseerd. Dit is nuttig om verbindingen te beschermen die geïnitieerd werden door bepaalde besturingssystemen die slecht ISNs kiezen. Beginnend met OpenBSD 3.5, kan de modulate state optie gebruikt worden in regels die andere protocols dan TCP specificeren.
Toestand bijhouden op uitgaande TCP, UDP en ICMP pakketten en TCP ISNs moduleren:
pass out on fxp0 proto { tcp, udp, icmp } from any \
to any modulate state
Een ander voordeel van toestand bijhouden is dat overeenkomstig ICMP verkeer zal doorgelaten worden doorheen de firewall. Als bijvoorbeeld een TCP verbinding die door de firewall gaat met "state" opgevolgd wordt en er komt een ICMP source-quench bericht aan dat verwijst naar deze TCP verbinding, dan zal het met de gepaste toestand-entry in overeenstemming gebracht worden en doorheen de firewall gelaten worden.
Het bereik van een toestand-entry wordt globaal gecontroleerd door de state-policy runtime optie en op een per regel basis door de if-bound, group-bound en floating state optie sleutelwoorden. Deze per regel sleutelwoorden hebben dezelfde betekenis als wanneer ze gebruikt worden met de state-policy optie. Voorbeeld:
pass out on fxp0 proto { tcp, udp, icmp } from any \
to any modulate state (if-bound)
Deze regel zou opdragen dat opdat pakketten zouden overeenstemmen met de toestand-entry, ze de fxp0 interface moeten doorkruisen.
Merk op dat nat, binat en rdr regels impliciet toestand creëren voor overeenstemmende verbindingen zolang de verbinding doorgelaten wordt door de filterregelset.
Opties worden gespecificeerd tussen haakjes en onmiddellijk na één van de state sleutelwoorden (keep state, modulate state of synproxy state). Meerdere opties worden gescheiden door komma's. Vanaf OpenBSD 4.1 werd de keep state optie impliciet de standaard voor alle filterregels. Desondanks moet, wanneer men stateful opties specificeert, één van de state sleutelwoorden nog steeds gebruikt worden vóór de opties.
Een voorbeeldregel:
pass in on $ext_if proto tcp to $web_server \
port www keep state \
(max 200, source-track rule, max-src-nodes 100, max-src-states 3)
De bovenstaande regel definieert het volgende gedrag:
Een afzonderlijk stel beperkingen kan geplaatst worden op "stateful" TCP verbindingen die de 3-wegs handdruk voltooid hebben.
Beide opties roepen automatisch de source-track rule optie op en zijn niet compatibel met source-track global.
Aangezien deze beperkingen alleen geplaatst worden op TCP verbindingen die de 3-wegs handdruk voltooid hebben, kunnen meer agressieve acties genomen worden op overtredende IP adressen.
Een voorbeeld:
table <abusive_hosts> persist
block in quick from <abusive_hosts>
pass in on $ext_if proto tcp to $web_server \
port www flags S/SA keep state \
(max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush)
Dit doet het volgende:
Om PF de TCP vlaggen te laten inspecteren tijdens de evaluatie van een regel, wordt het flags sleutelwoord gebruikt met de volgende syntaxis:
flags check/mask
flags any
Het mask gedeelte vertelt PF alleen de gespecificeerde vlaggen te inspecteren en het check gedeelte specificeert welke vlag(gen) "aan" moeten staan in de hoofding opdat overeenstemming zou plaatsvinden. Het gebruik van het any sleutelwoord laat gelijk welke combinatie van vlaggen toe in de hoofding.
pass in on fxp0 proto tcp from any to any port ssh flags S/SA
De bovenstaande regel laat TCP verkeer door met de SYN vlag aangezet terwijl hij enkel kijkt naar de SYN en ACK vlaggen. Een pakket met de SYN en ECE vlaggen zou overeenstemmen met de bovenstaande regel, maar een pakket met SYN en ACK of gewoon ACK niet.
Vanaf OpenBSD 4.1 zijn de standaardvlaggen die toegepast worden op TCP regels flags S/SA. In combinatie met de OpenBSD 4.1 standaard keep state op filterregels worden deze twee regels equivalent:
pass out on fxp0 proto tcp all flags S/SA keep state
pass out on fxp0 proto tcp all
Iedere regel zal overeenstemmen met TCP pakketten waarbij die de SYN vlag aan staat en de ACK vlag uit, en zullen een "state entry" creëren voor overeenstemmende pakketten. De standaardvlaggen kunnen overschreden worden door de flags optie zoals hierboven beschreven.
In OpenBSD 4.0 en vroeger werden standaard geen vlaggen toegepast op filterregels. Iedere regel moest specificeren welke vlag(gen) moesten overeenstemmen en moest ook expliciet de keep state optie gebruiken.
pass out on fxp0 proto tcp all flags S/SA keep state
Men moet voorzichtig zijn met het gebruik van vlaggen -- begrijp wat u aan
het doen bent en waarom, en wees voorzichtig met de raad die mensen geven
aangezien veel ervan slecht is. Sommige mensen hebben gesuggereerd toestand
te creëren "alleen als de SYN vlag aangezet is en geen andere". Zo'n regel
zou eindigen op:
. . . flags S/FSRPAUEW slecht idee!!
De theorie is: creëer toestand alleen bij het begin van de TCP sessie, en de sessie zou moeten beginnen met een SYN vlag, en geen andere. Het probleem is dat sommige sites de ECN vlag beginnen te gebruiken en gelijk welke site die ECN gebruikt en met u probeert te verbinden, zou afgewezen worden door zulk een regel. Een veel betere richtlijn is helemaal geen vlaggen specificeren en PF de standaardvlaggen laten toepassen op uw regels. Als u werkelijk zelf de vlaggen moet specificeren, dan zou deze combinatie veilig moeten zijn:
. . . flags S/SAFR
Hoewel dit praktisch en veilig is, is het onnodig om de FIN en RST vlaggen na te kijken indien trafiek ook geschrobd wordt. Het schrob-proces zal ervoor zorgen dat PF binnenkomende pakketten met illegale TCP vlag combinaties (zoals SYN en RST) laat vallen en mogelijk dubbelzinnige combinaties (zoals SYN en FIN) normaliseert.
Normaal gezien, wanneer een client een TCP verbinding met een server initieert, zal PF de handdruk ("handshake") pakketten tussen de twee eindpunten doorlaten als ze aankomen. PF heeft echter de mogelijkheid om de handdruk te proxy'en. Wanneer de handdruk geproxied wordt, zal PF zelf de handdruk met de client voltooien, een handdruk met de server initiëren, en vervolgens pakketten tussen beide doorsturen. Het voordeel van dit proces is dat er geen pakketten naar de server gestuurd worden alvorens de client de handdruk voltooit. Dit elimineert de bedreiging van gespoofte TCP SYN floods die de server treffen omdat een gespoofte client verbinding de handdruk niet zal kunnen voltooien.
De TCP SYN proxy wordt ingeschakeld met de synproxy state sleutelwoorden in filterregels. Voorbeeld:
pass in on $ext_if proto tcp from any to $web_server port www \
flags S/SA synproxy state
Hier zullen verbindingen naar de webserver TCP-geproxied worden door PF.
Omwille van de manier waarop synproxy state werkt, omvat het ook dezelfde functionaliteit als keep state en modulate state.
De SYN proxy zal niet werken als PF draait op een bridge(4).
PF biedt wat bescherming tegen adres-spoofing via het antispoof sleutelwoord:
antispoof [log] [quick] for interface [af]
Voorbeeld:
antispoof for fxp0 inet
Wanneer een regelset geladen wordt, zal het voorkomen van het antispoof sleutelwoord ontvouwen worden in twee filterregels. In de veronderstelling dat interface fxp0 IP adres 10.0.0.1 heeft en een subnet mask van 255.255.255.0 (dus een /24), zou de bovenstaande antispoof regel ontvouwen tot:
block in on ! fxp0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.1 to any
Deze regels bereiken twee dingen:
OPMERKING: De filterregels waarin de antispoof regel zich ontvouwt, zullen ook pakketten blokkeren die over de loopback interface naar lokale adressen verzonden worden. De beste gewoonte is om het filteren over te slaan op loopback interfaces, dit wordt echter een noodzaak bij gebruik van antispoof regels:
set skip on lo0
antispoof for fxp0 inet
Gebruik van antispoof wordt best beperkt tot interfaces waaraan een IP adres is toegekend. Gebruik van antispoof op een interface zonder IP adres zal leiden tot filterregels als:
block drop in on ! fxp0 inet all
block drop in inet all
Met deze regels is er een risico om alle ingaand verkeer op alle interfaces te blokkeren.
Beginnend met OpenBSD 4.0, biedt PF een Unicast Reverse Path Forwarding (uRPF) functionaliteit. Wanneer een pakket doorheen de uRPF controle gehaald wordt, wordt het bron IP adres van het pakket opgezocht in de routeringstabel. Als de uitgaande interface die gevonden werd in de routeringstabel dezelfde is als de interface waarop het pakket net binnenkwam, dan slaagt de uRPF controle. Als de interfaces niet overeenstemmen, dan is het mogelijk dat het bronadres van het pakket "gespoofed" werd.
De uRPF controle kan op pakketten uitgevoerd worden door het urpf-failed sleutelwoord te gebruiken in filterregels:
block in quick from urpf-failed label uRPF
Merk op dat de uRPF controle alleen steek houdt in een omgeving waar routering symmetrisch is.
uRPF biedt dezelfde functionaliteit als antispoof regels.
Passive OS Fingerprinting (OSFP) is een methode om passief het besturingssysteem van een remote host te detecteren op basis van bepaalde karakteristieken binnen de TCP SYN pakketten van die host. Deze informatie kan vervolgens gebruikt worden als criteria binnen filterregels.
PF bepaalt het remote besturingssysteem door karakteristieken van een TCP SYN pakket te vergelijken met het fingerprints bestand, dat standaard /etc/pf.os is. Zodra PF ingeschakeld wordt, kan de huidige fingerprint lijst bekeken worden met dit commando:
# pfctl -s osfp
Binnen een filterregel kan een fingerprint gespecificeerd worden per OS klasse, versie, of subtype/patchniveau. Elk van deze items wordt opgesomd in de uitvoer van het hierboven getoonde pfctl commando. Om een fingerprint te specificeren in een filterregel, wordt het os sleutelwoord gebruikt:
pass in on $ext_if from any os OpenBSD keep state
block in on $ext_if from any os "Windows 2000"
block in on $ext_if from any os "Linux 2.4 ts"
block in on $ext_if from any os unknown
De speciale besturingssysteemklasse unknown laat toe pakketten te laten overeenstemmen wanneer de OS fingerprint niet gekend is.
NOTEER het volgende:
pass in quick on fxp0 all allow-opts
ext_if = "fxp0"
int_if = "dc0"
lan_net = "192.168.0.0/24"
# tabel die alle IP adressen bevat die toegekend zijn aan de firewall
table <firewall> const { self }
# filter niet op de loopback interface
set skip on lo0
# schrob binnenkomende pakketen
scrub in all
# stel een standaard weigeren beleid in
block all
# activeer spoofing-bescherming voor alle interfaces
block in quick from urpf-failed
# laat alleen ssh verbindingen toe vanaf het lokale netwerk als het vanaf de
# vertrouwde computer, 192.168.0.15, komt. gebruik "block return" zodat een
# TCP RST verzonden wordt om geblokkeerde verbindingen meteen te sluiten.
# gebruik "quick" zodat deze regel niet opgeheven wordt door de "pass" regels
# hieronder.
block return in quick on $int_if proto tcp from ! 192.168.0.15 \
to $int_if port ssh
# laat alle verkeer naar en vanuit het lokale netwerk door.
# deze regels zullen state entries aanmaken dankzij de standaard
# "keep state" optie die automatisch wordt toegepast.
pass in on $int_if from $lan_net to any
pass out on $int_if from any to $lan_net
# laat tcp, udp en icmp naar buiten op de externe (Internet) interface.
pass out on $ext_if proto { tcp udp icmp } all modulate state
# laat ssh verbindingen binnen op de externe interface zolang ze NIET
# bestemd zijn voor de firewall (ze zijn dus bestemd voor een machine in
# het lokale netwerk). log het initiële pakket zodat we later kunnen
# zeggen wie er probeert te verbinden. gebruik de tcp syn proxy om de
# verbinding te proxy'en.
# de standaard vlaggen "S/SA" worden door PF automatisch toegepast op de
# regel.
pass in log on $ext_if proto tcp from any to ! <firewall> \
port ssh synproxy state
|
[Vorige: Tabellen] [Inhoud] [Volgende: Network Address Translation]