29.5. IPFW

IPFW ist eine Stateful-Firewall für FreeBSD, die sowohl IPv4 als auch IPv6 unterstützt. Die Firewall setzt sich aus mehreren Komponenten zusammen: dem Kernel Firewall Filter-Prozessor mit integriertem Paket-Accounting, Protokollfunktionen, NAT, dem dummynet(4) Traffic-Shaper, sowie Weiterleitungs-, Bridge- und ipstealth-Funktionen.

FreeBSD enthält mit /etc/rc.firewall ein Beispielregelwerk, welches mehrere Firewall-Typen für gebräuchliche Szenarien definiert und unerfahrene Anwender dabei unterstützen soll, ein geeignetes Regelwerk zu erstellen. IPFW besitzt eine leistungsstarke Syntax, mit der erfahrene Benutzer ihre eigenen Regeln anfertigen können, um den Sicherheitsanforderungen der jeweiligen Umgebung gerecht zu werden.

Diser Abschnitt beschreibt, wie IPFW aktiviert wird und bietet einen Überblick über die Regelsyntax. Zudem werden mehrere Regelsätze für gebräuchliche Konfigurationsszenarien vorgestellt.

29.5.1. IPFW aktivieren

Das FreeBSD Basissystem enthält für IPFW ein ladbares Kernelmodul, was bedeutet, dass kein angepasster Kernel benötigt wird, um IPFW zu benutzen.

Wenn Sie eine statische Unterstützung für IPFW in den Kernel kompilieren wollen, lesen Sie Kapitel 8, Konfiguration des FreeBSD-Kernels. Folgende Optionen können in der Kernelkonfigurationsdatei verwendet werden:

options    IPFIREWALL				# enables IPFW
options    IPFIREWALL_VERBOSE		# enables logging for rules with log keyword
options    IPFIREWALL_VERBOSE_LIMIT=5	# limits number of logged packets per-entry
options    IPFIREWALL_DEFAULT_TO_ACCEPT	# sets default policy to pass what is not explicitly denied
options    IPDIVERT			# enables NAT

Um IPFW beim Systemstart zu aktivieren, fügen Sie folgende Zeile in /etc/rc.conf ein:

firewall_enable="YES"

Wenn Sie einen der von FreeBSD zur Verfügung gestellten Firewall-Profile benutzen möchten, fügen Sie eine weitere Zeile hinzu, in der Sie das Profil bestimmen:

firewall_type="open"

Folgende Profile stehen zur Verfügung:

  • open: gestattet jeglichen Datenverkehr.

  • client: schützt lediglich diesen Rechner.

  • simple: schützt das gesamte Netzwerk.

  • closed: blockiert den gesamten IP-Datenverkehr, mit Ausnahme des Verkehrs über die Loopback-Schnittstelle.

  • workstation: schützt lediglich diesen Rechner und verwendet zustandsorientierte Regeln.

  • UNKNOWN: deaktiviert das Laden von Firewallregeln.

  • filename: absoluter Pfad zu einer Datei, in der die Firewallregeln definiert sind.

Wenn Sie firewall_type auf client oder simple setzen, müssen Sie die voreingestellten Regeln in /etc/rc.firewall anpassen, damit sie der Konfiguration des Systems entsprechen.

Beachten Sie, dass das Profil filename verwendet wird, um ein benutzerdefiniertes Regelwerk zu laden.

Eine alternative Möglichkeit, um ein benutzerdefiniertes Regelwerk zu laden, bietet die Variable firewall_script. Setzen Sie die Variable auf den absoluten Pfad eines ausführbaren Skripts, welches die Befehle für IPFW enthält. Die Beispiele in diesem Abschnitt gehen davon aus, dass firewall_script auf /etc/ipfw.rules gesetzt ist.

firewall_script="/etc/ipfw.rules"

Die Protokollierung wird mit diesem Eintrag aktiviert:

firewall_logging="YES"

Es existiert keine Variable für /etc/rc.conf, um die Protokollierung zu begrenzen. Um die Anzahl der Protokoll-Nachrichten pro Verbindungsversuch zu begrenzen, legen Sie die Anzahl der Einträge in /etc/sysctl.conf fest:

net.inet.ip.fw.verbose_limit=5

Nachdem Sie die Änderungen gespeichert haben, können Sie die Firewall starten. Um auch die Anzahl der Protokoll-Nachrichten zu konfigurieren, setzen Sie mit sysctl den gewünschten Wert:

# service firewall start
# sysctl net.inet.ip.fw.verbose_limit=5

29.5.2. IPFW Regel-Syntax

Wenn ein Paket die Firewall betritt, also von der Firewall geprüft und verarbeitet wird, wird die erste Regel des Regelwerkes auf das Paket angewandt. Auf diese Weise wird in aufsteigender Reihenfolge der Regelnummer mit allen weiteren Regeln verfahren. Falls die Selektionsparameter einer Regel auf ein Paket zutreffen, wird das Aktionsfeld der Regel ausgeführt und die Prüfung des Pakets beendet, nachfolgende Regeln werden also nicht mehr geprüft. Diese Suchmethode wird als erster Treffer gewinnt bezeichnet. Falls keine Regel auf das betreffende Paket zutrifft, wird die obligatorische IPFW-Rückfallregel mit der Nummer 65535 angewendet und das Paket wird ohne Rückantwort verworfen. Wenn das Paket jedoch einer Regel mit dem Schlüsselwort count, skipto oder tee entspricht, wird die Prüfung des Pakets weiter fortgeführt. Weitere Details darüber, wie diese Schlüsselwörter die Regelverarbeitung beeinflussen, finden Sie in ipfw(8).

Bei der Erstellung der IPFW-Regeln müssen die Schlüsselwörter in der folgenden Reihenfolge geschrieben werden. Einige Schlüsselwörter müssen zwingend angegeben werden, während andere optional sind. Die Wörter in Großbuchstaben repräsentieren Variablen und die Wörter in Kleinbuchstaben müssen den Variablen vorangestellt werden. Das Zeichen # wird benutzt, um einen Kommentar einzuleiten und kann am Ende einer Regel oder in einer eigenen Zeile stehen. Leerzeilen werden ignoriert.

CMD RULE_NUMBER set SET_NUMBER ACTION log LOG_AMOUNT PROTO from SRC SRC_PORT to DST DST_PORT OPTIONS

Dieser Abschnitt bietet einen Überblick über diese Schlüsselwörter und deren Optionen. Es ist keine vollständige Liste aller verfügbaren Optionen. Eine vollständige Beschreibung der Regel-Syntax, die Sie verwenden können um IPFW-Regeln zu erstellen, finden Sie in ipfw(8).

CMD

Jede Regel muss mit ipfw add beginnen.

RULE_NUMBER

Jede Regel gehört zu einer Nummer zwischen 1 und 65534. Die Nummer wird verwendet, um die Reihenfolge der Regelverarbeitung zu kennzeichnen. Es ist möglich, dass mehrere Regeln dieselbe Nummer haben. In diesem Fall werden sie entsprechend der Reihenfolge angewendet, in der sie aufgenommen wurden.

SET_NUMBER

Jede Regel ist einer Set-Nummer zwischen 0 und 31 zugeordnet. Sets können einzeln aktiviert oder deaktiviert werden. Dies macht es möglich, eine Reihe von Regeln schnell hinzuzufügen oder zu löschen. Wenn SET_NUMBER nicht angegeben ist, wird die Regel zu Set 0 hinzugefügt.

ACTION

Eine Regel kann mit einer der folgenden Aktionen verknüpft werden. Die festgelegte Aktion wird ausgeführt, wenn das Paket den Selektionskriterien der Regel entspricht.

allow | accept | pass | permit: All diese Aktionen sind gleichbedeutend und erlauben Pakete, die mit der Regel übereinstimmen.

check-state: Diese Aktion überprüft die Regel in der dynamischen Zustandstabelle. Bei einer Übereinstimmung wird die mit der dynamischen Regel verknüpfte Aktion ausgeführt, andernfalls wird mit der Prüfung gegen die nächste Regel fortgefahren. Die Regel check-state hat selbst kein Selektionskriterium. Sollte keine check-state-Regel im Regelwerk vorhanden sein, wird die dynamische Zustandstabelle beim ersten Vorkommen einer keep-state- oder limit-Regel überprüft.

count: Aktualisiert die Zähler für alle Pakete, die mit dieser Regel übereinstimmen. Die Prüfung wird mit der nächsten Regel fortgesetzt.

deny | drop: Diese Aktionen sind gleichbedeutend und verwerfen Pakete, die mit dieser Regel übereinstimmen.

Es stehen noch weitere Aktionen zur Verfügung. Einzelheiten finden Sie in ipfw(8).

LOG_AMOUNT

Erfüllt ein Paket die Selektionskriterien mit dem Schlüsselwort log, wird dies von syslogd(8) mit der Annotation SECURITY protokolliert. Dies erfolgt allerdings nur, wenn die Anzahl der protokollierten Pakete der betreffenden Regel die definierte LOG_AMOUNT-Grenze nicht übersteigt. Wenn LOG_AMOUNT nicht definiert ist, wird die Grenze aus dem Wert von net.inet.ip.fw.verbose_limit benutzt. Ein Wert von 0 bedeutet eine unbegrenzte Protokollierung. Wird eine definierte Grenze erreicht, wird die Protokollierung für diese Regel deaktiviert. Um die Protokollierung zu reaktivieren, können Sie den Protokoll- oder Paketzähler mit ipfw resetlog zurücksetzen.

Anmerkung:

Die Protokollierung findet statt, nachdem alle Selektionskriterien geprüft und bevor die endgültige Aktion auf das Paket angewendet wird. Der Administrator entscheidet, welche Regel protokolliert werden soll.

PROTO

Dieser optionale Wert wird verwendet, um einen beliebigen Protokollnamen oder -nummer aus /etc/protocols gegen das Paket zu prüfen.

SRC

Nach dem Schlüsslwortfrom muss die Quelladresse stehen, oder ein Schlüsselwort, das die Quelladresse darstellt. Eine Adresse wird dargestellt duch any, me (jede Adresse dieses Systems), me6 (jede IPv6-Adresse dieses Systems), oder table gefolgt von der Nummer der Tabelle, welche die Adressen enthält. IP-Adressen können in CIDR-Notation geschrieben werden. Beispielsweise 1.2.3.4/25 oder 1.2.3.4:255.255.255.128.

SRC_PORT

Optional kann ein Quellport über eine Nummer oder einen Namen aus /etc/services spezifiziert werden.

DST

Nach dem Schlüsselwort to muss die Zieladresse stehen, oder ein Schlüsselwort, das die Zieladresse darstellt. Es können die gleichen Schlüsselwörter und Adressen benutzt werden, die bereits im SRC-Abschnitt beschrieben wurden.

DST_PORT

Optional kann ein Zielport über eine Nummer oder einen Namen aus /etc/services spezifiziert werden.

OPTIONS

Nach der Quell- und Zieladresse können noch weitere Optionen angegeben werden. Wie der Name bereits sagt, sind OPTIONS optional. Häufig verwendete Optionen sind in oder out, mit denen die Richtug des Pakets bestimmt wird, icmptypes gefolgt vom Typ der ICMP-Nachricht, sowie keep-state.

Wenn ein Paket auf eine keep-state-Regel zutrifft, wird die Firewall eine dynamische Regel erstellen, die dem bidirektionalen Datenverkehr zwischen den gleichen Quell- und Zieladressen mit dem gleichen Protokoll entspricht.

Dynamische Regeln sind für einen sogenannten SYN-flood-Angriff anfällig, bei dem eine riesige Anzahl an dynamischen Regeln erzeugt wird. Verwenden Sie die Option limit, um einen solchen Angriff entgegenzuwirken. Diese Option begrenzt die Anzahl der gleichzeitig möglichen Sitzungen. Es handelt sich dabei um einen Zähler, der die Anzahl von dynamischen Regeln in Kombination mit der Quelladresse verfolgt. Übersteigt der Zähler den durch limit definierten Wert, wird das Paket verworfen.

Es stehen noch viele weitere Optionen zur Verfügung. ipfw(8) enthält eine Beschreibung der einzelnen Optionen.

29.5.3. Beispiel für einen Regelsatz

Dieser Abschnitt die Erstellung eines Firewall-Skripts namens /etc/ipfw.rules mit zustandsorientierten (stateful Regeln. Alle Regeln in diesem Beispiel verwenden die Optionen in und out, um die Richtung des Pakets zu verdeutlichen. Zusätzlich wird via interface-name benutzt, um die Schnittstelle für das Paket zu prüfen.

Anmerkung:

Bei den anfänglichen Tests mit dem Firewall-Regelsatz sollten Sie vielleicht folgende Einstellung vornehmen:

net.inet.ip.fw.default_to_accept="1"

Dies legt die Standardregel von ipfw(8) etwas großzügiger fest, als das voreingestellte default deny ip from any to any. Dadurch sinkt die Gefahr, sich nach einem Neustart des Systems auszusperren.

Das Firewall-Skript beginnt mit einem Hinweis, dass es sich um ein Bourne Shell-Skript handelt. Danach werden alle vorhandenen Filterregeln gelöscht. Anschließend wird die Variable cmd erstellt, sodass ipfw add nicht jedes mal von Hand eingegeben werden muss. Die Variable pif repräsentiert die mit dem Internet verbundene Schnittstelle.

#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
pif="dc0"     # interface name of NIC attached to Internet

Jetzt folgen die eigentlichen Filterregeln. Diese ersten beiden Regeln erlauben den Datenverkehr aus dem internen Netzwerk und über die Loopback-Schnittstelle:

# Change xl0 to LAN NIC interface name
$cmd 00005 allow all from any to any via xl0

# No restrictions on Loopback Interface
$cmd 00010 allow all from any to any via lo0

Die nächste Regel erlaubt Pakete, für die ein Eintrag in der dynamischen Zustandstabelle existiert:

$cmd 00101 check-state

Die nächsten Regeln definieren, welche internen Rechner Verbindungen zu anderen Rechnern im Internet aufbauen dürfen. Hier werden wieder zustandsorientierte Regeln verwendet:

# Allow access to public DNS
# Replace x.x.x.x with the IP address of a public DNS server
# and repeat for each DNS server in /etc/resolv.conf
$cmd 00110 allow tcp from any to x.x.x.x 53 out via $pif setup keep-state
$cmd 00111 allow udp from any to x.x.x.x 53 out via $pif keep-state

# Allow access to ISP's DHCP server for cable/DSL configurations.
# Use the first rule and check log for IP address.
# Then, uncomment the second rule, input the IP address, and delete the first rule
$cmd 00120 allow log udp from any to any 67 out via $pif keep-state
#$cmd 00120 allow udp from any to x.x.x.x 67 out via $pif keep-state

# Allow outbound HTTP and HTTPS connections
$cmd 00200 allow tcp from any to any 80 out via $pif setup keep-state
$cmd 00220 allow tcp from any to any 443 out via $pif setup keep-state

# Allow outbound email connections
$cmd 00230 allow tcp from any to any 25 out via $pif setup keep-state
$cmd 00231 allow tcp from any to any 110 out via $pif setup keep-state

# Allow outbound ping
$cmd 00250 allow icmp from any to any out via $pif keep-state

# Allow outbound NTP
$cmd 00260 allow tcp from any to any 37 out via $pif setup keep-state

# Allow outbound SSH
$cmd 00280 allow tcp from any to any 22 out via $pif setup keep-state

# deny and log all other outbound connections
$cmd 00299 deny log all from any to any out via $pif

Die folgenden Regeln steuern die Verbindungen von Rechern aus dem Internet ins interne Netzwerk. Zuerst werden Pakete verworfen, die typischerweise im Zusammenhang mit Angriffen stehen. Danach werden bestimmte Arten von Verbindungen erlaubt. Alle Dienste aus dem öffentlichen Internet beinhalten die Option limit, um Flooding zu unterbinden.

# Deny all inbound traffic from non-routable reserved address spaces
$cmd 00300 deny all from 192.168.0.0/16 to any in via $pif     #RFC 1918 private IP
$cmd 00301 deny all from 172.16.0.0/12 to any in via $pif      #RFC 1918 private IP
$cmd 00302 deny all from 10.0.0.0/8 to any in via $pif         #RFC 1918 private IP
$cmd 00303 deny all from 127.0.0.0/8 to any in via $pif        #loopback
$cmd 00304 deny all from 0.0.0.0/8 to any in via $pif          #loopback
$cmd 00305 deny all from 169.254.0.0/16 to any in via $pif     #DHCP auto-config
$cmd 00306 deny all from 192.0.2.0/24 to any in via $pif       #reserved for docs
$cmd 00307 deny all from 204.152.64.0/23 to any in via $pif    #Sun cluster interconnect
$cmd 00308 deny all from 224.0.0.0/3 to any in via $pif        #Class D & E multicast

# Deny public pings$
$cmd 00310 deny icmp from any to any in via $pif$
$
# Deny ident$
$cmd 00315 deny tcp from any to any 113 in via $pif$
$
# Deny all Netbios services.$
$cmd 00320 deny tcp from any to any 137 in via $pif$
$cmd 00321 deny tcp from any to any 138 in via $pif$
$cmd 00322 deny tcp from any to any 139 in via $pif$
$cmd 00323 deny tcp from any to any 81 in via $pif$

# Deny fragments
$cmd 00330 deny all from any to any frag in via $pif

# Deny ACK packets that did not match the dynamic rule table
$cmd 00332 deny tcp from any to any established in via $pif

# Allow traffic from ISP's DHCP server.
# Replace x.x.x.x with the same IP address used in rule 00120.
#$cmd 00360 allow udp from any to x.x.x.x 67 in via $pif keep-state

# Allow HTTP connections to internal web server
$cmd 00400 allow tcp from any to me 80 in via $pif setup limit src-addr 2

# Allow inbound SSH connections
$cmd 00410 allow tcp from any to me 22 in via $pif setup limit src-addr 2

# Reject and log all other incoming connections
$cmd 00499 deny log all from any to any in via $pif

Die letzte Regel protokolliert alle Pakete, die mit keiner Regel im Regelsatz übereinstimmen:

# Everything else is denied and logged
$cmd 00999 deny log all from any to any

29.5.4. NAT Konfiguration

Beigetragen von Chern Lee.

FreeBSDs integrierter NAT-Daemon, natd(8), arbeitet in Verbindung mit IPFW, um Network Address Translation bereitzustellen. NAT wird verwendet, um mehreren internen Rechnern, über eine einzige IP-Adresse, eine gemeinsame Verbindung zum Internet zu ermöglichen.

Um dies zu tun, muss der mit dem Internet verbundene FreeBSD-Rechner als Gateway eingerichtet sein. Das System muss über zwei Netzwerkschnittstellen verfügen, wobei eine Schnittstelle mit dem Internet verbunden ist und die andere mit dem internen Netzwerk. Jeder Rechner im internen Netzwerk sollte eine RFC 1918 konforme Adresse zugewiesen bekommen. Zudem muss das Standard-Gateway der Rechner auf die interne IP-Adresse des natd(8)-Systems gesetzt werden.

Es ist noch ein wenig Konfiguration nötig, um die NAT-Funktion von IPFW zu aktivieren. Wenn das System einen angepassten Kernel hat, muss die Kernelkonfigurationsdatei die Zeile option IPDIVERT sowie weitere IPFIREWALL-Optionen, die in Abschnitt 29.5.1, „IPFW aktivieren“ beschrieben sind, enthalten.

Um die NAT-Unterstützung beim Booten zu aktivieren, müssen folgende Einträge in /etc/rc.conf vorhanden sein:

gateway_enable="YES"		# enables the gateway
natd_enable="YES"		# enables NAT
natd_interface="rl0"		# specify interface name of NIC attached to Internet
natd_flags="-dynamic -m"	# -m = preserve port numbers; additional options are listed in natd(8)

Anmerkung:

Es ist auch möglich eine Konfigurationsdatei zu verwenden, welche die Optionen enthält, die an natd(8) übergeben werden:

natd_flags="-f /etc/natd.conf"

Die angegebene Datei muss die Konfigurationsoptionen enthalten, eine Option pro Zeile. Zum Beispiel:

redirect_port tcp 192.168.0.2:6667 6667
redirect_port tcp 192.168.0.3:80 80

Weitere Informationen zu dieser Konfigurationsdatei finden Sie in natd(8).

Als nächstes werden die NAT-Regeln hinzugefügt. Wenn die Regeln zustandsorientiert sind, ist die Platzierung der NAT-Regeln sehr wichtig und die skipto-Aktion wird verwendet. Dies erfordert, dass jede Regel über eine eindeutige Nummer verfügt, um eindeutige Sprungziele zu erhalten.

Das folgende Beispiel baut auf dem im vorherigen Abschnitt gezeigten Firewall-Relgelsatz auf. Es werden einige neue Einträge hinzugefügt und bestehende Regeln modifiziert, um NAT zu konfigurieren. Zunächst werden einige Variablen hinzugefügt, darunter Regelnummern, die keep-state-Option und eine Liste mit TCP-Ports um die Anzahl der Regeln zu reduzieren:

#!/bin/sh
ipfw -q -f flush
cmd="ipfw -q add"
skip="skipto 500"
pif=dc0
ks="keep-state"
good_tcpo="22,25,37,53,80,443,110"

Die NAT-Regel für eingehende Pakete wird nach den beiden Regeln, die das interne Netzwerk und die Loopback-Schnittstelle erlauben und vor der check-state-Regel eingefügt. Es ist wichtig, dass die Nummer der NAT-Regel (in diesem Beispiel 100) höher ist, als die beiden vorherigen Regeln und niedriger, als die check-state-Regel:

$cmd 005 allow all from any to any via xl0  # exclude LAN traffic
$cmd 010 allow all from any to any via lo0  # exclude loopback traffic
$cmd 100 divert natd ip from any to any in via $pif # NAT any inbound packets
# Allow the packet through if it has an existing entry in the dynamic rules table
$cmd 101 check-state

Die Regeln für den ausgehenden Verkehr werden ebenfalls modifiziert, um Aktionen mit der $skipto-Variable zu erlauben und anzuzeigen, dass die Prüfung mit der Regel 500 fortgesetzt wird. Die sieben Regeln für TCP wurden durch die Regel 125 ersetzt, da die sieben erlaubten ausgehenden Ports in der Variable $good_tcp0 enthalten sind.

# Authorized outbound packets
$cmd 120 $skip udp from any to x.x.x.x 53 out via $pif $ks
$cmd 121 $skip udp from any to x.x.x.x 67 out via $pif $ks
$cmd 125 $skip tcp from any to any $good_tcpo out via $pif setup $ks
$cmd 130 $skip icmp from any to any out via $pif $ks

Die eingehenden Regeln bleiben unverändert, mit Ausnahme der letzten Regel, in der das via $pif entfert wird, um ein- und ausgehende Pakete prüfen zu können. Nach der letzten Regel für ausgehende Pakete muss die NAT-Regel folgen. Die Regel muss eine höhere Nummer als die letzte Regel haben und die Nummer muss über die skipto-Aktion referenziert werden. In diesem Regelsatz leitet die Regel mit der Nummer 500 alle ausgehenden Pakete zur Weiterverarbeitung an natd(8) weiter. Die darauf folgende Regel lässt alle von NAT verarbeiteten Pakete passieren.

$cmd 499 deny log all from any to any
$cmd 500 divert natd ip from any to any out via $pif # skipto location for outbound stateful rules
$cmd 510 allow ip from any to any

In diesem Beispiel steuern die Regeln 100, 101, 125, 500 und 510 die Adressübersetzung der ein- und ausgehende Pakete, so dass immer die private LAN IP-Adresse in der dynamische Zustandstabelle registriert werden.

Nehmen wir beispielsweise einen Web-Browser, der neue HTTP-Sitzungen über Port 80 aufbaut. Wenn nun das erste ausgehende Paket von der Firewall geprüft wird, trifft es nicht auf Regel 100 zu, da das Paket nach außen geleitet wird und nicht nach innen. Das Paket trifft auch nicht auf Regel 101 zu, da es das erste ist und somit noch nicht in der dynamischen Zustandstabelle enthalten ist. Das Paket entspricht schließlich Regel 125, da es ausgehend auf einem erlaubten Port gesendet wird und von einer IP-Adresse aus dem internen LAN stammt. Für Pakete, die auf diese Regel zutreffen, werden zwei Aktionen ausgeführt. Zuerst wird durch die Aktion keep-state ein dynamischer Eintrag in der Statustabelle erstellt und die angegebene Aktion skipto 500 ausgeführt. Als nächstes durchläuft das Paket NAT und wird dann an das Internet gesendet. Nachdem dieses Paket am Webserver angekommen ist, wird dort eine Antwort erzeugt und zurückgeschickt. Dieses Paket wird wieder von oben nach unten durch das Regelwerk geprüft. Dieses Mal trifft Regel 100 auf das Paket zu und die Zieladresse wird auf die zugehörige (lokale) LAN-Adresse abgebildet. Danach wird das Paket von der Regel check-state verarbeitet. Die Zustandstabelle erkennt, dass eine zugehörige aktive Sitzung vorliegt und das Paket wird freigegeben und in das LAN geleitet.

Für den eingehenden Datenverkehr muss der Regelsatz unerwünschte Pakete blockieren und Pakete für autorisierte Dienste durchlassen. Ein Paket, das mit einer Regel für den eingehenden Datenverkehr übereinstimmt, wird in der dynamischen Zustandstabelle eingetragen und dann an das LAN freigegeben. Das Antwortpaket wird von der Regel check-state als Paket einer aktiven Sitzung erkannt. Das Paket wird dann von Regel 500 per NAT verarbeitet, bevor es über die externe Schnittstelle versendet wird.

29.5.4.1. Weiterleitung von Ports

Der Nachteil von natd(8) ist, dass die Rechner im LAN nicht aus dem Internet zugänglich sind. Diese Rechner können zwar ausgehende Verbindungen zur Außenwelt aufbauen, jedoch keine eingehenden Verbindungen empfangen. Dies stellt ein Problem dar, wenn Sie auf einem Rechner im LAN Dienste anbieten möchten, die aus dem Internet erreichbar sein sollen. In diesem Fall können Sie die Ports, welche über das Internet erreichbar sein sollen, über die natd(8)-Maschine an den Rechner im LAN weiterleiten.

Angenommen es gibt einen IRC-Server auf Rechner A und einen Webserver auf Rechner B. Damit dies funktioniert, müssen die Verbindungen auf den Ports 6667 (IRC) und 80 (HTTP) an die jeweiligen Rechner weitergeleitet werden.

Die Syntax für -redirect_port lautet:

-redirect_port proto targetIP:targetPORT[-targetPORT]
                 [aliasIP:]aliasPORT[-aliasPORT]
                 [remoteIP[:remotePORT[-remotePORT]]]

Für das obige Beispiel sollten die Argumente wie folgt aussehen:

-redirect_port tcp 192.168.0.2:6667 6667
    -redirect_port tcp 192.168.0.3:80 80

Damit werden die entsprechenden TCP-Ports an die Rechner im LAN weitergeleitet.

Portbereiche können über -redirect_port festgelegt werden. Zum Beispiel würde tcp 192.168.0.2:2000-3000 2000-3000 alle Verbindungen auf die Ports 2000 bis 3000 an die Ports 2000 bis 3000 an Rechner A weiterleiten.

Diese Optionen können über natd_flags="" in /etc/rc.conf direkt beim Start an natd(8) übergeben werden. Alternativ können die Optionen in eine Konfigurationsdatei eingetragen werden.

Weitere Konfigurationsmöglichkeiten sind in natd(8) beschrieben.

29.5.4.2. Weiterleiten von Adressen

Das Weiterleiten von Adressen ist nützlich, wenn mehr als eine IP-Adresse zur Verfügung steht. Jeder Rechner im LAN kann über natd(8) seine eigene externe IP-Adresse zugewiesen bekommen. natd(8) wird dann den ausgehenden Datenverkehr der Rechner aus dem LAN mit der entsprechenden externen IP-Adresse umschreiben. Auch der eingehenden Datenverkehr über die externe IP-Adresse wird an die entsprechenden Rechner im LAN weitergeleitet. Diese Methode ist auch als statisches NAT bekannt. Wenn Ihnen beispielsweise die IP-Adressen 128.1.1.1, 128.1.1.2 und 128.1.1.3 zur Verfügung stehen, kann 128.1.1.1 als externe Adresse der natd(8)-Maschine verwendet werden, während 128.1.1.2 und 128.1.1.3 an Rechner A und Rechner B im LAN weitergeleitet werden.

Die Syntax für -redirect_address lautet:

-redirect_address localIP publicIP
localIPDie interne IP-Adresse des Rechners im LAN.
publicIPDie externe IP-Adresse für den entsprechenden Rechner im LAN.

Für das obige Beispiel sollten die Argumente wie folgt aussehen:

-redirect_address 192.168.0.2 128.1.1.2
-redirect_address 192.168.0.3 128.1.1.3

Genau wie bei -redirect_port, werden diese Argumente innerhalb der /etc/rc.conf-Option natd_flags="" angegeben, oder alternativ über eine Konfigurationsdatei. Allerdings müssen beim Weiterleiten von Adressen keine Ports umgeleitet werden, da der gesamte eingehende Datenverkehr einer bestimmte IP-Adresse weitergeleitet wird.

Die externe IP-Adresse der natd(8)-Maschine muss auf der externen Schnittstelle aktiv und mit einem Alias versehen sein. Weitere Einzelheiten sind in natd(8) beschrieben.

29.5.5. Das IPFW Kommando

ipfw kann benutzt werden, um einzelne Regeln im laufenden Betrieb hinzuzufügen oder zu entfernen. Problematisch ist jedoch, dass diese Änderungen bei einem Neustart des Systems verloren gehen. Daher ist es empfehlenswert, eigene Regeln in einer Datei zu definieren und diese zu laden, um die Regeln der Firewall im laufenden Betrieb anzupassen.

ipfw ist auch hilfreich, um die geladenen Regeln der auf der Konsole auszugeben. IPFW erzeugt dynamisch einen Zähler, der jedes Paket, auf das eine Regel zutrifft, zählt. Dadurch ist es möglich, die Funktion einer Regel zu überprüfen.

Eine Auflistung aller geladenen Regeln erhalten Sie mit:

# ipfw list

Eine Auflistung aller Regeln inklusive des letzten Treffers erhalten Sie mit:

# ipfw -t list

Das nächste Beispiel zeigt Informationen über die Anzahl der Pakete, die von einer Regel gefiltert wurden sowie die Regel selbst. Der erste Spalte zeigt die Nummer der Regel, gefolgt von der Anzahl der gefilterten Pakete und der Anzahl der Pakete in Bytes. Zum Schluss steht die Regel selbst:

# ipfw -a list

Das folgende Kommando zeigt zusätzlich alle dynamischen Regeln an:

# ipfw -d list

Um diese Auflistung um die abgelaufenen Regeln zu erweitern, geben Sie folgendes Kommando ein:

# ipfw -d -e list

Hiermit werden alle Zähler auf Null zurückgesetzt:

# ipfw zero

Es ist auch möglich, einen spezifischen Zähler zurückzusetzen:

# ipfw zero NUM

29.5.5.1. Protokollierung von Firewall-Nachrichten

Auch bei aktivierter Protokollierung wird IPFW von selbst keine Regeln protokollieren. Der Administrator muss entscheiden, welche Regeln aus dem Regelwerk protokolliert werden sollen. In diesen Regeln muss dann das Schlüsselwort log hinzugefügt werden. Normalerweise werden nur geblockte Pakete protokolliert. Es ist üblich, die ipfw default deny everything-Regel am Ende des Regelwerks mit dem Schlüsselwort log zu duplizieren. Dadurch ist es möglich, alle Pakete zu sehen, auf die keine Regel zutraf.

Protokollierung ist allerdings ein zweischneidiges Schwert. Bei mangelnder Vorsicht oder einem DoS-Angriff wird die Festplatte mit einer enormen Flut von Protokolldaten belastet. Protokoll-Nachrichten werden nicht nur an syslogd(8) geschickt, sondern auch auf der Konsole angezeigt, was dann schnell lästig werden kann.

Die Kerneloption IPFIREWALL_VERBOSE_LIMIT=5 begrenzt die Anzahl identischer Nachrichten an syslogd(8) für eine gegebene Regel auf fünf Nachrichten. Ist diese Option im Kernel aktiviert, wird nach Erreichen den festgelegten Anzahl die Protokollierung von aufeinanderfolgenden Nachrichten auf den festgelegten Wert begrenzt, da beispielsweise die Speicherung von 200 gleichen Protokoll-Nachrichten sinnlos ist. Daher werden durch diese Option nur fünf gleichartige Nachrichten protokolliert. Alle weiteren Nachrichten werden nur gezählt und deren Gesamtzahl wird schließlich von syslogd(8) wie folgt ausgegeben:

Last message repeated 45 times

Alle protokollierten Pakete werden in der Voreinstellung in /var/log/security gespeichert. Dies wird in /etc/syslog.conf definiert.

29.5.5.2. Ein Firewall-Regelwerk erstellen

Die meisten fortgeschrittenen IPFW-Benutzer erzeugen eine Datei, welche die Regeln für die Firewall enthält, um diese als Skript ausführen zu können. Der Vorteil einer derartigen Konfiguration besteht darin, dass dadurch mehrere Regeln gleichzeitig geändert und aktiviert werden können, ohne dass dazu das System neu gestartet werden muss. Dies ist zudem beim Testen von Regeländerungen sehr hilfreich. Weil es sich bei der Datei um ein Skript handelt, ist es auch möglich, häufig verwendete Befehle durch Aliase zu ersetzen und diese dann in mehreren Regeln zu nutzen.

Die Syntax des folgenden Skripts entspricht der Syntax von sh(1), csh(1) sowie tcsh(1). Felder, die symbolisch substituiert werden, haben das Präfix $ (Dollarzeichen). Symbolische Felder haben das $-Präfix nicht. Der Wert, mit dem das symbolische Feld belegt wird, muss in doppelten Anführungszeichen ("") stehen.

Die Datei mit den Regeln könnte wie folgt aufgebaut sein:

############### start of example ipfw rules script #############
#
ipfw -q -f flush       # Delete all rules
# Set defaults
oif="tun0"             # out interface
odns="192.0.2.11"      # ISP's DNS server IP address
cmd="ipfw -q add "     # build rule prefix
ks="keep-state"        # just too lazy to key this each time
$cmd 00500 check-state
$cmd 00502 deny all from any to any frag
$cmd 00501 deny tcp from any to any established
$cmd 00600 allow tcp from any to any 80 out via $oif setup $ks
$cmd 00610 allow tcp from any to $odns 53 out via $oif setup $ks
$cmd 00611 allow udp from any to $odns 53 out via $oif $ks
################### End of example ipfw rules script ############

Die Regeln in diesem Beispiel sind nicht wichtig. Wichtig ist es, zu zeigen, wie die symbolische Substitution innerhalb der Regeln verwendet wird.

Wenn dieses Beispiel in etc/ipfw.rules gespeichert wurde, so könnten alle Regeln durch die Ausführung des folgenden Kommandos neu geladen werden:

# sh /etc/ipfw.rules

Anstelle von /etc/ipfw.rules kann ein beliebig anderer Name oder Speicherort verwendet werden.

Alternativ können die einzelnen Befehle dieses Skripts auch von Hand eingegeben werden:

# ipfw -q -f flush
# ipfw -q add check-state
# ipfw -q add deny all from any to any frag
# ipfw -q add deny tcp from any to any established
# ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state
# ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state
# ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state

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>.