[OpenBSD]

[Zurück: Tabellen] [Inhalt] [Weiter: Network Address Translation]

PF: Pakete filtern


Inhaltsverzeichnis


Einführung

Mit dem Filtern von Paketen ist das selekte Durchlassen oder Blocken von Datenpaketen gemeint, sobald sie durch das Netzwerkinterface gehen. Die Kriterien, die pf(4) verwendet, wenn Pakete untersucht werden, basieren auf den Layer-3- (IPv4 und IPv6) und Layer-4- (TCP, UDP, ICMP und ICMPv6) Headern. Die meistgenutzten Kriterien sind Quell- und Zieladressen sowie Zielport und das Protokoll.

Filterregeln geben sowohl die Kriterien an, auf die ein Paket zutreffen muss, als auch die resultierende Handlung (blocken oder durchlassen), die durchgeführt wird, wenn eine Übereintreffung gefunden wird. Filterregeln werden in sequenzieller Reihenfolge verarbeitet: von der ersten bis zur letzten. Solange das Paket nicht auf eine Regel trifft, die das quick-Schlüsselwort beinhaltet, werden alle Filterregeln überprüft, bevor die schlussendliche Aktion durchgeführt wird. Die letzte Regel, die zutrifft, ist der Gewinner und wird die Aktion angeben, die auf das Paket angewandt wird. Es gibt ein impliziertes pass all am Anfang des Filterregelsatzes, das bedeutet, dass falls ein Paket auf keine Filterregel zutrifft, die resultierende Aktion pass sein wird.

Regelsyntax

Die generelle höchstgradig vereinfachte Syntax für Filterregeln ist:
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]
action
Die Aktion, die für zutreffende Pakete angewandt werden soll: pass oder block. Die pass-Aktion wird das Paket zurück zum Kernel für weitere Verarbeitung lassen, während die block-Aktion je nach der block-policy-Option anders reagieren wird. Die standardmäßige Reaktion kann entweder durch Angabe von block drop oder block return verändert werden.
direction
Die Richtung, in die das Paket sich bewegt: rein (in) oder raus (out).
log
Gibt an, dass das Paket per pflogd(8) aufgezeichnet werden soll. Wenn die Regel zustandsbezogen ist, dann wird nur das Paket aufgezeichnet, das den Status aufgebaut hat. Um alle Pakete unabhängig davon aufzuzeichnen, verwende log (all).
quick
Wenn ein Paket auf eine Regel zutrifft, die quick angibt, dann wird die Regel als letzte zutreffende Regel angesehen, wodurch sie die Aktion (action) angibt, die durchgeführt werden soll.
interface
Der Name eines Netzwerkinterfaces (bzw. die Gruppe von Netzwerkinterfaces) durch das sich das Paket bewegt. Interfaces können mit dem ifconfig(8)-Kommando zu beliebigen Gruppen hinzugefügt werden. Einige Gruppen werden automatisch vom Kernel erstellt: Dies wird dazu führen, dass die Regel für jedes Paket zutrifft, das das ppp- oder carp-Interface durchläuft - je nachdem.
af
Die Adressfamilie des Pakets: inet für IPv4 oder inet6 für IPv6. PF ist normalerweise in der Lage, anhand der Parameter für die Quell- und/oder Zieladresse(n) das selbst zu erkennen.
protocol
Die Layer-4-Protokolle des Pakets:
src_addr, dst_addr
Die Quell/Zieladresse im IP-Header. Adressen können wie folgt angegeben werden:
src_port, dst_port
Der Quell/Ziel-Port in dem Layer-4-Paket-Header. Ports können wie folgt angegeben werden:
tcp_flags
Gibt die Flags an, die in dem TCP-Header gesetzt sein müssen, wenn proto tcp verwendet wird. Flags werden als flags check/mask angegeben. flags S/SA zum Beispiel dies sagt PF, dass nur auf die S- und A- (SYN und ACK) Flags geachtet werden und zutreffen soll, wenn nur das SYN-Flag aktiviert ist. In OpenBSD 4.1 und späteren Versionen werden die Standardflags S/SA an alle TCP-Filterregeln übergeben.
state
Gibt an, ob die Statusinformation für das Paket gehalten werden soll, das auf diese Regel zutrifft.

Standardmäßiges Blocken

Die empfohlene Praxis, wenn eine Firewall aufgesetzt wird ist, einen »standardmäßig block«-Weg einzuschlagen. Dies bedeutet, dass alles geblockt und dann selektiv bestimmter Verkehr durch die Firewall gelassen wird. Dieser Weg ist empfohlen, da man trotz entstehender Fehler auf der sicheren Seite ist und das Schreiben eines Regelsatzes einfacher wird.

Um eine »standardmäßig block«-Richtlinie zu erstellen, sollten die ersten beiden Filterregeln wie folgt sein:

block in  all
block out all

Dies wird den gesamten Verkehr auf allen Interfaces blocken - egal in welche Richtung und von wo nach wo.

Verkehr durchlassen

Verkehr muss nun explizit durch die Firewall gelassen werden oder er wird wegen der »standardmäßig blocken«-Richtlinie fallen gelassen. Nun kommen Paketkriterien wie Quell/Zielports, Quell/Zieladressen und das Protokoll ins Spiel. Wann auch immer Verkehr durch die Firewall gelassen wird, sollte(n) die Regel(n) so restriktiv wie möglich geschrieben werden. Dies stellt sicher, dass der beabsichtigte Verkehr - und zwar nur der beabsichtigte Verkehr - durchgelassen wird.

Einige Beispiele:

# Lasse den Verkehr auf dc0 vom lokalen Netzwerk 192.168.0.0/24
# zur OpenBSD-Maschine mit der IP-Adresse 192.168.0.1 herein. Lasse
# ebenfalls den Antwort-Verkehr durch dc0 wieder raus.
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


# Lasse TCP-Verkehr auf fxp0 vom Webserver herein, der auf der
# OpenBSD-Maschine läuft. Der Interfacename fxp0 wird als Zieladresse
# verwendet, sodass Pakete mit dieser Regel nur übereinstimmen, wenn
# sie für die OpenBSD-Maschine gedacht sind.
pass in on fxp0 proto tcp from any to fxp0 port www

Das quick-Schlüsselwort

Wie zuvor angedeutet wurde, wird jedes Paket mit dem gesamten Filterregelsatz von oben nach unten überprüft. Standardmäßig wird das Paket als durchgelassen markiert, was aber von jeglicher Regel geändert werden kann. Das wiederum kann mehrmals wechseln, bevor das Ende der Filterregeln erreicht ist. Die letzte zutreffende Regel gewinnt. Es gibt eine Ausnahme dafür: Die quick-Option einer Filterregel hat zur Folge, dass jegliche Verarbeitung der weiteren Regeln abgebrochen und die angegebene Aktion durchgeführt wird. Lass uns nun einige Beispiele dafür ansehen:

Falsch:

block in on fxp0 proto tcp from any to any port ssh
pass  in all

In diesem Fall wird die block-Zeile zwar verarbeit, aber keinen Effekt haben, da sie von einer Zeile gefolgt wird, die alles durchlässt.

Besser:

block in quick on fxp0 proto tcp from any to any port ssh
pass  in all

Diese Regeln werden auf eine etwas unterschiedliche Weise verarbeitet. Wenn die block-Zeile zutrifft, wird das Paket geblockt und wegen der quick-Option wird der Rest des Regelsatzes ignoriert.

Status halten

Eine der wichtigen Fähigkeiten von Packet Filter ist »keeping state« (bzw. »stateful inspection«. »Stateful inspection« verweist auf PFs Fähigkeit, den Status (oder Fortschritt) auf der Netzwerkverbindung nachweisen zu können. Durch die Aufbewahrung der Informationen über jede Verbindung in einer Statustabelle ist PF in der Lage, schnell herauszufinden, ob ein Paket, das durch die Firewall gelassen wird, zu einer bereits erstellten Verbindung gehört. Wenn es das tut, wird es durch die Firewall gelassen, ohne durch die Regelsätze geschickt zu werden.

Den Status zu halten hat viele Vorteilen, einschließlich einfacherer Regelsätze und besserer Leistung beim Paketfiltern. PF ist in der Lage, Pakete mit den Einträgen in der Statustabelle zu überprüfen, egal in welche Richtung sich das Paket bewegt. Das bedeutet, dass Filterregeln, die den Antwortverkehr hereinlassen, nicht geschrieben werden müssen. Und da Pakete, die mit zustandsabhängigen Verbindungen übereinstimmen, nicht durch die Regelsatzüberprüfung gehen, kann die Zeit, die PF zur Verarbeitung der Pakete benötigt, drastisch verringert werden.

Wenn eine Regel einen Status erstellt, dann wird das erste zutreffende Paket diesen Status zwischen Sender und Empfänger erstellen. Nun werden nicht nur die Pakete ohne Überprüfung durchgelassen, die vom Sender zum Empfänger gehen, sondern auch die Antwortpakete vom Empfänger zum Sender.

Beginnend mit OpenBSD 4.1 erstellen alle Filterregeln automatisch einen Statuseintrag, wenn ein Paket auf eine Regel zutrifft. In früheren OpenBSD-Versionen musste man für die Filterregel explizit die Option keep state angeben.

Beispiel für OpenBSD 4.1 und späteren Versionen:

pass out on fxp0 proto tcp from any to any

Beispiel für OpenBSD 4.0 und ältere Versionen:

pass out on fxp0 proto tcp from any to any keep state

Diese Regeln erlauben jeglichen ausgehenden TCP-Verkehr auf dem fxp0-Interface und lassen ebenfalls Antwortverkehr zu, der zurück durch die Firewall geht. Während das Halten von Zuständen eine schöne Funktionalität ist, kann es die Leistung deiner Firewall signifikant erhöhen, da Zustandsüberprüfungen um ein vielfaches schneller sind als das Paket durch die Filterregeln zu schicken.

Die modulate state-Option funktioniert genauso wie keep state - mit der Ausnahme, dass es nur auf TCP-Pakete zutrifft. Mit modulate state wird die »Initial Sequence Number« (ISN) des ausgehenden Verkehrs zufällig gewählt. Dies ist sinnvoll, um Verbindungen zu schützen, die von bestimmten Betriebssystemen erstellt worden sind, die eine schlechte Leistung beim Wählen von ISNs an den Tag legen. Beginnend mit OpenBSD 3.5 kann die modulate state-Option in Regeln genutzt werden, die andere Protokolle als TCP angeben.

Den Zustand von ausgehenden TCP-, UDP-, und ICMP-Paketen und ,modulate'-TCP-ISNs halten:

pass out on fxp0 proto { tcp, udp, icmp } from any \
    to any modulate state

Ein anderer Vorteil beim Halten von Zuständen ist, dass der dazugehörige ICMP-Verkehr durch die Firewall gelassen wird. Wenn zum Beispiel eine TCP-Verbindung - deren Status überwacht wird - durch die Firewall gelassen wird und eine ICMP-Source-Quench-Nachricht für diese TCP-Verbindung ankommt, wird sie mit dem dazugehörigem Status übereinstimmen und durch die Firewall gelassen.

Der Bereich des Statuseintrags wird systemweit durch die state-policy-Laufzeitoption auf einer regelspezifischen Basis durch die if-bound-, group-bound- und floating-state-Optionsschlüsselwörter kontrolliert. Diese regelspezifischen Schlüsselwörter haben die gleiche Bedeutung als wenn sie mit der state-policy-Option verwendet werden. Beispiel:

pass out on fxp0 proto { tcp, udp, icmp } from any \
    to any modulate state (if-bound)

Diese Regel bestimmt, dass nur Pakete, die durch das Interface fx0 gelangen, mit dem Statuseintrag übereinstimmen können.

Bedenke, dass nat-, binat- und rdr-Regeln implizit einen Status für zutreffende Verbindungen erstellen, solange die Verbindung durch den Filterregelsatz gelassen wird.

,state' für UDP halten

Man wird ab und zu hören, dass jemand sagt: »Man kann keinen Zustand mit UDP erstellen, da UDP ein zustandsloses Protokoll ist!« Obwohl es stimmt, dass UDP-Verbindungssitzungen kein Konzept eines Zustands haben (einen expliziten Anfang und ein explizites Ende), hat dies keine Wirkung auf PFs Fähigkeit, einen Status für eine UDP-Sitzung zu erstellen. In dem Fall von Protokollen ohne Start- und Endpakete, merkt sich PF einfach, wie lange es her ist, dass ein zutreffendes Paket durchgelassen wurde. Wenn der Timeout erreicht wurde, wird der Status gelöscht. Der Timeout-Wert kann in der options-Sektion in der Datei pf.conf gesetzt werden.

Optionen für zustandsabhängiges Tracking

Filterregeln, die einen Statuseintrag erstellen, können mehrere Optionen angeben, um das Verhalten des resultierenden Statuseintrags zu kontrollieren. Die folgenden Optionen sind verfügbar:
max anzahl
Begrenzt die maximale Anzahl Statuseinträge, die die Regel erstellen kann, auf anzahl. Wenn das Maximum erreicht wurde, werden Pakete, die normalerweise einen Status erstellen würden, nicht auf diese Regel zutreffen, bis die Anzahl vorhandener Zustände wieder unterhalb der Obergrenze liegt.
no state
Die Regel wird davon abgehalten, automatisch einen Statuseintrag anzulegen.
source-track
Diese Option aktiviert das Tracking der Anzahl der Zustände, die für jede einzelne IP-Adresse erstellt wurden. Diese Option hat zwei Formate: Die gesamte Anzahl der Quell-IP-Adressen, die verfolgt werden, kann systemweit durch die Verwendung der src-nodes-Laufzeitoption kontrolliert werden.
max-src-nodes anzahl
Wenn die source-track-Option genutzt wird, wird max-src-nodes die Anzahl der Quell-IP-Adressen begrenzen, die gleichzeitig einen Status anlegen können. Diese Option kann nur zusammen mit source-track rule genutzt werden.
max-src-states anzahl
Wenn die source-track-Option verwendet wird, wird max-src-states die Anzahl gleichzeitig erstellter Statuseinträge begrenzen, die pro Quell-IP-Adresse angelegt werden können. Der Bereich dieser Begrenzung (z. B. Zustände, die nur durch diese Regel erstellt wurden, oder die durch alle Regeln unter Verwendung von source-track erstellt wurden) ist abhängig von der angegebenen source-track-Option.

Optionen werden in Klammern und direkt nach einem der Statusschlüsselwörter (keep state, modulate state oder synproxy state) angegeben. Mehrere Optionen werden mit Kommas getrennt. In OpenBSD 4.1 und späteren Versionen ist die Option keep state implizierter Standard für alle Filterregeln. Trotzdem muss bei der Angabe von Statusoptionen eines dieser Statusschlüsselwörter vor der Option stehen.

Eine Beispielregel:

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)

Die oben angegebene Regel sorgt für folgendes Verhalten:

Ein separater Satz von Begrenzungen kann auf zustandsabhängigen TCP-Verbindungen gesetzt werden, die den dreifachen Handschlag vollzogen haben.

max-src-conn Nummer
Begrenzt die maximale Anzahl gleichzeitiger TCP-Verbindungen, die den dreifachen Handschlag vollzogen haben, die ein einzelner Host erstellen kann.
max-src-conn-rate Nummer / Intervall
Begrenzt die Rate der neuen Verbindungen, die zu einem bestimmten Zeitintervall aufgebaut werden können.

Beide Optionen beziehen automatisch die source-track rule-Option mit ein und sind inkompatibel zu source-track global.

Da diese Begrenzungen nur für TCP-Verbindungen gültig sind, die den dreifachen Handschlag vollzogen haben, können aggressivere Aktionen gegen die offensiven IP-Adressen durchgeführt werden.

overload <Tabelle>
Schreibt den IP-Adresse des offensiven Hosts in die benannte Tabelle.
flush [global]
Zerstöre alle anderen ,states', die auf diese Regel zutreffen und die von dieser Quell-IP stammen. Wenn global angegeben wird, zerstöre alle ,states', die auf diese Quell-IP zutreffen, unabhängig davon, welche Regel diesen ,state' erzeugt hat.

Ein Beispiel:

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)

Dies macht Folgendes:

TCP-Flags

TCP-Pakete anhand ihrer Flags zu überprüfen wird meistens verwendet, um TCP-Pakete zu filtern, die versuchen, eine neue Verbindung zu eröffnen. Die TCP-Flags und ihre Bedeutungen sind hier aufgeführt:

Damit PF die TCP-Flags während der Überprüfung einer Regel inspiziert, muss das flags-Schlüsselwort mit folgender Syntax verwendet werden:

flags check/mask
flags any

Der mask-Teil teilt PF mit, nur die angegebenen Flags zu inspizieren und der check-Teil gibt an, welche(r) Flag(s) im Header aktiviert sein müssen, damit eine Übereinstimmung stattfinden kann. Das Schlüsselwort any ermöglicht jede erdenkliche Kombination der zu setzenden Optionen im Header.

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

Die hier angegebene Regel lässt TCP-Verkehr mit gesetztem SYN-Flag durch, während nur die SYN- und ACK-Flags überprüft werden. Ein Paket mit den SYN- und ECE-Flags würde der oben genannten Regel entsprechen, während ein Paket mit SYN und ACK oder nur ACK keine Übereinstimmung hätte.

In OpenBSD 4.1 und späteren Versionen wird standardmäßig flags S/SA für TCP-Regeln verwendet. Zusammen mit dem OpenBSD-4.1-Standard keep state für Filterregeln sind diese beiden Regeln gleichwertig:

pass out on fxp0 proto tcp all flags S/SA keep state
pass out on fxp0 proto tcp all

Jede Regel wird auf TCP-Pakete reagieren, deren SYN-Flag gesetzt und ACK-Flag nicht gesetzt ist, und einen Statuseintrag für die zutreffenden Pakete anlegen. Die Standardflags können mit der Option flags wie oben erläutert überschrieben werden.

In OpenBSD 4.0 und älteren Versionen wurden keine Standardflags für Filterregeln angegeben. Jede Regel musste daher zu überprüfende Flag(s) übergeben bekommen und explizit die Option keep state gesetzt haben.

pass out on fxp0 proto tcp all flags S/SA keep state

Man sollte vorsichtig bei der Verwendung mit Flags sein - zu verstehen, was du warum tust, und vorsichtig mit den Ratschlägen von Leuten zu sein, die häufig schlechte geben. Einige Leute empfehlen das Erstellen von ,states', "nur, wenn das SYN-Flag gesetzt ist und kein anderes". Solch eine Regel würde wie folgt enden: . . . flags S/FSRPAUEW bad idea!!

Die Theorie dahinter ist, dass nur am Anfang der TCP-Sitzung ein ,state' erzeugt wird und die Sitzung nur mit einem SYN-Flag starten sollte, keinem anderen. Das Problem ist, dass einige Seiten anfangen, das ECN-Flag zu verwenden und jegliche Seite, die ECN verwendet und versucht, sich zu dir zu verbinden, bei einer solchen Regel abgeblockt werden würde. Eine bessere Möglichkeit ist es, überhaupt keine Flags anzugeben und PF die Standardflags für deine Regeln übernehmen lassen. Wenn du wirklich unbedingt selbst Flags angeben musst, dann sollte diese Option sicher sein:

. . . flags S/SAFR

Während dies praktisch und sicher ist, ist das Überprüfen für die FIN- und RST-Flags unnötig, wenn der Verkehr ebenfalls ge,scrubbed' wird. Der ,scrubbing'-Prozess wird PF veranlassen, jegliche eingehenden Pakete mit ungültigen TCP-Flag-Kombinationen (wie zum Beispiel SYN und RST) fallen zu lassen und potenziell unklare Kombinationen (z. B. SYN und FIN) zu normalisieren.

TCP-SYN-Proxy

Wenn ein Client normalerweise eine TCP-Verbindung zu einem Server aufbaut, wird PF die Handschlag-Pakete zwischen den beiden Endpunkten durchlassen, sobald sie ankommen. PF hat jedoch die Fähigkeit, den Handschlag durch einen Proxy zu senden. Mit einem Handschlag, der durch einen Proxy gesendet wurde, wird PF selbst den Handschlag mit dem Client absolvieren, einen Handschlag mit dem Server beginnen und dann die Pakete zwischen den beiden durchlassen. Der Vorteil von diesem Prozess ist, dass keine Pakete zum Server gesendet werden, bevor der Client den Handschlag abgeschlossen hat. Dies eliminiert die Gefahr eines ,spoofed' TCP-SYN-Floods, die den Server beeinträchtigen könnten, weil die ,spoofed' Client-Verbindung nicht in der Lage ist, den Handschlag zu vollenden.

Der TCP-SYN-Proxy wird durch die Verwendung der synproxy state-Schlüsselworte in den Filterregeln aktiviert. Beispiel:

pass in on $ext_if proto tcp from any to $web_server port www \
   flags S/SA synproxy state

Hier werden die Verbindungen zum Webserver durch den TCP-Proxy von PF gesendet.

Wegen der Funktionsweise von synproxy state beinhaltet es die gleiche Funktionalität wie keep state und modulate state.

Der SYN-Proxy wird nicht mit PF funktionieren, wenn dieser auf einer bridge(4) läuft.

,spoofed' Pakete blocken

Adress-,spoofing' liegt vor, wenn ein böswilliger Benutzer die Quell-IP-Adresse in den Paketen ändert, die versendet werden, um entweder seine tatsächliche Adresse zu verbergen oder um so zu wirken, als würde er ein anderes Gerät im Netzwerk bedienen. Sobald ein Benutzer eine ,spoofed' Adresse hat, kann er Netzwerkattacken durchführen, ohne seine wahre Herkunft offenzulegen, oder erreicht Zugriff auf Netzwerkdienste, die nur bestimmten IP-Adressen ermöglicht werden sollen.

PF bietet einen gewissen Schutz gegen Adress-,spoofing' durch das antispoof-Schlüsselwort:

antispoof [log] [quick] for interface [af]
log
Gibt ab, ob das zutreffende Paket via pflogd(8) aufgezeichnet werden soll.
quick
Wenn ein Paket auf diese Zeile zutrifft, wird es als ,Gewinner'-Regel angesehen und die Verarbeitung des Regelsatzes angehalten.
interface
Das Netzwerk-Interface, auf dem ,spoofing'-Schutz aktiviert werden soll. Dies kann ebenfalls eine Liste von Interfaces sein.
af
Die Adress-Familie, für die der ,spoofing'-Schutz aktiviert werden soll, entweder inet für IPv4 oder inet6 für IPv6.

Beispiel:

antispoof for fxp0 inet

Wenn ein Regelsatz geladen wird, wird jedes Vorkommen des antispoof-Schlüsselwortes in zwei Filterregeln eingesetzt. Angenommen, dass das Interface fxp0 die IP-Adresse 10.0.0.1 und eine Subnetz-Maske von 255.255.255.0 hat (z. B. /24), dann würde die oben angegebene antispoof-Regel wie folgt entwickelt werden:

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

Diese Regeln erreichen zwei Dinge:

HINWEIS. Die Filterregeln, die aus der antispoof-Regel hervorgehen, blocken ebenfalls Pakete, die über das Loopback-Interface zur lokalen Adresse gesendet werden. Es ist sowieso ein guter Stil, wenn man auf Loopbackinterfaces nicht filtert - doch bei der Verwendung von antispoof-Regeln ist das eine Notwendigkeit:

set skip on lo0 all

antispoof for fxp0 inet

Die Verwendung von antispoof sollte auf Interfaces beschränkt werden, denen eine IP-Adresse zugewiesen wurde. Wenn antispoof auf ein Interface angewandt wird, das keine IP-Adresse hat, wird das in Filterregeln enden, die so ähnlich wie folgende aussehen werden:

block drop in on ! fxp0 inet all
block drop in inet all

Mit diesen Regeln besteht die Gefahr, dass der gesamte eingehende Verkehr auf allen Interfaces geblockt wird.

Unicast Reverse Path Forwarding

Beginnend mit OpenBSD 4.0 bietet PF »Unicast Reverse Path Forwarding« (uRPF) an. Wenn ein Paket durch eine uRPF-Routine überprüft wird, so wird die Quell-IP-Adresse des Pakets in der Routingtabelle nachgesehen. Wenn das weiterführende Interface das gleiche ist, über das das Paket hereingekommen ist, so wird die uRPF-Überprüfung das Paket durchlassen. Sollten sich die Interfaces unterscheiden, so kann es sich um eine gefälschte Quelladresse handeln.

Die uRPF-Überprüfung für Pakete kann mit dem urpf-failed-Schlüsselwort in den Filterregelsätzen aktiviert werden:

block in quick from urpf-failed label uRPF

Denk daran, dass die uRPF-Überprüfung nur in Umgebungen Sinn macht, in denen das Routing symmetrisch abläuft.

uRPF bietet die gleiche Funktionalität wie Antispoof-Regeln.

Passives Betriebssystem-,Fingerprinting'

Passives OS-,Fingerprinting' (OSFP) ist eine Methode zum passiven Ermitteln des Betriebssystems auf dem gegenüberliegendem Host, basierend auf bestimmten Kriterien in den TCP-SYN-Paketen des Hosts. Diese Information kann dann als Kriterium in Filterregeln verwendet werden.

PF ermittelt das entfernte Betriebssystem, indem die Charakteristiken des TCP-SYN-Pakets mit denen in der ,fingerprints'-Datei verglichen werden, welche standardmäßig /etc/pf.os ist. Sobald PF aktiviert wurde, kann die aktuelle ,fingerprint'-Liste mit diesem Kommando angesehen werden:

# pfctl -s osfp

Innerhalb der Filterregel kann ein ,fingerprint' anhand der OS-Klasse, -Version oder -Untertyp/-Patchlevel angegeben werden. Jedes dieser Objekte wird in der Ausgabe des angegebenen pfctl-Kommandos aufgelistet. Um einen ,fingerprint' in einer Filterregel anzugeben, wird das os-Schlüsselwort verwendet:

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

Die spezielle Betriebssystem-Klasse unknown erlaubt es, dass alle Pakete zutreffen, wenn der ,fingerprint' des OS unbekannt ist.

Folendes sollte ZUR KENNTNIS GENOMMEN WERDEN:

IP-Optionen

Standardmäßig blockt PF alle Pakete, die IP-Optionen haben. Dies kann die Arbeit für ,OS fingerprinting'-Anwendungen wie nmap erschweren. Wenn du eine Applikation hast, die das Durchlassen dieser Pakete erfordert, wie zum Beispiel Multicast oder IGMP, kannst du die allow-opts-Direktive verwenden:
pass in quick on fxp0 all allow-opts

Beispiel-Filterregelsatz

Weiter unten ist ein Beispiel für einen Filterregelsatz. Auf der Maschine läuft PF, die als Firewall zwischen einem kleinen, internen Netzwerk und dem Internet fungiert. Nur die Filterregeln werden angezeigt; queueing, nat, rdr etc. wurden aus diesem Beispiel herausgelassen.

ext_if = "fxp0" int_if = "dc0" lan_net = "192.168.0.0/24" # tabelle, die alle IP-Adressen beinhaltet, die der firewall zugewiesen # worden sind table <firewall> const { self } # filtere nicht das loopback-interface set skip on lo0 # ,scrub' auf alle eingehenden pakete anwenden scrub in all # eine richtlinie zum standardmäßigen blocken errichten block all # ,spoofing'-schutz für alle interfaces. block in quick from urpf-failed # nur ssh-verbindungen vom lokalen netzwerk erlauben, wenn es von dem # computer 192.168.0.15 kommt, dem man vertrauen kann. verwende # ,block return', sodass ein TCP-RST gesendet wird, um blockierte # Verbindungen sofort zu schließen. verwende ,quick', sodass diese # regel nicht von der ,pass'-regel weiter unten überschrieben wird. block return in quick on $int_if proto tcp from ! 192.168.0.15 \ to $int_if port ssh # den gesamten verkehr von und zum lokalen netzwerk durchlassen. # diese regeln werden statuseinträge erstellen, da die standardoption # "keep state" automatisch übernommen wird. pass in on $int_if from $lan_net to any pass out on $int_if from any to $lan_net # tcp, udp und icmp durch das externe (internet-)interface rauslassen. # tcp-verbindungen werden reguliert, udp/icmp-verbindungen werden # statusüberwacht. pass out on $ext_if proto { tcp udp icmp } all modulate state # erlaube eingehende ssh-verbindungen auf dem externen interface, so # lange sie NICHT für die firewall bestimmt sind (z. B. wenn sie an # eine maschine im lokalen netzwerk gerichtet sind). zeichne das erste # paket auf, sodass wir später sagen können, wer versucht, zu verbinden. # verwende den tcp-syn-proxy um einen proxy für diese verbindung # aufzubauen. die standardflags "S/SA" werden dieser regel automatisch # von PF übergeben. pass in log on $ext_if proto tcp from any to ! <firewall> \ port ssh synproxy state

[Zurück: Tabellen] [Inhalt] [Weiter: Network Address Translation]


[zurück] www@openbsd.org
$OpenBSD: filter.html,v 1.30 2008/01/13 13:43:34 tobias Exp $