[[Vorlage(Getestet, general)]] {{{#!vorlage Wissen [:Router:] [:Router/Multifunktionsgerät:] [:Programme_starten: Starten von Programmen] [:Terminal: Ein Terminal öffnen] [:mit Root-Rechten arbeiten:] }}} [[Inhaltsverzeichnis()]] [#Links 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 [:iptables2:iptables]; dieses dient zur Konfiguration von [#Links Netfilter] im Linux-Kernel. {{{#!vorlage 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 [#Server-im-Privatnetz 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]: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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 ([#Links UDP], [#Links DCCP], [#Links TCP], [#Links 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-Router:Hardware-Routern] auch „Portfreigabe“ oder „Portweiterleitung“ genannt, deren Einrichtung über eine Weboberfläche [:Portweiterleitung:in einem eigenen Artikel] beschrieben wird. Unter Linux wird dies im Netfilter des Kernels z.B. mit '''iptables''' konfiguriert: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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. {{{#!vorlage 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl man iptables man iptables-extensions }}} = Links = * [wikipedia:Network_Address_Translation:NAT] {de} * [https://www.netfilter.org/ The netfilter.org project] {en} – Projektseite von Linux-Netfilter, iptables, nftables. * [wikipedia:User_Datagram_Protocol:UDP – User Datagram Protocol] {de} * [wikipedia:Datagram_Congestion_Control_Protocol:DCCP – Datagram Congestion Control Protocol] {de} * [wikipedia:Transmission_Control_Protocol:TCP – Transmission Control Protocol] {de} * [wikipedia:Stream_Control_Transmission_Protocol:SCTP – Stream Control Transmission Protocol] {de} # tag: Netzwerk, Router, Internet