NAT
Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:
Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
NAT, (engl. Network Address Translation, Adressumsetzung) bezeichnet die Änderung einer als Absender oder Empfänger verwendeten IP-Adresse im Kopf eines IP-Pakets. Dieser Artikel beschränkt sich auf die NAT-Arten, welche für die Funktion eines Routers auf der Grenze zwischen Internet und einem privaten Netzwerk erforderlich und sinnvoll sind.[1][2] NAT ist bei IPv4 die gebräuchliche Abhilfe bei knappen Adressen; bei IPv6 sollte man und kann auch auf die Anwendung dieser Technik verzichten.
Dieser Artikel beschreibt die Einrichtung verschiedenen NAT-Arten auf einem Linux-Rechner mit dem Werkzeug iptables; dieses dient zur Konfiguration von Netfilter im Linux-Kernel.
Hinweis:
In diesem Artikel wird dieses Szenario vorausgesetzt und diese Bezeichnungen beispielhaft verwendet:
Ein Router mit zwei Netzwerkschnittstellen:
Die Verbindung zum Internet erfolgt über die Schnittstelle
extern
mit der IP-Adresse203.0.113.255/32
. Die IP-Adresse wird vom ISP für beschränkte Zeit zugeteilt, z.B. nach 24h durch eine andere ersetzt und ist aus dem Internet erreichbar.Im privaten Netzwerk an der Schnittstelle
intern
verwenden die Rechner das Netz192.168.33.0/24
, "link-local"-Adressen aus dem Bereich169.254.0.0/16
, Multicast-Adressen224.0.0.0/4
und die "limited-broadcast"-Adresse255.255.255.255
.
Aus dem privaten Netz heraus dürfen alle Rechner Server im Internet ansprechen, wenn sie als Absender eine Adresse aus dem Bereich
192.168.33.64-192.168.33.127
verwenden.Der Rechner mit der Adresse
192.168.33.33
soll als Server über TCP auf Port 445 aus dem Internet als zuhause.example.net erreichbar sein.
Internet aus dem Privatnetz¶
Dabei muss vom Client (IP-Adresse beispielhaft: 192.168.33.64
) im privaten Netz eine Verbindung zum Server (IP-Adresse beispielhaft: 198.51.100.99
) im Internet aufgebaut werden. Zunächst ist es, auch bei fehlendem NAT, kein Problem den Server im Internet zu erreichen, denn dessen IP-Adresse ist ja im Internet bekannt. Jedoch kann dieser Server nicht antworten, weil für die privaten Adressen die Router im Internet keine Leitwege kennen. (Private Adressen werden im Internet nicht "geroutet".) Möglicherweise kennt der Router, an dem der Server selbst angeschlossen ist, einen Leitweg zu seinem (aber sicher nicht unserem!) privaten Netz 192.168.33.0/24
, dann wird die Antwort des Servers möglicherweise einen falschen Rechner erreichen oder sonst gar keinen. Damit die Antwort des Servers den anfragenden Client erreichen kann, muss man also dem Server mitteilen, die Antwort an die öffentliche Adresse 203.0.113.255
des Routers des Clients zu schicken. Dafür ist erforderlich
in jedem IP-Paket vom Client an den Server die Absender-Adresse
192.168.33.65
durch die Adresse203.0.113.255
des Routers zu ersetzen,und in jedem IP-Paket vom Server an den Router die Empfänger-Adresse
203.0.113.255
durch die Adresse192.168.33.65
des Clients zu ersetzen,und dabei die Verbindungen verschiedener Clients aus dem privaten Netz zu möglicherweise demselben Server im Internet nicht durcheinander zu mischen.
Unter Linux richtet man dafür im Netfilter des Kernels ein "statefull source NAT" ein. ("statefull", weil die Verbindungen gemerkt werden müssen und "source", weil bei der Anfrage die Adresse des Absenders umgeschrieben wird.) Das geht z.B. mit iptables [3][4][5]:
iptables --table nat --append POSTROUTING --src 192.168.33.64/26 -o extern -j MASQUERADE
Das ist alles. Es wird nur dieser eine Befehl benötigt, der automatisch auch für die richtige Bearbeitung der eintreffenden Antworten sorgt. Der Befehl kann wahlweise auch noch kürzer geschrieben werden:
iptables -t nat -A POSTROUTING -s 192.168.33.64/26 -o extern -j MASQUERADE
MASQUERADE
ist ein Spezialfall für "source NAT". Bei MASQUERADE
wird als neuer Wert für die Adresse des Absenders automatisch die Adresse der sendenden Schnittstelle gewählt. Alternativ könnte man auch verwenden:
iptables -t nat -A POSTROUTING -s 192.168.33.64/26 -o extern -j SNAT --to-src 203.0.113.255
SNAT
arbeitet effektiver als MASQUERADE
, weil der neue Wert für die Adresse nur einmalig und nicht für jedes IP-Paket bestimmt werden muss. Dafür ist MASQUERADE
bequemer anzuwenden und hat den Vorteil, bei einer Zwangstrennung und erneutem Aufbau der Internetverbindung die Verbindungstabelle zu löschen und ist deshalb für die hier angenommene Aufgabenstellung optimal.
Der Bereich der umzusetzenden Adressen kann nicht immer wie in diesem Beispiel (192.168.33.64/26 = 192.168.33.64-192.168.33.127
) als Netzwerk geschrieben werden. In solchen Fällen kann man ein Netzwerk angeben, welches den zulässigen Bereich vollständig enthält (im Beispiel möglich: 192.168.33.0/25
) und man sollte dann mit weiteren Netfilter-Regeln dafür sorgen, dass die unzulässigen Adressen den NAT-Befehl nicht erreichen. Eine bessere Variante ist es, auf die Option --src
zu verzichten und den Adressbereich mit Hilfe des Moduls iprange festzulegen:
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.33.64-192.168.33.127 -o extern -j MASQUERADE
Für jede Verbindung wird die Netfilter-Regel zur Einrichtung des NAT nur ein einziges Mal „ausgeführt“; alle folgenden IP-Pakete werden direkt im Netfilter-Modul conntrack bearbeitet.
Linux löst mit diesem Befehl die Aufgabenstellung so gut es geht, denn leider ist die Aufgabe nicht allgemein lösbar:
Bei einem Client funktioniert es problemlos.
Bei mehreren Clients funktioniert der Verkehr zu unterschiedlichen Servern auch problemlos.
Wenn mehrere Clients zum selben Server eine Verbindung aufbauen wollen,
Das hier beschriebene, und auch bei Linux angewendete NAT modifiziert also den IP-Header (d.h. die IP-Adressen) und für seine interne Buchführung auch (manchmal oder immer, abhängig von der Implementierung) die Nutzlast im IP-Paket. Es wird deshalb auch als P-NAT, PAT, NAT/PT bezeichnet (engl. Port and (Network) Address Translation bzw. Network Address Translation with Port Translation).
Es gibt bei iptables noch die Targets SAME
und NETMAP
, welche ebenfalls Source-NAT ermöglichen:
SAME
bietet erst dann Vorteile im Vergleich zuSNAT
, wenn man über mehrere öffentliche IP-Adressen verfügt.NETMAP
ist für die hier besprochene Aufgabe nicht anwendbar, weil die Verbindungstabelle gemerkt werden muss,NETMAP
aber zustandslos arbeitet.
Server im Privatnetz¶
Der Server 192.168.33.33
im Privatnetz ist natürlich für Rechner im LAN problemlos zu erreichen, aber aus dem Internet gibt es keinen Weg zu ihm. Es muss zunächst die täglich wechselnde vom ISP geliehene öffentliche IP-Adresse (heute: 203.0.113.255/32
) unter dem gleichbleibenden DNS-Namen zuhause.example.net
veröffentlicht werden. Dafür muss auf dem Router ein DynDNS-Client installiert werden.
Der Router muss außerdem speziell konfiguriert werden:
Für jedes TCP-Paket mit Zielport
445
muss im einhüllenden IP-Paket mit der Adresse des Routers203.0.113.255/32
als Zieladresse diese auf die interne IP-Adresse des Servers192.168.33.33
geändert werden,und in jedem TCP-Paket vom Absenderport
445
muss im einhüllenden IP-Paket die Absender-Adresse192.168.33.33
ersetzt werden durch die öffentliche Adresse des Routers.
Diese Aufgabe kann auf dem Router mit einem "stateless destination NAT" gelöst werden. ("stateless", weil keine Tabelle mit bestehenden Verbindungen gepflegt werden muss und "destination", weil bei der Anfrage die Empfängeradresse umgeschrieben wird.)
Dies wird bei Hardware-Routern auch „Portfreigabe“ oder „Portweiterleitung“ genannt, deren Einrichtung über eine Weboberfläche in einem eigenen Artikel beschrieben wird.
Unter Linux wird dies im Netfilter des Kernels z.B. mit iptables konfiguriert:
iptables --table nat --insert PREROUTING --protocol tcp --dport 445 --dst 203.0.113.255/32 -j NETMAP --to 192.168.33.33/32 iptables --table nat --insert POSTROUTING --protocol tcp --sport 445 --src 192.168.33.33/32 -j NETMAP --to 203.0.113.255/32
Alternativ kürzer:
iptables -t nat -I PREROUTING -p tcp --dport 445 -d 203.0.113.255/32 -j NETMAP --to 192.168.33.33/32 iptables -t nat -T POSTROUTING -p tcp --sport 445 -s 192.168.33.33/32 -j NETMAP --to 203.0.113.255/32
NETMAP
arbeitet zustandslos; deshalb muss man bei dieser Methode Hin- und Rückrichtung konfigurieren.
Hinweis:
Achtung! NETMAP
ändert nicht die mit --dst
bsw --src
angegebenen Adressen in die mit --to
angegebenen Adressen!
Sondern:
In
PREROUTING
wird die Empfänger-Adresse des Pakets geändert.In
POSTROUTING
wird die Absender-Adresse des Pakets geändert.Änderung bedeutet in beiden Fällen, dass die ursprünglichen und die neuen Werte gemäß der mit
--to
angegebenen Netzmaske gemischt werden; dabei wird der Netzwerkteil auf den neuen Wert geändert und der Host-Anteil beibehalten.
In den oben angegebenen Befehlen dienen die Angaben mit --src
bzw. --dst
lediglich zur Selektion der Pakete, bei denen die Regel greifen soll.
Die Aufgabe kann man mit alternativer Methode auch mit dem eigentlich zu mächtigen, weil zustandsbehaftet arbeitenden DNAT
lösen:
iptables --table nat --append PREROUTING --protocol tcp --dport 445 --dst 203.0.113.255 -j DNAT --to-dst 192.168.33.33
Alternativ kürzer:
iptables -t nat -A PREROUTING -p tcp --dport 445 -d 203.0.113.255 -j DNAT --to-dst 192.168.33.33
Bei beiden Methoden ist natürlich die Erfordernis zur Angabe der externen Adresse des Routers unschön, da man diese bei Einwahlverbindungen über z.B. DSL oder Funktelefonnetzen vorher nicht kennt und deshalb nicht statisch konfigurieren kann. Abhilfen:
Entweder: Man ändert die Konfiguration seines Routers dynamisch nach jedem Einwahlvorgang. Die Erstellung eines für die individuelle Situation passenden Skripts wird dem Leser als Übungsaufgabe überlassen.
Oder: Man benutzt die DNAT-Methode, arbeitet aber bei der Paket-Selektion unsauber, indem man die Option
--dst
einfach weg lässt. Zum Ausgleich verwendet man bei seinem Server einen ungewöhnlichen Port, der von anderen Clients niemals für andere Zwecke benutzt wird.Oder: Man benutzt die DNAT-Methode ohne die Option
--dst
, sondern selektiert die Pakete über die empfangende Schnittstelle"--i extern"
. Dann sollte man aber vor der NAT-Regel mit zusätzlichen Regeln alle Pakete mit anderen Zieladressen als die der empfangenden Schnittstelle ausfiltern.
Es gibt bei iptables auch noch das Target REDIRECT
zur Einrichtung eines speziellen Destination-NAT. Hierbei wird als Zieladresse immer automatisch die IPv4-Adresse der empfangenden Schnittstelle des Rechners ausgewählt.
Alle NAT-Targets erlauben zusätzlich zur Umschreibung der Adressen auch eine Änderung des Ports. Die Details sind in den Manpages von iptables beschrieben:
man iptables man iptables-extensions
Links¶
NAT 🇩🇪
The netfilter.org project 🇬🇧 – Projektseite von Linux-Netfilter, iptables, nftables.