Warum reserviert NAT keine Ports aus dem TCP- und UDP-Portpool des Computers?


8

Ich habe zwei Experimente gemacht. Dies ist das Netzwerk für beide:

        [private network]     [public network]
    A -------------------- R ----------------- B
192.168.0.5     192.168.0.1|192.0.2.1       192.0.2.8

A ‚s Standard - Gateway ist R . In R ist die IPv4-Weiterleitung aktiv und die folgende iptables-Regel gilt:

iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 50000

Die Absicht ist es , alles , was TCP von A wird als 192.0.2.1 mit maskierenden R ‚s - Port 50000.

Ich habe einen TCP-Dienst auf Port 60000 auf B mit veröffentlicht nc -4l 192.0.2.8 60000.

Dann habe ich eine Verbindung von A geöffnet :nc -4 192.0.2.8 60000

A begann Pakete zu senden, die so aussahen:

192.168.0.5:53269 -> 192.0.2.8:60000

R übersetzte das in

192.0.2.1:50000 -> 192.0.2.8:60000

So weit, ist es gut.

Ich habe dann versucht, den folgenden Client auf R zu öffnen : nc -4 192.0.2.8 60000 -p 50000. Ich habe Nachrichten gesendet, nichts passiert. Keine Pakete können auf zu sehen ist R ‚s tcpdump.

Da die Maskerade Regel vorhanden ist , oder zumindest , weil es aktiv ist, hätte ich erwartet , dass R ‚s nc mit der Fehlermeldung fehlschlagen‚nc: Adresse bereits in Verwendung‘, das ist das, was , wenn ich auf den gleichen Port binden zwei NCS geschieht.

Ich habe dann eine Weile gewartet, damit die Kartierung von conntrack sterben würde.

Das zweite Experiment auf mir bestand zu öffnen versucht , R zuerst ‚s - Client. R beginnt ganz gut mit B zu reden . Wenn ich dann die Verbindung von A aus öffne , werden die Pakete ignoriert. A ‚s SYNs bei ankommen R , aber sie werden nicht beantwortet, auch nicht von ICMP - Fehler. Ich weiß nicht, ob dies daran liegt, dass R weiß, dass die Maskierungsports nicht mehr ausreichen oder dass Linux nur völlig verwirrt ist (es maskiert den Port technisch, aber die bereits hergestellte Verbindung stört irgendwie).

Ich denke, das Verhalten des NAT ist falsch. Ich könnte versehentlich einen Port sowohl für die Maskierung (insbesondere durch Nichtangabe --to-portswährend der iptables-Regel) als auch für einen Dienst konfigurieren , und der Kernel wird Verbindungen stillschweigend trennen. Ich sehe auch nichts davon irgendwo dokumentiert.

Zum Beispiel:

  • A macht eine normale Anforderung an B . R- Masken mit Port 50k.
  • A macht eine DNS - Abfrage an R . Da T rekursiv ist, fragt R (mit rein zufälligem kurzlebigen Port 50k) den autorisierenden Nameserver Z an Port 53 ab.

Eine Kollision ist gerade passiert; R verwendet jetzt Port 50k für zwei separate TCP-Verbindungen.

Ich denke, das liegt daran, dass Sie normalerweise keine Dienste auf Routern veröffentlichen. Aber würde es dem Kernel schaden, den Port aus dem TCP-Port-Pool zu "leihen", wenn er aktiv maskiert wird?

Ich weiß, dass ich meine kurzlebigen Ports von meinen trennen kann --to-ports. Dies scheint jedoch nicht das Standardverhalten zu sein. Sowohl NAT als auch die kurzlebigen Ports sind standardmäßig 32768-61000, was gruselig ist.

(Ich habe den kurzlebigen Bereich durch Abfragen von / proc / sys / net / ipv4 / ip_local_port_range und den NAT-Bereich durch einfaches NATen vieler UDP-Anforderungen in einem separaten Experiment gefunden - und den Quellport auf der Serverseite gedruckt. Ich konnte ihn nicht finden eine Möglichkeit, den Bereich mit iptables zu drucken.)


2
Warum ist es gruselig, dass NAT den ethemeralen Portbereich verwendet? Wenn ein Client auf A einen ethemeral Port verwendet, der auch auf R verwendet wird, wird er auf einen neuen NAT NATed. Und warum hat ein Dienst wie DNS oder DHCP auf R etwas damit zu tun? DNS und DHCP verwenden keine kurzlebigen Ports (auf der Serverseite). Und warum nur einen einzigen Port zum Maskieren verwenden?
Thomas Erker

@Thomas: Ihre Fragen haben mich tatsächlich in die richtige Richtung geführt, und ich bin sehr dankbar, aber es scheint, dass Sie auch ein leichtes Missverständnis haben: Wenn ein Client auf A einen kurzlebigen Port verwendet, der auch auf R verwendet wird, muss dies nicht unbedingt der Fall sein Holen Sie sich NATed zu einem neuen; NAT fragt die TCP / UDP-Portpools nicht ab. Mir ist tatsächlich aufgefallen, dass kollidierende NAT-Verbindungen normal und harmlos sind. siehe meine Antwort.
Yd Ahhrk

@ Thomas: Ich habe DHCP nicht durchdacht; Ich habe tatsächlich über DNS nachgedacht. Ich stelle mir vor, dass DNS kurzlebige Ports verwendet, wenn es sich um einen rekursiven Nameserver handelt (um die autorisierenden abzufragen). siehe meine Bearbeitung.
Yd Ahhrk

@Thomas: Das ganze Experiment soll sehen, was passiert, wenn es zu Kollisionen kommt. Ich habe die kurzlebige Reichweite auf einen einzigen Port reduziert, um die Kollision zu erzwingen.
Yd Ahhrk

Antworten:


2

Würde es dem Kernel schaden, den Port aus dem TCP-Port-Pool zu "leihen", wenn er aktiv maskiert wird?

Ich denke die Antwort ist "nein, aber es macht nicht viel aus."

Ich habe fälschlicherweise angenommen, dass R nur die Zieltransportadresse des Antwortpakets verwendet hat, um festzustellen, ob es in Richtung A oder selbst geleitet wurde. Es scheint tatsächlich das gesamte Quell-Ziel-Transportadressen-Tupel zu verwenden, um eine Verbindung zu identifizieren. Daher ist es für NAT eigentlich normal, mehrere Verbindungen über denselben ( R- eigenen) Port zu erstellen . es schafft keine Verwirrung. Folglich spielen die TCP / UDP-Portpools keine Rolle.

Es ist jetzt ziemlich offensichtlich, dass ich darüber nachdenke.

Ich habe dann versucht, den folgenden Client auf R zu öffnen : nc -4 192.0.2.8 60000 -p 50000. Ich habe Nachrichten gesendet, nichts passiert. Keine Pakete können auf zu sehen ist R ‚s tcpdump.

Dies ist der Teil der Experimente, in dem ich es vermasselt habe.

Der Fehler tritt auf, weil sowohl die Quell- als auch die Zieltransportadresse identisch sind, nicht nur, weil die Quelladresse identisch ist.

Wenn ich das tue, nc -4 192.0.2.8 60001 -p 50000funktioniert es tatsächlich. Auch wenn es denselben Port wie eine NAT-Maske verwendet.

Ich denke, das Verhalten des NAT ist falsch. Ich könnte versehentlich einen Port sowohl für die Maskierung (insbesondere durch Nichtangabe --to-portswährend der iptables-Regel) als auch für einen Dienst konfigurieren , und der Kernel wird Verbindungen stillschweigend trennen.

Dies ist nicht der Fall , da die maskierten Verbindungen und die R- gestarteten Verbindungen höchstwahrscheinlich unterschiedliche Ziele haben.

Da die Maskerade Regel vorhanden ist , oder zumindest , weil es aktiv ist, hätte ich erwartet , dass R ‚s nc mit der Fehlermeldung fehlschlagen‚nc: Adresse bereits in Verwendung‘, das ist das, was , wenn ich auf den gleichen Port binden zwei NCS geschieht.

Ich bin immer noch auf der Suche nach einer kugelsicheren Antwort darauf, aber alles scheint darauf hinzudeuten, dass "dies eine nachteilige Folge der Implementierung ist und so klein, dass wir bereit sind, damit zu leben".

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.