Wann genau wird PMTUD durchgeführt? (Pfad MTU Entdeckung)

21

In Diskussionen, die sich aus anderen Fragen auf dieser Website ergeben haben , habe ich festgestellt, dass ich nicht genau weiß, wann Path MTU Discovery (PMTUD) ausgeführt wird.

Ich weiß, was es tut - finde die niedrigste MTU auf einem Pfad von Client zu Server).
Ich weiß, wie es funktioniert - senden Sie progressiv größere Pakete mit gesetztem Bit "Don't Fragment" und sehen Sie, wie groß ein Paket sein kann, ohne den Fehler "ICMP Need to Fragment" zu erhalten.

Meine Frage lautet dann konkret: Wann wird ein Host PMTUD durchführen?

Ich suche nach bestimmten Fällen. Nicht nur so etwas wie "Wenn ein Host den Pfad MTU entdecken will". Bonuspunkte, wenn Sie eine Paketerfassung eines Hosts bereitstellen oder Anweisungen zum Generieren einer solchen Paketerfassung bereitstellen können.

Außerdem beziehe ich mich speziell auf IPv4. Ich weiß, dass transiente IPv6-Router nicht für die Fragmentierung verantwortlich sind, und kann mir vorstellen, dass PMTUD viel häufiger vorkommt. Im Moment suche ich nach konkreten Beispielen für PMTUD in IPv4. (obwohl, wenn die einzige Paketerfassung, die Sie von PMTUD zusammenstellen können, in IPv6 ist, würde ich es immer noch gerne sehen)

Eddie
quelle
Wird PMTUD von der niedrigsten unterstützten MTU zur höchsten durchgeführt? Oder versucht das Gerät, das PMTUD durchführt, zuerst die größte MTU und tritt dann in großen Schritten zurück, bis das Paket durchgelaufen ist, und dann in kleineren Schritten vor und zurück, bis eine endgültige Bestimmung erfolgt ist?
cpt_fink
@cpt_fink, es gibt ein paar Strategien. Moderne Implementierungen der ICMP Fragmentation Needed-Nachricht enthalten in der ICMP-Nutzlast selbst die MTU der Verbindung, für die die Fragmentierung erforderlich war. Das macht es einfach, denn der Starthost weiß sofort, wie die MTU vor sich geht. Ältere Implementierungen müssen verschiedene Strategien verwenden, um nach der richtigen MTU zu suchen. Diese Strategien werden in RFC1191 in Abschnitt 5 beschrieben. Sie reichen von der automatischen Standardeinstellung bis zum IP-Minimum (576) bis zur Verwendung einer Tabelle mit "allgemeinen" MTUs für eine effizientere Suche (siehe RFC1191, Abschnitt 7.1).
Eddie
2
Das ist eine interessante Frage. Ich grub ein bisschen in PMTUD und fand es. Obwohl es alt ist, habe ich beschlossen zu antworten, weil ich genau die gleiche Frage hatte und nach einigen Stunden Nachforschungen eine ziemlich anständige Antwort finden konnte (denke ich). Ich werde versuchen, meine Antwort morgen mit einer Paketerfassung zu aktualisieren und zu unterstützen, falls dies möglich ist.
Filipe Gonçalves

Antworten:

15

Die Antwort ist einfach: wann immer der Gastgeber will. Ja wirklich. So einfach ist das.

In der folgenden Erläuterung wird eine reine IPv4-Umgebung vorausgesetzt, da IPv6 die Fragmentierung in den Routern beseitigt (und der Host gezwungen ist, sich immer mit Fragmentierung und MTU-Erkennung zu befassen).

Es gibt keine strikte Regel, die regelt, wann (oder sogar wenn) ein Host die Pfad-MTU-Ermittlung durchführt. Der Grund, warum PMTUD aufgetaucht ist, ist, dass Fragmentierung aus verschiedenen Gründen als schädlich angesehen wird . Um eine Paketfragmentierung zu vermeiden, wurde das Konzept von PMTUD als Workaround ins Leben gerufen. Natürlich, ein schönes Betriebssystem sollte PMTUD verwenden Fragmentierung zu minimieren.

Daher hängt die genaue Semantik der Verwendung von PMTUD natürlich vom Betriebssystem des Absenders ab - insbesondere von der Socket-Implementierung. Ich kann nur für den speziellen Fall von Linux sprechen, aber andere UNIX-Varianten sind wahrscheinlich nicht sehr unterschiedlich.

Unter Linux wird PMTUD über die IP_MTU_DISCOVERSocket-Option gesteuert . Sie können den aktuellen Status mit abrufen, getsockopt(2)indem Sie die Stufe IPPROTO_IPund die IP_MTU_DISCOVEROption angeben. Diese Option ist SOCK_STREAMnur für Sockets gültig (ein SOCK_STREAMSocket ist ein bidirektionaler, verbindungsorientierter, zuverlässiger Socket; in der Praxis ist es ein TCP-Socket, obwohl andere Protokolle möglich sind). Wenn diese Option festgelegt ist , führt Linux PMTUD genau so aus, wie in RFC definiert 1191.

Beachten Sie, dass PMTUD in der Praxis ein kontinuierlicher Prozess ist. Pakete werden mit gesetztem DF-Bit gesendet, einschließlich der 3-Wege-Handshake-Pakete. Sie können sich dies als Verbindungseigenschaft vorstellen (obwohl eine Implementierung möglicherweise bereit ist, irgendwann einen bestimmten Fragmentierungsgrad zu akzeptieren und das Senden von Paketen mit dem DF zu beenden Bit gesetzt). Somit ist PMTUD nur eine Folge der Tatsache, dass alles auf dieser Verbindung mit DF gesendet wird.

Was ist, wenn Sie nicht einstellen IP_MTU_DISCOVER?

Es gibt einen Standardwert. Standardmäßig IP_MTU_DISCOVERist für SOCK_STREAMSockets aktiviert . Dies kann durch Lesen gelesen oder geändert werden /proc/sys/net/ipv4/ip_no_pmtu_disc. Ein Nullwert bedeutet, dass IP_MTU_DISCOVERin neuen Sockets standardmäßig aktiviert ist. ein ungleich Null bedeutet das Gegenteil.

Was ist mit verbindungslosen Steckdosen?

Dies ist schwierig, da verbindungslose, unzuverlässige Sockets verlorene Segmente nicht erneut übertragen. Es liegt in der Verantwortung des Benutzers, die Daten in MTU-großen Blöcken zu paketieren. Es wird auch erwartet, dass der Benutzer die erforderlichen Neuübertragungen im Falle eines zu großen Nachrichtenfehlers vornimmt. Daher muss der Benutzercode PMTUD im Wesentlichen neu implementieren. Wenn Sie für die Herausforderung bereit sind, können Sie das DF-Bit erzwingen, indem Sie das IP_PMTUDISC_DOFlag an übergeben setsockopt(2).

Die Quintessenz

  • Der Host entscheidet, wann (und ob) PMTUD verwendet wird
  • Wenn es PMTUD verwendet, ist es wie ein Verbindungsattribut, es passiert ununterbrochen (aber die Implementierung kann jederzeit damit aufhören).
  • Verschiedene Betriebssysteme verwenden unterschiedliche Ansätze, aber normalerweise führen zuverlässige, verbindungsorientierte Sockets standardmäßig PMTUD aus, während unzuverlässige, verbindungslose Sockets dies nicht tun
Filipe Gonçalves
quelle
4

In der Regel erfolgt die Ermittlung der maximalen Pfadübertragungseinheit (PMTUD) immer dann, wenn ein Host denkt, dass ein Paket verworfen wurde, weil es zu groß ist.

Dies kann eine Reaktion auf die ICMP-Fragmentierung sein, die erforderlich ist (Typ 3, Code 4) und die explizit angibt, dass das Paket verworfen wurde. In der typischen Praxis werden alle IPv4-Pakete mit dem gesetzten DF-Flag (Don't Fragment) gesetzt, sodass jedes Paket, das die MTU überschreitet, eine solche Antwort hervorruft. IPv6 unterstützt überhaupt keine Fragmentierung.

Einige Router oder Host-Firewalls lassen ICMP häufig fallen, da ein naiver Administrator ICMP als Sicherheitsrisiko ansieht . Einige Linkaggregationsschemata können die ICMP-Übermittlung beeinträchtigen . In RFC4821 wird ein alternativer Mechanismus zum Erkennen der MTU vorgeschlagen, der nicht auf ICMP basiert .

tracepathist mein Lieblings-Linux-Tool zum Testen von MTU. Hier ist ein Beispiel von einem Host mit einer 9001-MTU im LAN, der jedoch ein IPsec-VPN durchlaufen muss, um 10.33.32.157 zu erreichen:

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

Die ICMP-Fehler können beobachtet werden bei tcpdump:

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

MTU-Entdeckungen werden zwischengespeichert. In Linux kann dies beobachtet und mit gelöscht werden ip(Vorsicht vor Änderungen seit Linux 3.6 ):

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

Bei TCP kann das Überschreiten der MTU im Rahmen des Verbindungsaufbaus vermieden werden. In der von jedem Ende gesendeten SYN ist eine maximale Segmentgröße (MSS) enthalten. Der TCP-Header (20 Byte ohne Optionen ) und der IP-Header (20 Byte) bedeuten, dass MSS und MTU um 40 Byte voneinander abweichen.

Hier ist ein Beispiel für einen Verbindungsaufbau zwischen diesen beiden Hosts beim Übertragen einer großen Datei mit scp:

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

Im ersten Paket schlägt der lokale Host einen MSS von 8961 vor. Dies ist die konfigurierte 9001-MTU, abzüglich 40 Bytes. Das zurückgegebene SYN / ACK hat eine MSS von 1379, was eine MTU von 1419 bedeutet. Ich weiß, dass in diesem Netzwerk der Remote-Host ebenfalls 8961 gesendet hat, aber der Wert wurde von einem Router geändert, da er weiß, dass der Pfad einen Internetpfad enthält ( MTU 1500) ein Overhead von einem IPsec-Tunnel. Dieser Router hat auch unser gesendetes MSS von 8961 so geändert, dass es auf dem anderen Host als 1419 angezeigt wird. Dies wird als MSS-Klemmung bezeichnet .

In gewissem Sinne passiert PMTUD die ganze Zeit. In der Praxis kann es tatsächlich niemals vorkommen, wenn MSS-Clamping vorhanden ist und der gesamte Datenverkehr über TCP erfolgt oder keiner der Router eine MTU aufweist, die kleiner ist als die auf den Endpunkten konfigurierten Werte. Auch ohne MSS-Clamping kann es nur selten vorkommen, dass der Cache abläuft.

Phil Frost
quelle