Geschrieben wurde IPFILTER von Darren Reed. IPFILTER ist vom Betriebssystem unabhängig: Es ist eine Open Source Anwendung, die auf die Betriebssysteme FreeBSD, NetBSD, OpenBSD, SunOS™, HP/UX und Solaris™ portiert wurde. IPFILTER wird aktiv betreut und gepflegt. Es werden regelmäßig neue Versionen herausgegeben.
IPFILTER basiert auf einer kernelseitigen Firewall und einem NAT Mechanismus, der durch Anwenderprogramme betreut und gesteuert werden kann. Die Regeln der Firewall werden mit dem Programm ipf(8) gesetzt oder gelöscht. Für die Manipulation der NAT Regeln verwendet man ipnat(1). Mit ipfstat(8) werden Laufzeitstatistiken der kernelseitigen Anteile von IPFILTER aufgelistet. Und mit dem Programm ipmon(8) kann man die Aktionen von IPFILTER in die Protokolldateien des Systems speichern.
IPF funktionierte ursprünglich mit einer
Regel-Prozess-Logik à la „die letzte Regel, die
passt, entscheidet“ und verwendete ausschließlich
Regeln ohne feste Zustände. Inzwischen wurde die
Regel-Prozess-Logik drastisch modernisiert: Es gibt eine
quick
und eine zustandsorientierte
keep-state
Option. Die offizielle Dokumentation beinhaltet
leider nur die veralteten Parameter zur Regelerstellung - die neuen
Funktionen werden nur als Zusatzoptionen aufgelistet, was ihre
Vorteile beim Erstellen einer weit überlegenen und viel
sichereren Firewall völlig untergräbt.
Die Anweisungen in diesem Kapitel basieren darauf, Regeln mit
den Optionen quick
und keep-state
zu erstellen. Mit diesem Grundwissen wird man einen kompletten
einschließenden Regelsatz erstellen können.
Für eine ausführliche Erläuterung der alten Methode zur Regelverarbeitung schauen Sie bitte auf http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1 oder http://coombs.anu.edu.au/~avalon/ip-filter.html.
Antworten auf häufige Fragen finden Sie unter http://www.phildev.net/ipf/index.html.
Und ein durchsuchbares Archiv der Mailingliste zu IPFILTER gibt es unter http://marc.theaimsgroup.com/?l=ipfilter.
FreeBSD enthält IPF in der Standardversion als ladbares
Kernelmodul. Dieses Modul wird vom System automatisch geladen,
wenn in der rc.conf
der Eintrag
ipfilter_enable="YES"
angelegt wird. In dieser
ursprünglichen Konfiguration ist die Protokollierung aktiv
und die Option default pass all
("Pakete passieren
lassen") als Standard gesetzt. Um die block all
("alles Blockieren") Option zu setzen, muss man nicht gleich
einen neuen Kernel bauen - es reicht, block all
als letzte Position des Regelsatzes aufzulisten.
Es ist nicht unbedingt notwendig, IPF durch die folgenden Optionen direkt in der Kernel einzubinden. Diese Möglichkeit der Verwendung von IPF wird hier mehr als Hintergrundwissen angeboten. Man sollte nur wissen, dass dadurch nicht mehr das Kernelmodul geladen wird - und dementsprechend auch nicht mehr entladen werden kann.
Die Beschreibung der einzelnen Optionen von IPF für die
Verwendung in der Kernelkonfiguration finden Sie auch in der Datei
/usr/src/sys/conf/NOTES
.
options IPFILTER
aktiviert die Verwendung
der „IPFILTER“ Firewall.
options IPFILTER_LOG
aktiviert den
Logging-Mechanismus. Das bedeutet, dass jedes Paket geloggt wird,
auf das eine Regel passt, die das Schlüsselwort
log
enthält. Dazu wird der
Pseudo—Device ipl
verwendet.
options IPFILTER_DEFAULT_BLOCK
ändert
das Verhalten der Firewall dahingehend, dass jedes Paket, dass nicht
explizit von einer pass
Regel Zugang erhält,
abgewiesen, bzw. geblockt, wird.
Diese Einstellungen werden erst aktiv, wenn der Kernel, in den sie eingebunden wurden, kompiliert, installiert und gebootet wurde.
Um IPF während des Bootvorgangs einzubinden, braucht man
lediglich die folgenden Zeilen der Datei
/etc/rc.conf
anzufügen:
Falls sich hinter der Firewall ein lokales Netzwerk befindet,
das den reservierten privaten Adressbereich verwendet, müssen
die folgenden Zeilen zur Aktivierung von NAT
ebenfalls in /etc/rc.conf
eingetragen
werden:
Mit dem Befehl ipf(8) liest man die Datei, die den Regelsatz enthält ein. Mit dem folgenden Befehl können Sie Ihre eigenen, für Ihr System maßgeschneiderten Regeln einlesen und so in einem Schritt alle Regeln der laufenden Firewall ersetzen:
#
ipf -Fa -f /etc/ipf.rules
-Fa
bedeutet, dass alle intern gespeicherten
Tabellen mit Regeln gelöscht werden.
-f
gibt die Datei an, aus der die neuen Regeln
gelesen werden sollen.
Mit diesen beiden Optionen erhalten Sie die Möglichkeit, Änderungen an der Datei mit Ihrem Regelsatz vorzunehmen und gleich die Firewall mit den neuen Regeln zu bestücken, ohne den Rechner neu starten zu müssen. Da dieser Vorgang beliebig wiederholt werden kann, ist es ein sehr bequemer Weg, neue Regeln einzuarbeiten und zu testen.
Um mehr über diese und weitere Optionen von ipf(8) zu erfahren, konsultieren Sie bitte die Manpage.
ipf(8) erwartet, dass es sich bei der Datei mit dem Regelsatz um eine Standard-Textdatei handelt. Eine Datei, die ein Skript oder Variablen enthält, wird nicht verarbeitet.
Es gibt allerdings doch einen Weg, IPF Regeln mit Hilfe von Skripten und Variablen zu erstellen. Weitere Informationen dazu finden Sie unter Abschnitt 31.5.9, „Die Erstellung eines Regelsatzes mit Variablen“.
Das normale Verhalten von ipfstat(8) ist, die Zusammenfassung
der angefallenen Statistiken, die als Resultat der Anwendung von
nutzerspezifischen Regeln auf ein- und ausgehende Pakete seit dem
letzten Start der Firewall oder seit dem letzten Zurücksetzen
der Zähler auf Null durch das Kommando
ipf -Z
angesammelt wurden, abzurufen und
anzuzeigen.
Für weiterführende Informationen schauen Sie bitte auf die Manpage von ipfstat(8)!
Die Ausgabe von ipfstat(8), wenn keine Parameter übergeben wurden, sieht etwa so aus:
Wenn die Option -i
für
„eingehend“ oder -o
für
„ausgehend“ übergeben wird, liefert das Kommando
eine entsprechende Liste von Filter-Regeln, die gerade installiert
sind und vom Kernel verwendet werden.
ipfstat -in
zeigt alle aktive Regeln
für eingehende Verbindungen zusammen mit ihren Nummern.
ipfstat -on
erledigt dasselbe für die
ausgehenden Verbindungen.
Die Ausgabe sieht in etwa folgendermaßen aus:
ipfstat -ih
zeigt die Tabelle der aktiven
Regeln für eingehende Verbindungen zusammen mit der Anzahl,
wie oft jeder einzelnen Regel entsprochen wurde.
ipfstat -oh
zeigt das Gleiche für
die ausgehenden Verbindungen.
Hier wird die Ausgabe so oder so ähnlich aussehen:
Einer der wichtigsten Funktionen von ipfstat
wird über die Option -t
bereitgestellt. Mit
ihr wird eine Statustabelle vergleichbar der Prozess-Tabelle
von top(1) ausgegeben. Mit dieser Funktion erhalten Sie im
Falle eines Angriffs die Möglichkeit, die angreifenden Pakete
zu identifizieren, abzufangen und auszuwerten. Weitere Unteroptionen
eröffnen, die IP-Adresse, den Port oder das Protokoll, geteilt
nach Herkunft und Ziel, auszuwählen und dann in Echtzeit zu
beobachten. Lesen Sie dazu bitte auch die Manpage von
ipfstat(8).
Damit der Befehl ipmon
korrekt arbeiten kann,
muss die Option IPFILTER_LOG
in die
Kernelkonfiguration eingearbeitet werden. Das Kommando selbst
arbeitet in zwei verschiedenen Modi. Für den nativen Modus
startet man ipmon
auf der Kommandozeile ohne die
Option -D
.
Der Hintergrundmodus (daemon mode
) dient der
Erstellung eines stetigen Systemprotokolls, so dass Einträge
vergangener Ereignisse inspiziert werden können. So sollen FreeBSD
und IPFILTER entsprechend ihrer Konfiguration zusammen arbeiten.
FreeBSD kann mit einem eingebauten Mechanismus Systemprotokolle
turnusmäßig abspeichern. Aus diesem Grund sollte man
besser syslogd(8) verwenden anstatt die Protokollinformationen
in eine Datei zu schreiben, wie es als Standard vorgesehen ist. In
der Standard-rc.conf
-Datei (im Ordner
/etc/defaults/
) wird dem Eintrag
ipmon_flags
die Option -Ds
übergeben:
Die Vorteile des Protokollierens liegen auf der Hand: Sie versetzen den Administrator in die Lage, nach einem Vorfall Informationen abzurufen, etwa welche Pakete aussortiert wurden, welche Adressen diese Pakete gesendet haben oder wohin sie gesendet werden sollten. Alles in allem erhält er ein sehr gutes Werkzeug zum Aufspüren von Angreifern.
Jedoch, auch wenn die Protokollierung aktiviert ist, wird IPF
keine einzige Regel zum Protokollieren von alleine entwerfen und
umsetzen. Der Administrator der Firewall entscheidet, welche Regeln
in seinem Regelsatz mitgeschrieben werden sollen und er muss
dementsprechend das Schlüsselword log
in
dieser Regel angeben. Normalerweise werden nur Treffer auf abweisende
Regeln protokolliert.
Es ist üblich, als letzte Regel eine alles blockierende
Regel mit dem Schlüsselwort log
in den
Regelsatz einzutragen. Dadurch erkennt man alle Pakete, die keiner
Regel im Regelsatz entsprachen.
Syslogd verwendet seine eigene Methode
zum Sortieren der gesammtelten Protokolldaten - spezielle Gruppierungen
namens „facility“ und „level“. IPMON
verwendet im daemon
-Modus als
„facility“ den Wert security
. Die
folgenden „level“ können für eine genauere
Trennung der Protokolldaten verwendet werden:
Damit IPFILTER angewiesen werden kann, alle Protokolldaten in
die Datei /var/log/ipfilter.log
zu schreiben,
muss diese erst erstellt werden. Folgendes Kommando
übernimmt diese Aufgabe:
#
touch /var/log/ipfilter.log
Die Funktionen von syslogd(8) werden durch Definition in
der Datei /etc/syslog.conf
gesteuert. In dieser
Datei kann sehr weitläfig eingestellt werden, wie
syslog mit den Systemnachrichten umgehen
soll, die ihm von Anwendungen wie IPF übergeben werden.
Fügen Sie folgende Definition in die Datei
/etc/syslog.conf
ein, um die Protokollierung
für IPF via syslog
zu aktivieren:
security.*
bedeutet, dass alle Nachrichten
der Klasse security.*
am angegebenen Ort (hier
eine Datei) geschrieben werden sollen.
Um Änderungen an der Datei
/etc/syslog.conf
zu aktivieren müssen Sie
den Rechner neu starten, oder den Befehl
#
/etc/rc.d/syslogd reload
ausführen.
Vergessen Sie nicht, /etc/newsyslog.conf
anzupassen, damit die neuen Protokolldateien, die eben konfiguriert
wurden, auch in den Rotationsturnus eingefügt werden!
Nachrichten, die durch ipmon
erzeugt werden,
bestehen aus durch Leerstellen getrennten Datenfeldern. Folgende
Felder sind in allen Nachrichten enthalten:
Das Datum der Paketerstellung.
Die Uhrzeit der Paketerstellung in der Form
HH:MM:SS.F
, mit Stunden, Minuten, Sekunden
und Sekundenbruchteilen, wobei letztere mehrere Stellen lang
sein können.
Der Name der Schnittstelle, die das Paket verarbeitet hat,
bspw. dc0
.
Die Gruppe und die Nummer der angewandten Regel, bspw.
@0:17
.
Die ausgeführte Aktion: p für
passed
(zugelassen), b für blockiert,
S für short packet
(unvollständiger
Header), n für no match
(gar keine Regel
wurde berührt) und L für Log-Regel. Die Reihe, in der
die Flags angezeigt werden ist: S, p, b, n, L. Ein groß
geschriebenes P oder B bedeutet, dass das Paket aufgrund einer
globalen Einstellung protokolliert wurde und nicht wegen einer
einzelnen Regel.
Die Adressen. Diese bestehen aus drei Feldern: Der
Quelladresse mit Port (getrennt durch ein Komma), dem Symbol
„->“ und der Zieladresse. Also bspw.
209.53.15.22,80 -> 198.64.221.18,1722
.
PR
gefolgt vom Namen eines
Netzwerk-Protokolls oder dessen Nummer. Bspw.
PR tcp
.
len
gefolgt von der Länge des Headers
und der Gesamtlänge des Paketes, beispielsweise
len 20 40
.
Wenn es sich um ein TCP-Paket handelt, wird ein weiteres Feld, beginnend mit einem Querstrich und gefolgt von Buchstaben, die den gesetzten Flags entsprechen, angezeigt. Lesen Sie bitte die Manpage ipmon(8) für eine Liste der Buchstaben und deren Bedeutungen.
Falls das Paket ein ICMP-Paket ist, werden zwei Felder am Ende
hinzugefügt - das erstere ist immer „ICMP“, das
zweite enthält die ICMP-Nachricht und den Nachrichtentyp,
getrennt durch einen Schrägstrich. ICMP 3/3
steht beispielsweise für „Port nicht
erreichbar“.
Erfahrenere IPF Anwender erstellen sich eine Datei, die die Regeln enthält und gestalten diese als ein Skript, in dem Variablen verwendet werden. Der wichtigste Vorteil besteht darin, dass man lediglich den Wert der Variablen anpassen muss und diese, sobald das Skript gestartet wird, durch die entsprechenden Werte ersetzt und die Regeln entsprechend formuliert werden. In Skripten kann man so häufig verwendete Werte einfach als Variable in mehreren Regeln zuweisen. Am folgenden Beispiel soll das verdeutlicht werden.
Die Syntax dieses Skriptes ist kompatibel mit den Shells sh(1), csh(1) und tcsh(1).
Variablen beginnen mit einem Dollar-Zeichen:
$Variablenname
. Im Beispiel unten steht
$oif
für die Variable, in der der Name
der Schnittstelle abgelegt wird, über die der Verkehr nach
außen erfolgt.
In Variablenzuweisungen fehlt das beginnende $-Zeichen.
Alleine der Name der Variable wird angegeben, gefolgt von einem
Gleichheitszeichen, und dem Wert, der der Variablen zugewiesen werden
soll. Dieser muss in doppelten Anführungszeichen
(""
) stehen. Also folgt eine Zuweisung dem Schema
Variablenname = "Wert"
.
Das ist schon alles. Die Regeln selbst sind im Beispiel nicht
so wichtig - achten Sie auf die Anwendung der Variablenzuweisung
am Anfang und die Verwendung der Variablen im Skript. Falls das
obige Beispiel in einer Datei namens
/etc/ipf.rules.script
gespeichert wurde,
können die Regeln mit folgenden Kommando neu geladen
werden:
#
sh /etc/ipf.rules.script
Es gibt ein Problem mit Regelsatz-Dateien, die Variablen verwenden: IPF kann mit Variablen nichts anfangen - und kann derartige Skripte nicht direkt einlesen.
Unser kleines Skript kann daher nur auf eine der beiden folgenden Weisen verwendet werden:
Entfernen Sie das Kommentarzeichen der Zeile, die mit
cat
beginnt. Kommentieren Sie die Zeile aus,
die mit /sbin/ipf
beginnt. Schreiben Sie die
Zeile ipfilter_enable="YES"
in die Datei
/etc/rc.conf
und rufen Sie dann das Skript
auf, um /etc/ipf.rules
zu erstellen oder
zu erneuern.
Deaktivieren Sie IPFILTER in den Systemstart-Skripten, indem
Sie die Zeile ipfilter_enable="NO"
in die
Datei /etc/rc.conf
eintragen (was auch der
Standard-Einstellung entspricht).
Fügen Sie ein Skript ähnlich dem folgenden in Ihr
Verzeichnis /usr/local/etc/rc.d/
. Es
sinnvoll, dem Skript einen offensichtlichen Namen zu geben, wie
etwa ipf.loadrules.sh
. Die Endung
.sh
ist dabei verbindlich.
Die Zugriffsrechte für die Datei, die das Skript
enthält, müssen für den Eigentümer
root
auf Lesen, Schreiben und Ausführen
gesetzt werden.
#
chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh
Wenn nun Ihr System startet, werden Ihre IPF-Regeln geladen.
Ein Regelsatz ist eine Gruppe von IPF-Regeln, die anhand der
Werte eines Netzwerkpaketes entscheiden, ob dieses Paket durchgelassen
oder blockiert wird. Der Austausch von Paketen erfolgt immer
zweiseitig in Form einer sogenannten Session. Der Regelsatz der
Firewall verarbeitet sowohl die eingehenden Pakete aus dem
öffentlichen Internet als auch die Pakete, die vom System als
Antwort auf die Ersteren gesendet werden. Jeder Dienst, der via
TCP/IP arbeitet, zum Beispiel
telnet
, www
oder
mail
, ist vordefiniert durch sein Protokoll und
seinen privilegierten Port, an dem er auf Anfragen wartet und
reagieren kann. Pakete, die gezielt einen Dienst ansprechen sollen,
werden von einem unprivilegierten Port des Senders an einen konkreten
privilegierten Port des Zielsystems geschickt. Alle genannten
Parameter (Ports, Adressen usw.) können als Auswahlkriterien zum
erstellen von Regeln eingesetzt werden, die Dienste erlauben oder
blockieren.
IPF wurde ursprünglich mit einer Regel-Prozess-Logik
geschrieben, die ausschließlich statusfreie Regeln zuließ
und nach dem Prinzip „die letzte Regel, die passt,
entscheidet“ arbeitete. Mit der Zeit erhielt IPF eine
quick
Option sowie keep-state
Option
für die Anwendung von zustandsorientierten Regeln, was die
Regel-Prozess-Logik signifikant modernisierte.
Die Anweisungen in diesem Kapitel basieren auf der Verwendung von Regeln, die diese beiden neuen Optionen verarbeiten. Dies ist das Framework zur Entwicklung eines Firewallregelsatzes.
Wenn Sie mit einer Firewall arbeiten, seien Sie sehr vorsichtig. Durch wenige Einstellungen können Sie sich aus Ihrem System aussperren. Wenn Sie auf der sicheren Seite sein wollen, führen Sie die Firewall-Konfiguration direkt am entsprechenden Gerät aus und nicht über eine Netzwerkverbindung wie bspw. ssh.
Die Syntax zur Erstellung der Regeln, die hier vorgestellt wird, ist dahingehend vereinfacht worden, dass sie ausschliesslich auf den modernen Regelkontext, mit statusbehafteten Regeln und einer „die erste Regel, die passt, gewinnt“-Logik, zurückgreift. Um alles über die veraltete Syntax zu erfahren, lesen Sie bitte die Man-Page von ipf(8).
Ein #
-Zeichen markiert den Beginn eines
Kommentars. Es darf nach nach einer Regel stehen oder als erstes
Zeichen einer Zeile. Leere Zeilen werden von der
Regel-Prozess-Logik ignoriert.
Regeln enthalten Schlüsselwörter. Diese Schlüsselwörter müssen in einer bestimmten Reihenfolge von links nach rechts in einer Zeile erscheinen. Als solche identifizierte Schlüsselwörter werden fett wiedergegeben. Einige Schlüsselwörter haben Unteroptionen, die wiederum selbst Schlüsselwörter sein und ebenfalls weiter Unteroptionen einschließen können.
ACTION IN-OUT OPTIONS SELECTION STATEFUL PROTO
SRC_ADDR,DST_ADDR OBJECT PORT_NUM TCP_FLAG
STATEFUL
ACTION
= block | pass
IN-OUT
= in | out
OPTIONS
= log | quick | on
interface-name
SELECTION
= proto value |
source/destination IP | port = number | flags flag-value
PROTO
= tcp/udp | udp | tcp |
icmp
SRC_ADD,DST_ADDR
= all | from
object to object
OBJECT
= IP address | any
PORT_NUM
= port number
TCP_FLAG
= S
STATEFUL
= keep state
Die „ACTION“ bestimmt, was mit dem Paket passieren soll, wenn der Rest der Regel zutrifft. Dieser Teil muss für jede Regel angegeben werden.
Das Schlüsselwort block
gibt an, dass
das Paket verfallen soll, wenn die Auswahlparameter zutreffen.
Das Schlüsselwort pass
gibt an, dass
das Paket durch die Firewall durchgelassen werden soll, wenn die
Auswahlparameter zutreffen.
Ebenfalls verbindlich ist die Angabe, welchen Teil der
Verbindung, Ein- oder Ausgang, die Regel beeinflussen soll. Das
nächste Schlüsselwort muss daher entweder
in
, für eingehend, oder
out
, für ausgehend, lauten - oder die Regel
wird aufgrund eines Syntaxfehlers nicht umgesetzt.
in
bedeutet, dass diese Regel auf eingehende
Pakete angewendet wird, die gerade an der dem öffentlichen
Internet zugewandten Schnittstelle empfangen wurden.
out
bedeutet, das diese Regel auf ausgehende
Pakete angewendet wird, also Pakete die gerade gesendet werden und
deren Zieladresse im öffentlichen Internet liegt.
Die Optionen müssen in der hier aufgeführten Reihenfolge verwendet werden.
log
bestimmt, dass die Kopfdaten des Paketes
an die Systemschnittstelle ipl(4) geschrieben werden sollen.
Genaueres dazu weiter unten im Abschnitt LOGGING.
quick
bestimmt, dass,
wenn die Auswahlkriterien der Regel auf das
Paket zutreffen, keine weiteren Regeln ausgewertet werden. So
vermeidet man das Abarbeiten des gesamten Regelsatzes. Diese Option
ist eine verbindliche Vorraussetzung der modernen
Regel-Prozess-Logik.
on
bestimmt den Namen der Schnittstelle,
der als Auswahlkriterium hinzugefügt werden soll. Die Namen
aller verfügbaren Schnittstellen werden durch den Befehl
ifconfig(8) angezeigt. wenn man diese Option verwendet,
passt die Regeln nur auf Pakete, die durch diese Schnittstelle
empfangen (in
) oder gesendet
(out
) wurden. Für die modernisierte
Regel-Prozess-Logik ist die Verwendung dieser Option
verbindlich.
Wenn ein Paket protokolliert wird, werden die Kopfdaten in
die Pseudo-Schnittstelle ipl(4) geschrieben. Folgende Parameter
können zusätzlich übergeben werden, müssen dazu
aber direkt nach dem Schlüsselwort log
und in
gleicher Reihenfolge stehen:
body
bestimmt, dass die ersten 128 Bytes des
Paketinhaltes zusätzlich zu den Kopfdaten protokolliert
werden.
first
trifft nur zu, wenn das
Schlüsselwort log
zusammen mit
keep-state
verwendet wird. Es bestimmt, dass nur
das auslösende Paket protokolliert wird und nicht jedes weitere
Paket, dass von der gespeicherten Status-Regel betroffen ist.
Die Schlüsselwörter, die in diesem Abschnitt vorgestellt werden, dienen zur Beschreibung von Attributen, anhand derer geprüft und entschieden wird, ob eine Regel zutrifft oder nicht. Es gibt ein Schlüsselwort, und das hat mehrere Optionen, von denen eine ausgewählt werden muss. Die folgenden allgemeinen Attribute können beliebig zum Erstellen einer Regel verwendet werden, allerdings nur in der vorgestellten Reihenfolge:
proto
ist das Schlüsselwort für
das im Paket angewendete Protokoll. Als Option ein Protokoll aus
Auswahlkriterium übergeben. Diese Option ist verbindlich, wenn
man die moderne Regel-Prozess-Logik verwendet.
tcp/udp | udp | tcp | icmp
oder irgendein
Protokollname, der in der Datei /etc/protocols
zu finden ist, kann übergeben werden. Außerdem kann das
Schlüsselwort tcp/udp
verwendet werden, wenn
sowohl TCP als auch UDP von der
Regel betroffen sein sollen. Dieses Schlüsselwort wurde
eingeführt, um Duplikate sonst identischer Regeln zu
vermeiden.
Das Schlüsselwort all
ist ein Synonym
für „from any to any“ ohne weitere
Auswahlkriterien.
from src to dst
: Die Schlüsselwörter
from
und to
dienen zur Angabe
von Quelle und Ziel in Form von IP-Adressen oder -Bereichen.
Innerhalb einer Regel muss immer beides angegeben werden.
Statt einer Adresse kann auch das Schlüsselwort
any
übergeben werden, das für jede
beliebige IP-Adresse steht. Zum Beispiel:
from any to any
oder
from 0.0.0.0/0 to any
oder
from any to 0.0.0.0/0
oder
from 0.0.0.0 to any
oder
from any to 0.0.0.0
bedeuten alle das
Gleiche.
IP-Bereiche können nur in der CIDR-Notation angegeben
werden. Der Port net-mgmt/ipcalc
hilft Ihnen bei der Berechnung der richtigen Angaben.
Weiterführende Informationen zu CIDR finden Sie auf der Webseite
von ipcalc
.
Wenn ein Port als Auswahlkriterium übergeben wurde, bei
Quelle und/oder Ziel, wird er nur bei TCP und
UDP Paketen verwendet. Angegeben werden kann
entweder die Portnummer oder der Dienstname aus
/etc/services
. Die Verwendung der
Portoption mit dem to
-Objekt ist verbindlich
für die Verwendung der modernisierten Regel-Prozess-Logik.
Ein Beispiel für die Filterung Paketen von allen Quell-IPs mit
beliebiger Portnummer auf beliebige Ziel-IPs mit der Portnummer 80
(dem www
-Port):
from any to any port = 80
.
Einfache Portvergleiche können auf verschiedenen Wegen erfolgen. Mehrere Vergleichsoperatoren stehen dafür zur Verfügung. Genauso können Bereiche angegeben werden.
port "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" | "le" | "ge".
Um einen Bereich anzugeben: port "<>" | "><"
Genau wie die Trefferspezifikation für Quelle und Ziel sind auch die beiden folgenden Parameter obligatorisch bei der Verwendung der modernen Regel-Prozess-Logik.
Flags spielen nur beim Filtern von TCP eine Rolle. Die Buchstaben entsprechen jeweils einem möglichen Flag, dass in den Kopfdaten der TCP-Pakete geprueft werden soll.
Die moderne Regel-Prozess-Logik verwendet den Parameter
flags S
um eine Anfrage zum Start einer
TCP-Session zu identifizieren.
Stateful filtering treats traffic as a bi-directional exchange of packets comprising a session conversation. When activated, keep-state dynamically generates internal rules for each anticipated packet being exchanged during the bi-directional session conversation. It has sufficient matching capabilities to determine if the session conversation between the originating sender and the destination are following the valid procedure of bi-directional packet exchange. Any packets that do not properly fit the session conversation template are automatically rejected as impostors.
Keep state will also allow ICMP packets related to a TCP or UDP session through. So if you get ICMP type 3 code 4 in response to some web surfing allowed out by a keep state rule, they will be automatically allowed in. Any packet that IPF can be certain is part of an active session, even if it is a different protocol, will be let in.
What happens is:
Packets destined to go out through the interface connected to the public Internet are first checked against the dynamic state table. If the packet matches the next expected packet comprising an active session conversation, then it exits the firewall and the state of the session conversation flow is updated in the dynamic state table. Packets that do not belong to an already active session, are simply checked against the outbound ruleset.
Packets coming in from the interface connected to the public Internet are first checked against the dynamic state table. If the packet matches the next expected packet comprising an active session conversation, then it exits the firewall and the state of the session conversation flow is updated in the dynamic state table. Packets that do not belong to an already active session, are simply checked against the inbound ruleset.
When the conversation completes it is removed from the dynamic state table.
Stateful filtering allows you to focus on blocking/passing new sessions. If the new session is passed, all its subsequent packets will be allowed through automatically and any impostors automatically rejected. If a new session is blocked, none of its subsequent packets will be allowed through. Stateful filtering has technically advanced matching abilities capable of defending against the flood of different attack methods currently employed by attackers.
The following ruleset is an example of how to code a very
secure inclusive type of firewall. An inclusive firewall only
allows services matching pass
rules through, and blocks all
others by default. Firewalls intended to protect other machines,
also called „network firewalls“, should have at least
two interfaces, which are generally configured to trust one side
(the LAN) and not the other (the public Internet). Alternatively,
a firewall might be configured to protect only the system it is
running on—this is called a
„host based firewall“, and is particularly appropriate
for servers on an untrusted network.
All UNIX® flavored systems including FreeBSD are designed to
use interface lo0
and IP address
127.0.0.1
for internal
communication within the operating system. The firewall rules
must contain rules to allow free unmolested movement of these
special internally used packets.
The interface which faces the public Internet is the one
to place the rules that authorize and control access of the outbound
and inbound connections. This can be your user PPP
tun0
interface or your NIC that is
connected to your DSL or cable modem.
In cases where one or more NICs are cabled to private network segments, those interfaces may require rules to allow packets originating from those LAN interfaces transit to each other and/or to the outside (Internet).
The rules should be organized into three major sections: first trusted interfaces, then the public interface outbound, and last the public untrusted interface inbound.
The rules in each of the public interface sections should have the most frequently matched rules placed before less commonly matched rules, with the last rule in the section blocking and logging all packets on that interface and direction.
The Outbound section in the following ruleset only
contains pass
rules which contain selection values that
uniquely identify the service that is authorized for public
Internet access. All the rules have the quick
, on
,
proto
, port
, and keep state
options set. The proto
tcp
rules have the flag
option included to identify the
session start request as the triggering packet to activate the
stateful facility.
The Inbound section has all the blocking of undesirable
packets first, for two different reasons. The first is that
malicious packets may be partial matches for legitimate traffic.
These packets have to be discarded rather than allowed in, based on
their partial matches against allow
rules.
The second reason is that known and uninteresting rejects may be
blocked silently, rather than being caught and logged by the last
rules in the section. The final rule in each section, blocks and
logs all packets and can be used to create the legal evidence needed
to prosecute the people who are attacking your system.
Another thing that should be taken care of, is to ensure there is no
response returned for any of the undesirable traffic. Invalid
packets should just get dropped and vanish. This way the attacker
has no knowledge if his packets have reached your system. The
less the attackers can learn about your system, the more
time they must invest before actually doing something bad.
Rules that include a log first
option, will only
log the event the first time they are triggered. This option is
included in the sample nmap OS fingerprint
rule.
The security/nmap
utility is
commonly used by attackers who attempt to identify the operating
system of your server.
Any time there are logged messages on a rule with
the log first
option, an ipfstat -hio
command should be executed to evaluate how many times the rule has
actually matched. Large number of matches usually indicate that the
system is being flooded (i.e.: under attack).
The /etc/services
file may be used to
lookup unknown port numbers. Alternatively,
visit http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
and do a port number lookup to find the purpose of a particular
port number.
Check out this link for port numbers used by Trojans http://www.sans.org/security-resources/idfaq/oddports.php.
The following ruleset creates a complete and very secure
inclusive
type of firewall ruleset that has been
tested on production systems. It can be easily modified for your
own system. Just comment out any pass
rules for
services that should not be authorized.
To avoid logging unwanted messages,
just add a block
rule in the inbound section.
The dc0
interface name has to be changed
in every rule to the real interface name of the NIC
card that connects your system to the public Internet. For
user PPP it would be tun0
.
Add the following statements to
/etc/ipf.rules
:
NAT stands for Network Address Translation. To those familiar with Linux®, this concept is called IP Masquerading; NAT and IP Masquerading are the same thing. One of the many things the IPF NAT function enables is the ability to have a private Local Area Network (LAN) behind the firewall sharing a single ISP assigned IP address on the public Internet.
You may ask why would someone want to do this. ISPs normally assign a dynamic IP address to their non-commercial users. Dynamic means that the IP address can be different each time you dial in and log on to your ISP, or for cable and DSL modem users, when the modem is power cycled. This dynamic IP address is used to identify your system to the public Internet.
Now lets say you have five PCs at home and each one needs Internet access. You would have to pay your ISP for an individual Internet account for each PC and have five phone lines.
With NAT only a single account is needed with your ISP. The other four PCs may then be cabled to a switch and the switch to the NIC in your FreeBSD system which is going to service your LAN as a gateway. NAT will automatically translate the private LAN IP address for each separate PC on the LAN to the single public IP address as it exits the firewall bound for the public Internet. It also does the reverse translation for returning packets.
There is a special range of IP addresses reserved for NATed private LANs. According to RFC 1918, the following IP ranges may be used for private nets which will never be routed directly to the public Internet:
Start IP 10.0.0.0 | - | Ending IP 10.255.255.255 |
Start IP 172.16.0.0 | - | Ending IP 172.31.255.255 |
Start IP 192.168.0.0 | - | Ending IP 192.168.255.255 |
NAT rules are loaded by using the
ipnat
command. Typically the
NAT rules are stored in
/etc/ipnat.rules
. See ipnat(1) for
details.
When changing the NAT rules after
NAT has been started, make your changes to
the file containing the NAT rules, then run the ipnat
command with
the -CF
flags to delete the internal in use
NAT rules and flush the contents of the
translation table of all active entries.
To reload the NAT rules issue a command like this:
#
ipnat -CF -f /etc/ipnat.rules
To display some statistics about your NAT, use this command:
#
ipnat -s
To list the NAT table's current mappings, use this command:
#
ipnat -l
To turn verbose mode on, and display information relating to rule processing and active rules/table entries:
#
ipnat -v
NAT rules are very flexible and can accomplish many different things to fit the needs of commercial and home users.
The rule syntax presented here has been simplified to what is most commonly used in a non-commercial environment. For a complete rule syntax description see the ipnat(5) manual page.
The syntax for a NAT rule looks something like this:
IF
LAN_IP_RANGE
-> PUBLIC_ADDRESS
The keyword map
starts the rule.
Replace IF
with the external
interface.
The LAN_IP_RANGE
is what your
internal clients use for IP Addressing, usually this is
something like 192.168.1.0/24
.
The PUBLIC_ADDRESS
can either
be the external IP address or the special keyword
0/32
, which means to use the IP address
assigned to IF
.
A packet arrives at the firewall from the LAN with a public
destination. It passes through the outbound filter rules,
NAT gets its turn at the packet and applies
its rules top down, first matching rule wins.
NAT tests each of its rules against the
packet's interface name and source IP address. When a packet's
interface name matches a NAT rule then the
source IP address (i.e.: private LAN IP address) of the packet
is checked to see if it falls within the IP address range
specified to the left of the arrow symbol on the
NAT rule. On a match the packet has its
source IP address rewritten with the public IP address
obtained by the 0/32
keyword.
NAT posts an entry in its internal
NAT table so when the packet returns from
the public Internet it can be mapped back to its original
private IP address and then passed to the filter rules for
processing.
To enable IPNAT add these statements to
/etc/rc.conf
.
To enable your machine to route traffic between interfaces:
To start IPNAT automatically each time:
To specify where to load the IPNAT rules from:
For networks that have large numbers of PC's on the LAN or networks with more than a single LAN, the process of funneling all those private IP addresses into a single public IP address becomes a resource problem that may cause problems with the same port numbers being used many times across many NATed LAN PC's, causing collisions. There are two ways to relieve this resource problem.
A normal NAT rule would look like:
In the above rule the packet's source port is unchanged
as the packet passes through IPNAT. By
adding the portmap
keyword,
IPNAT can be directed to only use source ports in the specified range.
For example the following rule will tell
IPNAT to modify the source port to be
within the range shown:
Additionally we can make things even easier by using the
auto
keyword to tell
IPNAT to determine by itself which ports
are available to use:
In very large LANs there comes a point where there are just too many LAN addresses to fit into a single public address. If a block of public IP addresses is available, these addresses can be used as a „pool“, and IPNAT may pick one of the public IP addresses as packet-addresses are mapped on their way out.
For example, instead of mapping all packets through a single public IP address, as in:
A range of public IP addresses can be specified either with a netmask:
or using CIDR notation:
A very common practice is to have a web server, email
server, database server and DNS server each segregated to a
different PC on the LAN. In this case the traffic from these
servers still have to be NATed, but there
has to be some way to direct the inbound traffic to the
correct LAN PCs. IPNAT has the redirection
facilities of NAT to solve this problem.
For example, assuming a web server operating on LAN address 10.0.10.25
and using a single public IP
address of 20.20.20.5
the rule would
be coded as follows:
or:
or for a LAN DNS Server on LAN address of 10.0.10.33
that needs to receive
public DNS requests:
FTP is a dinosaur left over from the time before the Internet as it is known today, when research universities were leased lined together and FTP was used to share files among research Scientists. This was a time when data security was not a consideration. Over the years the FTP protocol became buried into the backbone of the emerging Internet and its username and password being sent in clear text was never changed to address new security concerns. FTP has two flavors, it can run in active mode or passive mode. The difference is in how the data channel is acquired. Passive mode is more secure as the data channel is acquired by the ordinal ftp session requester. For a real good explanation of FTP and the different modes see http://www.slacksite.com/other/ftp.html.
IPNAT has a special built in FTP proxy option which can be specified on the NAT map rule. It can monitor all outbound packet traffic for FTP active or passive start session requests and dynamically create temporary filter rules containing only the port number really in use for the data channel. This eliminates the security risk FTP normally exposes the firewall to from having large ranges of high order port numbers open.
This rule will handle all the traffic for the internal LAN:
This rule handles the FTP traffic from the gateway:
This rule handles all non-FTP traffic from the internal LAN:
The FTP map rule goes before our regular map rule. All packets are tested against the first rule from the top. Matches on interface name, then private LAN source IP address, and then is it a FTP packet. If all that matches then the special FTP proxy creates temp filter rules to let the FTP session packets pass in and out, in addition to also NATing the FTP packets. All LAN packets that are not FTP do not match the first rule and fall through to the third rule and are tested, matching on interface and source IP, then are NATed.
Only one filter rule is needed for FTP if the NAT FTP proxy is used.
Without the FTP Proxy, the following three rules will be needed:
Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an
<de-bsd-questions@de.FreeBSD.org>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an
<de-bsd-translators@de.FreeBSD.org>.