So verhindern Sie, dass Netfilter die Quellports automatisch ändert

So verhindern Sie, dass Netfilter die Quellports automatisch ändert

Ich habe beobachtet, dass Netfilter den Quellport ändert, wenn im Conntrack-Modul eine Verbindung hergestellt wird. Dieses Verhalten muss ich verhindern.

Folgendes habe ich getan, um mein Problem zu reproduzieren:

  1. Ich erstelle eine Netfilter-Regel, die DNAT von Port 2002 bis 2003 ausführt

sudo iptables -w -t nat -A OUTPUT -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001 --dport 2002 -j DNAT --to-destination :2003

  1. Ich erstelle dann einen Conntrack-Eintrag, um eine Verbindung von 192.168.30.1:2001 (Mein Computer) zu 192.168.30.1:2003 zu simulieren

sudo /sbin/conntrack -I -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 --timeout 100000

  1. Abschließend stelle ich von meinem Rechner mit Quellport 2001 eine Verbindung zu 192.168.30.1:2002 her:

sudo nc -u -p 2001 192.168.30.1 2002

Aufgrund der Netfilter-DNAT-Regel habe ich ein Ausgabepaket mit Zielport 2003 und Quellport 2001 erwartet. Bei Wireshark habe ich jedoch beobachtet, dass sich der Quellport in eine zufällige Zahl geändert hat. Ich vermute, das liegt daran, dass mein Computer davon ausgeht, dass auf Port 2001 eine Verbindung besteht (aufgrund des Conntrack-Eintrags) und dann verhindert, dass der Quellport 2001 ist (richtig?). Aber ich möchte dieses Verhalten nicht? Wie kann ich die Verwendung der Portnummer 2001 erzwingen?

Antwort1

Damit DNAT funktioniert (in dem Sinne, dass das Programm die Antworten erkennen kann), muss „Reverse NAT“ durchgeführt werden , das den Quellport des Antwortverkehrs von 192.168.30.1(nach 192.168.30.3:2001) von 2003nach ändert.2002

Wenn jedoch Datenverkehr von dort kommt, der 192.168.30.1:2003aus 192.168.30.3:2001Sicht von Conntrack keine Folge des DNAT ist (weil der Host laut erstelltem Conntrack-Eintrag nicht derjenige ist, der die Verbindung initiiert hat), ist das Reverse-NAT ungeeignet.

Daher wird Netfilter „gezwungen“, auch SNAT für den Datenverkehr auszuführen, der der DNAT-Regel entspricht, damit es den antwortenden Datenverkehr (der ebenfalls von stammt 192.168.30.1:2003) nach dem Ziel unterscheiden kann 192.168.30.3:$random.

Ich gehe davon aus, dass Netfilter entweder Reverse NAT für DNAT (was ein SNAT ist) vor Reverse NAT für SNAT (was ein DNAT ist) durchführt oder es schafft, das Ziel vor dem Reverse NAT für SNAT (also 192.168.30.3:$random) als Matching für das Reverse NAT für DNAT zu verwenden, da das erzwungene SNAT sonst sinnlos ist. (Im Fall einer Nichtumkehrung trifft meines Wissens jedoch keines davon zu: DNAT wird in PREROUTING vor SNAT in INPUT durchgeführt, und das Zielmatching in der SNAT-Regel, falls vorhanden, verwendet den im DNAT resultierenden Wert.)


Die Sache ist, dass die obige Geschichte / das „Problem“ in Ihrer Frage in der Realität kaum Sinn ergibt. Nehmen wir als Beispiel ein Wireguard-VPN mit zwei Hosts: Angenommen, Sie möchten Endpoint=auf beiden Hosts eine Einstellung haben (damit einer von beiden die Kommunikation initiieren kann) und möchten nicht, dass die Werte aufgrund des erzwungenen SNAT unerwartet „aktualisiert“ werden (vorausgesetzt, dies könnte tatsächlich ausgelöst werden), sollten Sie einfach ein „Always-On“-SNAT verwenden, das DNAT „ergänzt“ / dem Reserve-NAT entspricht:

iptables -t nat -A INPUT -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 -j SNAT --to-source :2002

was im Client-Server-Modell aufgrund des automatischen Reverse-NAT für das DNAT normalerweise nicht erforderlich ist.

PS: Sie sollten trotzdem nicht 192.168.30.1:2003bis erreichen 192.168.30.1:2003, da sonst das erzwungene Quell-NAT auch dann auftritt, wenn Sie es erneut bis erreichen, 192.168.30.1:2002bevor der Conntrack-Eintrag des vorherigen gelöscht wird. Die zusätzliche SNAT-Regel in INPUT sollte Ihnen auch keine zusätzlichen Probleme bereiten.

Antwort2

Sie können zwei Flows festlegen, die normalerweise in derKontaktLookup-Tabelle (was normalerweise eine Neuschreibung des Quellports im neuen Flow auslöst, um die Kollision zu vermeiden) in verschiedenenConntrack-Zonen. Diese zusätzliche Zoneneigenschaft machtKontaktstimmt nicht mit einem vorhandenen Flow in einer anderen Conntrack-Zone überein/kollidiert nicht mit diesem: Es erfolgt keine Neuschreibung des Quellports.

Für Ihr konkretes Beispiel ist hier eine spezielle Regel, die die Kollision und damit das Neuschreiben des Quellports verhindert:

iptables -t raw -A OUTPUT -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001  --dport 2002 -j CT --zone-orig 1

Normalerweise wird je nach Anwendungsfall ein sinnvollerer Selektor verwendet. Er wird häufig in der PREROUTING-Kette mit einer eingehenden Schnittstelle als Selektor beim Routing verwendet und oft mit einem Markierungswert verknüpft, sodass auch das Routing beeinflusst werden kann.


Der ursprüngliche Anwendungsfall, der diese Option erforderlich machte, ist, wennKontaktauf demselben Netzwerkstapel (kein zusätzlicher Netzwerk-Namespace) mit einem komplexen Routing-Setup (z. B. Routing zwischen 4 verschiedenen privaten LANs mit denselben IP-Adressen, z. B. zwischen 192.168.1.0/24 eth0 <-> eth1 10.1.0.0/24 undwieder192.168.1.0/24 eth2 <-> 10.1.0.0/24 eth3) kann zwei unabhängige Flüsse mit denselben Adressen/Ports sehen.NetzfilterUndKontaktweiß nichts über Routing (dieKontaktLookup-Tabelle enthält nur Adressen), müssen sie lernen, diese Flüsse separat zu berücksichtigen, indem sie eine Zoneneigenschaft hinzufügen, die manuell an die Routing-Topologie in derKontaktNachschlagwerk.

(Hier ist einLWN-Linkals die Funktion ursprünglich vorgeschlagen wurde.)

Antwort3

NAT ändert den Quellport, um das Risiko eines Portkonflikts zu verringern. Was soll passieren, wenn dieser Port 2002 auf der NAT-Maschine bereits belegt ist?

Wenn Sie spezielle Anforderungen für bestimmte Ports haben, können Sie SNATdafür spezielle Regeln hinzufügen. Was aber, wenn mehrere interne Clients versuchen, denselben Quellport zu verwenden?

Hier sollten wir zurückgehen und anerkennen, dass NAT ein Hack ist, der entwickelt wurde, um das Problem des Mangels an öffentlichen IP-Adressen zu verringern. Die eigentliche Lösung besteht darin, dass jeder öffentliche IPs ohne NAT hat.

Wenn wir heutzutage von NAT sprechen, meinen wir meistens private IP-Adressen hinter einer IP. In diesen Fällen ist es eigentlichNAPT AÄhnliche Frage dazu, ich dachte an MASQUERADEdas Ziel und nichtDNAT

verwandte Informationen