ubuntuusers.de

NAT

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

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-Adresse 203.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 Netz 192.168.33.0/24, "link-local"-Adressen aus dem Bereich 169.254.0.0/16, Multicast-Adressen 224.0.0.0/4 und die "limited-broadcast"-Adresse 255.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 Adresse 203.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 Adresse 192.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,

    • kann der Router bei Protokollen mit Ports (UDP, DCCP, TCP, SCTP) diese meistens über den Quellport unterscheiden,

    • und in den seltenen Fällen mit demselben Quellport zusätzlich diesen ändern,

    • jedoch bei Protokollen ohne Port zeitgleich nur eine einzige derartige Verbindung zulassen.

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 zu SNAT, 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 Routers 203.0.113.255/32 als Zieladresse diese auf die interne IP-Adresse des Servers 192.168.33.33 geändert werden,

  • und in jedem TCP-Paket vom Absenderport 445 muss im einhüllenden IP-Paket die Absender-Adresse 192.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 

Diese Revision wurde am 26. Februar 2023 12:34 von struland erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Netzwerk, Internet, Router