[Zurück: Pakete filtern]
[Inhalt]
[Weiter: Verkehr-Umleitung (Port-Weiterleitung)]
PF: Network Address Translation (NAT)
Inhaltsverzeichnis
Einführung
Network Address Translation (NAT) ist ein Weg, um ein gesamtes
Netzwerk (oder Netzwerke) einer einzigen IP-Adresse zuzuweisen.
NAT ist notwendig, wenn dir eine Anzahl von IP-Adressen von deinem
Internet-Anbieter zur Verfügung gestellt wurde, die geringer ist
als die Gesamtanzahl an Rechnern, denen du Internetzugriff ermöglichen
möchtest. NAT wird im
RFC 1631
beschrieben.
NAT erlaubt dir den Vorteil der reservierten Adressblöcke zu
nutzen, wie sie in
RFC 1918
beschrieben werden.
Normalerweise wird dein internes Netzwerk so eingerichtet sein, dass einer
dieser Netzwerkblöcke verwendet wird. Diese sind:
10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Ein OpenBSD-System, das NAT durchführt, muss mindestens zwei
Netzwerk-Adapter besitzen, einen in Richtung Internet und die anderen
in Richtung internes Netzwerk. NAT wird die Anfragen vom internen
Netzwerk so übersetzen, dass sie so wirken, als wenn sie alle vom
OpenBSD-NAT-System kommen würden.
Wie NAT funktioniert
Wenn ein Client im internen Netzwerk eine Maschine im Internet
kontaktiert, sendet er IP-Pakete, die für diese Maschine bestimmt
sind. Diese Pakete beinhalten alle Adress-Informationen, die benötigt
sind, um am Ziel anzukommen. NAT befasst sich mit diesen Informationen:
- Quell-IP-Adresse (zum Beispiel 192.168.1.35)
- Quell-TCP- oder -UDP-Port (zum Beispiel 2132)
Wenn das Paket durch das NAT-Gateway gesendet wird, wird es so
modifiziert, dass es wirkt, als wenn es vom NAT-Gateway geschickt
worden sind. Das NAT-Gateway wird sich die Änderungen in der
,state'-Tabelle merken, so dass es a) die Änderungen für die
Antwort-Pakete wieder rückgängig machen kann und b) sicherstellen kann,
dass die Antwort-Pakete durch die Firewall gelassen und nicht geblockt
werden. Zum Beispiel können die folgenden Änderungen durchgeführt
werden:
- Quell-IP: ersetzt mit der externen Adresse des Gateways
(zum Beispiel 24.5.0.5)
- Quell-Port: ersetzt mit einem zufällig gewählten, unbenutzen Port des
Gateways (zum Beispiel 53136)
Weder die interne Maschine noch der Internet-Host wissen etwas von
diesen Übersetzungs-Schritten. Für die interne Maschine ist das
NAT-System einfach ein Internet-Gateway. Für den Internet-Host
scheinen die Pakete vom NAT-System direkt zu kommen; er weiß noch
nicht einmal, dass die interne Workstation überhaupt existiert.
Wenn der Internet-Host auf die Pakete der internen Maschine antwortet,
werden sie an die externe IP des NAT-Gateways (24.5.0.5) und den
Übersetzungs-Port (53136) gerichtet sein. Das NAT-Gateway durchsucht dann
die ,state'-Tabelle, ob die Antwort-Pakete zu einer bereits erstellten
Verbindung gehören. Ein einzigartiger Treffer, basierend auf der
IP/Port-Kombination, wird gefunden, welcher PF mitteilt, dass die
Pakete zu einer Verbindung gehören, die von der internen Maschine
192.168.1.35 eröffnet wurde. PF wird dann die entgegengesetzten
Änderungen, die an den Paketen, die hinausgingen, gemacht worden sind,
vornehmen und die Antwort-Pakete an die interne Maschine weiterleiten.
Die Übersetzung von ICMP-Paketen findet auf eine ähnliche Art und Weise
statt, aber ohne der Quell-Port-Modifizierung.
NAT und das Filtern von Paketen
HINWEIS: Übersetzte Pakete müssen weiterhin
die Filter-Engine durchlaufen und werden geblockt oder durchgelassen,
jenachdem, welche Filterregeln definiert worden sind.
Die einzige Ausnahme zu dieser Regel ist, wenn das
pass-Schlüsselwort innerhalb der nat-Regel verwendet
wird.
Dies hat zur Folge, dass NAT-Pakete direkt durch die Filter-Engine
gelassen werden.
Sei dir ebenfalls bewusst, dass, da die Übersetzung vor dem
Filtern stattfindet, die Filter-Engine die übersetzten Pakete
mit den übersetzten IP-Adressen und Ports sehen, wie es in
Wie NAT funktioniert beschrieben wurde.
IP-Weiterleitung
Da NAT fast ausschließlich auf Routern und Netzwerk-Gateways verwendet
wird, ist es wahrscheinlich notwendig, IP-Weiterleitung zu aktivieren,
so dass die Pakete zwischen den Netzwerk-Interfaces der OpenBSD-Maschine
ausgetauscht werden können. IP-Weiterleitung wird durch den
sysctl(3)-Mechanismus aktiviert:
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (wenn IPv6 verwendet wird)
Um diese Änderungen dauerhaft zu machen, sollten die folgenden
Zeilen der
/etc/sysctl.conf hinzugefügt werden:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
Diese Zeilen sind in der Standard-Installation bereits vorhanden, aber
auskommentiert (vor ihnen steht eine Raute #).
Entferne die # und speicher die Datei. IP-Weiterleitung
wird aktiviert, wenn die Maschine neustartet.
NAT konfigurieren
Das generelle Format der NAT-Regeln in pf.conf sieht so
ähnlich aus wie folgt:
nat [pass [log]] on interface [af] from src_addr
[port src_port] to \
dst_addr [port dst_port] ->
ext_addr [pool_type] [static-port]
- nat
- Das Schlüsselwort, das eine NAT-Regel einleitet.
- pass
- Sorgt dafür, dass übersetzte Pakete komplett von den Filterregeln
unbeachtet bleiben.
- log
- Wenn pass angegeben wird, können Pakete mittels
pflogd(8) aufgezeichnet werden. Normalerweise wird nur das erste
zutreffende Paket aufgezeichnet. Damit alle Pakete protokolliert
werden verwende log (all).
- interface
- Der Name des Netzwerk-Interfaces, auf dem die Pakete übersetzt
werden sollen.
- af
- Die Adress-Familie, entweder inet für IPv4 oder inet6
für IPv6. PF ist normalerweise in der Lage, das selbst anhand der
Quell-/Ziel-Adresse(n) herauszufinden.
- src_addr
- Die Quell- (interne) Adresse der Pakete, die übersetzt werden
sollen.
Die Quell-Adresse kann wie folgt angegeben werden:
- Eine einzelne IPv4- oder IPv6-Adresse.
- Ein
CIDR-Netzwerkblock.
- Ein ,fully qualified domain name', der per DNS aufgelöst werden kann,
wenn der Regelsatz geladen wird. Alle resultierenden IP-Adressen werden in
die Regel eingesetzt.
- Der Name eines Netzwerk-Interfaces. Jegliche IP-Adressen, die dem
Interface zugeordnet worden sind, werden in die Regel zur Ladezeit
eingesetzt.
- Der Name eines Netzwerk-Interfaces, gefolgt von
/netmask (z.B. /24). Jede IP-Adresse auf dem
Interface wird mit der Netzmaske kombiniert, um einen CIDR-Netzwerkblock
zu bilden, der in die Regel eingesetzt wird.
- Der Name eines Netzwerk-Interfaces, gefolgt von einem dieser
Modifizierer:
- :network - fügt den CIDR-Netzwerkblock ein (z.B.
192.168.0.0/24)
- :broadcast - fügt die Netzwerk-Broadcast-Adresse ein
(z.B. 192.168.0.255)
- :peer - fügt die IP-Adresse eines Peers von einem
Point-to-Point-Link ein
- Zusätzlich kann der :0-Modifizierer einem Interfacenamen
oder einem der vorher genannten Modifizierer angehängt werden, um
PF mitzuteilen, dass keine IP-Adress-Aliase mit eingefügt werden
sollen. Diese Modifizierer können ebenfalls verwendet werden, wenn
das Interface sich in Klammern befindet.
Beispiel: fxp0:network:0
- Eine Tabelle.
- Irgendeine der zuvor genannten Möglichkeiten, aber mit dem !-
(,nicht') Modifizierer.
- Ein Satz an Adressen unter Verwendung einer
Liste.
- Das Schlüsselwort any, das für alle Adressen steht
- src_port
- Der Source-Port im Layer-4-Paket-Header. Ports können wie folgt
angegeben werden:
- Eine Nummer zwischen 1 und 65535
- Ein gültiger Servicename aus
/etc/services
- Ein Satz an Ports unter Verwendung einer
Liste
- Ein Bereich:
- != (ungleich)
- < (kleiner als)
- > (größer als)
- <= (kleiner oder gleich)
- >= (größer oder gleich)
- >< (Bereich)
- <> (invertierter Bereich)
- Die letzten beiden sind Binär-Operatoren (sie nehmen zwei
Argumente) und fügen diese Argumente nicht mit in den Bereich ein.
- : (inklusiver Bereich)
- Der Operator für den inklusiven Bereich ist ebenfalls ein
Binär-Operator und fügt die Argumente mit in den Bereich ein.
Die port-Option wird normalerweise nicht in nat-Regeln
verwendet, da das Ziel normalerweise ist, NAT auf den Verkehr
auszuüben, unabhängig davon, welche Ports verwendet werden.
- dst_addr
- Die Ziel-Adresse der Pakete, die übersetzt werden sollen. Die
Ziel-Adresse wird genauso wie die Quell-Adresse angegeben.
- dst_port
- Der Ziel-Port im Layer-4-Paket-Header. Dieser Port wird genauso
wie der Quell-Port angegeben.
- ext_addr
- Die externe (Übersetzungs-)Adresse des NAT-Gateways, die die
übersetzten Pakete annehmen sollen. Die externe Adresse kann wie folgt
angegeben werden:
- Eine einzelne IPv4- oder IPv6-Adresse.
- Ein
CIDR-Netzwerkblock.
- Ein ,fully qualified domain name', der per DNS aufgelöst werden kann,
wenn der Regelsatz geladen wird. Alle resultierenden IP-Adressen werden in
die Regel eingesetzt.
- Der Name des externen Netzwerk-Interfaces. Jegliche IP-Adressen, die
dem Interface zugeordnet worden sind, werden in die Regel zur Ladezeit
eingesetzt.
- Der Name des externen Netzwerk-Interfaces in Klammern ( ).
Dies teil PF mit, dass die Regel neugeladen werden soll, wenn die
IP-Adresse(n) des genannten Interfaces sich über DHCP oder ,dial-up'
ändern, da der Regelsatz nicht immer neugeladen werden muss, wenn sich
die Adresse ändert.
- Der Name eines Netzwerk-Interfaces, gefolgt von einem dieser
Modifizierer:
- :network - fügt den CIDR-Netzwerkblock ein (z.B.
192.168.0.0/24)
- :peer - fügt die IP-Adresse eines Peers von einem
Point-to-Point-Link ein
- Zusätzlich kann der :0-Modifizierer einem Interfacenamen
oder einem der vorher genannten Modifizierer angehängt werden, um
PF mitzuteilen, dass keine IP-Adress-Aliase mit eingefügt werden
sollen. Diese Modifizierer können ebenfalls verwendet werden, wenn
das Interface sich in Klammern befindet.
Beispiel: fxp0:network:0
- Ein Satz an Adressen unter Verwendung einer
Liste.
- pool_type
- Gibt den Typ des Adress-Pools an, der
für die Übersetzung verwendet werden soll.
- static-port
- Teilt PF mit, den Quell-Port in TCP- und UDP-Paketen nicht zu
verändern.
Dies würde zu der einfachsten Form einer Zeile führen, die dieser
ähnlich sein würde:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Diese Regel besagt, dass NAT auf dem tl0-Interface für
alle Pakete ausgeführt werden soll, die von 192.168.1.0./24 aus kommen,
und sie mit der Quell-IP-Adresse von 24.5.0.5 übersetzt werden sollen.
Während die vorher genannte Regel korrekt ist, ist es keine empfohlene
Form. Die Verwaltung könnte schwierig sein, da jegliche Änderung an
den internen oder externen Netzwerknummern eine Änderung der Zeile
zur Folge hätte. Vergleiche sie stattdessen mit dieser einfacher zu
verwaltenen Zeile (tl0 ist extern, dc0 intern):
nat on tl0 from dc0:network to any -> tl0
Der Vorteil sollte recht klar sein: du kannst die IP-Adressen von
einem der Interfaces ändern, ohne die Regeln ändern zu müssen.
Wenn ein Interfacename für die Übersetzungs-Adresse wie zuvor
angegeben wird, wird die IP-Adresse zur Ladezeit von pf.conf
ermittelt, nicht während der Verwendung. Wenn du DHCP verwendet, um dein
externes Interface zu konfigurieren, kann dies zu einem Problem werden.
Wenn deine zugewiesene IP-Adresse sich ändert, wird NAT weiterhin die
Pakete, die hinausgehen, mit der alten IP-Adresse übersetzen. Dies
wird dazu führen, dass ausgehende Verbindungen nicht mehr funktionieren
werden. Um dies zu umgehen, kannst du PF sagen, dass die
Übersetzungs-Adresse automatisch aktualisiert werden soll, indem
Klammern um den Interface-Namen herum gesetzt werden:
nat on tl0 from dc0:network to any -> (tl0)
Diese Methode funktioniert für Übersetzungen von IPv4- und IPv6-Adressen.
Bidirektionales Mapping (1:1 mapping)
Ein bidirektionales Mapping kann durch die Verwendung der
binat-Regel aufgebaut werden. Eine binat-Regel
erzeugt ein eins-zu-eins-Mapping zwischen einer internen und einer
externen IP-Adresse. Dies kann sinnvoll sein, wenn beispielsweise
ein Webserver aus dem internen Netzwerk mit seiner eigenen externen
Adresse bereitgestellt werden soll. Verbindungen aus dem Internet
zur externen Adresse werden dann zur internen Adresse übersetzt und
Verbindungen vom Webserver (zum Beispiel DNS-Anfragen) werden mit
der externen Adresse übersetzt. TCP- und UDP-Ports werden niemals
mit binat-Regeln modifiziert wie es mit nat-Regeln
der Fall ist.
Beispiel:
web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Übersetzungsregel-Ausnahmen
Ausnahmen bei den Übersetzungsregeln können unter Verwendung des
no-Schlüsselwortes gemacht werden. Wenn zum Beispiel das
vorherige NAT-Beispiel so modifiziert wurde, dass es nun wie folgt
aussieht:
no nat on tl0 from 192.168.1.208 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79
Dann werden für das gesamte 192.168.1.0/24-Netzwerk alle Pakete
zur externen Adresse 24.2.74.79 übersetzt, nur nicht für 192.168.1.208.
Bedenke, dass die erste zutreffende Regel gewinnt; wenn es eine
no-Regel ist, dann wird das Paket nicht übersetzt. Das
no-Schlüsselwort kann ebenfalls mit binat-
und rdr-Regeln verwendet werden.
Den NAT-Status abfragen
Um die aktiven NAT-Übersetzungen zu betrachten, wird
pfctl(8) mit der -s state-Option verwendet. Diese Option
wird alle momentanten NAT-Sitzungen auflisten:
# pfctl -s state
fxp0 TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
fxp0 UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53 MULTIPLE:SINGLE
Erklärungen (nur die erste Zeile):
- fxp0
- Gibt das Interface an, an welches der ,state' gebunden ist. Das Wort
self wird erscheinen, wenn der ,state'
,floating' ist.
- TCP
- Das Protokoll, das von der Verbindung genutzt wird.
- 192.168.1.35:2132
- Die IP-Adresse (192.168.1.35) der Maschine im internen Netzwerk.
Der Quell-Port (2132) wird nach der Adresse angezeigt. Dies ist ebenfalls
die Adresse, die im IP-Header ersetzt wird.
- 24.5.0.5:53136
- Die IP-Adresse (24.5.0.5) und Port (53136) vom Gateway, mit denen
die Pakete übersetzt werden.
- 65.42.33.245:22
- Die IP-Adresse (65.42.33.245) und der Port (22), mit denen die
interne Maschine verbunden ist.
- TIME_WAIT:TIME_WAIT
- Dies gibt an, was PF glaubt, zu welchem ,state' die TCP-Verbindung gehört.
[Zurück: Pakete filtern]
[Inhalt]
[Weiter: Verkehr-Umleitung (Port-Weiterleitung)]
www@openbsd.org
$OpenBSD: nat.html,v 1.15 2006/05/01 12:19:17 jufi Exp $