Zum Inhalt springen

IP/Fragmentierung

Aus Foxwiki
Die 5 zuletzt angesehenen Seiten:  SQL/Ändern » Disclosure » Nmap/Zusatzfunktionen » Typo3/Backend » IP/Fragmentierung

IP/Fragmentierung - Aufteilung eines IP-Datagramms, wenn es größer als die Maximum Transmission Unit der Netzwerkschnittstelle ist

Beschreibung

Fragmentierung von Paketen auf einem Übertragungsnetzwerk, wenn das Paket größer ist als die MTU-Size des Netzwerks oder einer Teilstrecke

Zielsetzung

Ziel bei der Einführung der Fragmentierung im Internetprotokoll (IP) war es

  • die zugrundeliegende Netzwerkstruktur für den Benutzer zu verbergen (OSI-Modell)
  • Implementierung des Netzwerkprotokolls Hardware-unabhängig zu gestalten
Hintergrund

Im einfachsten Fall passt das gesamte IP-Datagramm in einen Datenblock

  • Höchste Effizienz
  • Maximale Größe eines IP-Datagramms
    • 64 kB
  • Die maximal mögliche Paketgröße (MTU) ist abhängig von den verwendeten Infrastrukturkomponenten
  • Moderne Paket-Switching-Techniken lassen unterschiedliche maximale Paketgrößen zu
Relevanz
Bereich Beschreibung
LAN Router, WLAN
Sicherheit Angriffe
Internet 2007 machte der fragmentierte Datenverkehr 0,06 % aus, 91 % der IPv4-Pakete hatten das don’t fragment (DF) Bit gesetzt, zuvor wurden 1-2% gemessen

Arbeitsweise

Sobald der IP-Stack (vgl. auch OSI-Modell oder TCP/IP-Referenzmodell) ein Datenpaket zum Versenden enthält, prüft dieser, ob die Paketgröße eine Aufteilung anhand der für die zu verwendende Netzwerkschnittstelle gegebene MTU notwendig macht

  • Ist dies nötig, so teilt dieser das vorhandene Datenpaket in mehrere Datenpakete auf
  • Dieser Vorgang wird als Fragmentierung bezeichnet
  • Diese Fragmentierung kann sowohl beim ursprünglichen Sender stattfinden oder auch auf Routern, die zwischen Sender und Empfänger liegen
  • Wird ein IP-Datagramm fragmentiert, so wird es erst beim Empfänger wieder zusammengesetzt (Ausnahme: ggf. zwischengeschaltete Firewalls, die speziell angewiesen wurden, ein sogenanntes reassembly durchzuführen, bevor die Daten weitergeleitet werden)

Sollte es nötig sein, kann auch ein bereits fragmentiertes Paket weiter fragmentiert werden (etwa bei einem Wechsel der Übertragungstechnik)

Jedes IP-Datagramm, das fragmentiert wurde, erhält einen neuen Header auf Basis des originalen Headers und spezieller aktualisierter Felder

  • Der Fragment-Offset (13 bit im IP-Header) wird dabei in 8-Byte-Blöcken angegeben
  • Wenn also das erste Datagramm 1000 Byte Nutzdaten enthält, dann ist der Fragment-Offset des zweiten Paketes 125 (= 1000 Byte/8 Byte)
  • Somit kann nur das letzte Fragment eine Nutzdaten-Menge haben, die nicht ein Vielfaches von 8 Byte ist
  • Weiterhin ist zu beachten, dass der Fragment-Offset bei 0 beginnt (der Eintrag im ersten Fragment) und deswegen der Offset des zweiten Paketes im genannten Beispiel 125 und nicht etwa 126 ist

Bei allen Fragmenten, außer dem letzten, wird das More-Fragments-Flag gesetzt

  • Ins Längen-Feld des IP-Headers wird bei allen Fragmenten die Länge des jeweiligen Fragments eingetragen, und für jeden Header wird die IP-Header-Prüfsumme separat berechnet, während der Rest des Headers dem Originalheader vor der Fragmentierung entspricht

Der Empfänger hat nun die Aufgabe, das Original aus den in den Paketheadern vorhandenen Informationen wieder zusammenzusetzen, indem er alle Fragmente mit gleichem IP-Header (mit Ausnahme der für jedes Fragment separaten Information) nimmt und sie anhand ihres Offsets in die richtige Reihenfolge bringt

  • Da jedes einzelne Fragment ein eigenständiges Paket darstellt, kann es auch vorkommen, dass diese Einzelteile nicht geordnet ankommen
  • Es ist auch möglich, dass einzelne Fragmente verlorengehen oder defekt sind
  • Es ist dann Sache des Empfängers, das Paket zu verwerfen und die Daten erneut anzufordern, wodurch eine höhere Netzwerklast entstehen kann

Per Definition kann die IP-Schicht keine Angaben darüber machen, ob ein Paket im Verlauf seiner Übertragung fragmentiert wird oder nicht

  • Einzige Ausnahme: Der Sender kann das sogenannte Don’t-Fragment-Flag setzen, welches alle beteiligten Kommunikationssysteme (Router, Gateways und weitere) anweist, keine Fragmentierung vorzunehmen
  • Für den Fall, dass eine Fragmentierung doch notwendig wäre, wird das Paket verworfen und dem Sender eine ICMP Fehlermeldung vom Typ 3 (destination unreachable) mit Code 4 (fragmentation required but don’t fragment bit set) gesendet, welche besagt, dass das Ziel für unfragmentierbare Pakete dieser Größe nicht erreichbar sei

Auswirkungen

Obwohl die Zielsetzung eine für höhere Schichten (z. B. TCP/UDP) transparente Implementierung ist, gibt es zwei Punkte, in denen dieses nicht ganz erreicht wird:

  • Die Fragmentierung kann großen Einfluss auf den Datendurchsatz haben und beeinflusst diesen im Allgemeinen negativ
  • Geht ein fragmentiertes Paket des originalen Paketes verloren, so muss das gesamte Original erneut übertragen werden. IP hat jedoch keine Sicherungs- bzw.ggf.Timeoutmechanismen und ist hierbei auf die Sicherungsfunktionen höherer Schichten wie die des TCP angewiesen

Aus genannten Gründen wird versucht, Fragmentierung immer so weit wie möglich zu vermeiden


Wo wird fragmentiert?

Wenn zwei System miteinander per TCP/IP kommunizieren, übertragen Sie Pakete mit Daten

  • Einige Pakete tragen nur wenige Inhalte, beispielsweise eine Terminal-Eingabe hat meist nur 1 Zeichen als Payload
  • Audio-Übertragungen kommen meist mit 160 Bytes Payload (= 20ms Ton bei 64kbit) aus
  • Ein Dateitransfer hingegen überträgt viele Daten  und möchte die Bandbreite optimal ausnutzen

Nun gibt es aber auf dem Übertragungsweg verschieden Teilstrecken mit unterschiedlicher Paketgröße

  • Das maximale Paket bei Ethernet beträgt normalerweise 1514 Bytes

Datei:Bild1.png

Wenn man nun die 6 Bytes der Absender-MAC-Adresse, weitere 6 Bytes der Empfänger-MAC-Adresse und 2 Bytes für den Protokolltyp (0x0800 = IP) abzieht, bleiben noch 1500 Bytes Nutzdaten für das eigentliche Protokoll übrig

  • Das kann dann natürlich IP, TCP, UDP, ICMP aber auch NetBEUI, IPX o. ä. sein
  • Die MTU-Größe wird also von dem Übertragungsmedium der Netzwerkkarte definiert

Sie können die aktuelle MTU Größe abfragen

PS C:\> Get-NetAdapter | ft name,status,linkspeed,mtusize

name Status LinkSpeed mtusize
----  ------  --------- -------
Mobilfunk Disconnected 0 bps 1500
WLAN Disconnected 0 bps 1500
LAN Onboard Disconnected 0 bps 1500
Bluetooth-Netzwerkverbindung Disconnected 3 Mbps 1500
LAN USBDock Up 1 Gbps 1500

In der Regel sind es 1500 Bytes, aber das muss nicht sein

  • Der darauf aufbauende Protokollstapel muss seine großen Pakete entsprechend zum Versand aufteilen und auf der Gegenseite wieder zusammensetzen.Sie können abweichend auch eine kleinere MTU-Size auf ihrer Netzwerkkarte einstellen
  • Einige Treiber erlauben die Konfiguration per GUI in den Netzwerkeigenschaften

Ansonsten geht es auch per NETSH

netsh interface ipv4 set subinterface `Local USBDock` mtu=1472 store=persistent”
netsh interface ipv4 show subinterface
Achtung
Sie sollten die MTU-Size nicht ohne sehr gute Kenntnisse der Funktion ändern
  • Gut gemeinte Tipps die MTU-Size zu verringern, um mit DSL-Verbindungen schneller Ping-Zeiten zu erreichen, sind falsch
  • Nur bei Problemen mit dem MTU-Discovery können Sie überlegen die MTU-Size manuell anzupassen

Die Änderung der MTU-Size auf einer Netzwerkkarte beeinflusst sowohl die Sende- als auch Empfangsrichtung

  • Sie können damit absichtlich kleinere Pakete erreichen, beispielsweise wenn eine dynamische Anpassung nicht möglich ist
  • In dem folgenden Bild ist das die Einstellung am Punkt (1)

Datei:Bild2.png

Ein Client kann aber nicht wissen, wie groß die Pakete auf dem Übertragungsweg sind

  • Gerade der erste Hop der Fritz!Box per DSL, DSLite, Kabel o. ä. sorgt schon dafür, dass an der Position (2) ein 1500 Bytes großes Paket nicht mehr mehr weiter geleitet werden kann
  • Der Router hat nun zwei Möglichkeiten damit umzugehen:* Verwerfen und Absender informierenMit einem "ICMP Fragmentation needed" kann der Router ein Paket an den Absender übermitteln, wie groß das Paket maximal sein darf
  • Der Sender schnürt dann kleinere Pakete, auch wenn dies bedeutet, dass auch auf den anderen Teilsteckern nicht mehr die maximale Paketgröße ausnutzt wird
  • Dieses "Paket zu groß" kann auch auf dem weiteren Verlauf weiter passieren und bei einem Wechsel des Routing auch während einer Verbindung passieren
  • Gehen Sie davon aus, dass alle Router im Internet nach dem Schema verfahren
  • Router packt selbst umHistorisch gibt es aber auch noch die Option, dass der Router das zu große Paket selbst in kleinere Pakete verpackt und die Gegenseite daraus wieder die originalen Pakete herstellt
  • Das belastet aber die Router zusätzlich und muss von beiden Seiten unterstützt werden
  • Zudem verschlechtert dies Durchsatz, wen beispielsweise * aus einem 1500er Paket dann ein 1400er + 100er Paket wird
  • Auf dem weiteren Weg könnte das Umpacken dann noch mal erforderlich werden
  • Die meisten ISPs unterstützen daher dieses Verfahren nicht mehr

Es soll Router geben, die zu große Pakete verwerfen und keine Rückmeldung senden und es soll Firewall-Administratoren geben, die das Protokoll ICMP als Schutz gegen "Ping"-Anfragen blocken und dabei auch die anderen ICMP-Steuernachrichten verlieren. 

ICMP zu blocken ist eine schlechte Idee, denn diese Steuerungsnachrichten sind für das Internet und TCP/IP von elementarem Interesse

  • Angreifer brauchen keinen PING um ihr Netzwerk zu analysieren
  • Dazu reichen auch TCP-Sync-Scans, UPNP Abfragen, ARP-Requests im LAN u.a. "Security by Obscurity" war noch nie ein guter Ansatz

Um solche Probleme zukünftig zu vermeiden, sollten sie zwei Fakten wissen:* IPv6 macht keine FragmentierungBei IPv6 müssen Sie daher "ICMP-Size Exceeded"-Meldungen verarbeiten

MTU anpassen

Dieser Abschnitt passt zwar besser auf die Seite Maximum Transmission Unit (MTU) aber wenn Sie die folgenden Analysen im LAN nachtesten wollen, dann brauchen Sie diese Information

  • Mein Ziel ist es, dass ich von PC1 Pakete zu PC2 im gleichen LAN sende
  • Da beide im Ethernet sind damit die MTU = 1500 Bytes gleich ist, kann ich das Verhalten schlecht zeigen, denn alles >1500 Bytes lehnt der IP-Stack schon ab
  • Daher möchte ich auf der entfernten Seite die MTU-Size reduzieren
  • Einige Netzwerkkarten erlauben diese Konfiguration in den erweiterten Eigenschaften:

Datei:Bild3.png

Ich würde diese hier aber nicht ändern sondern per NETSH auf der Netzwerkkarte des PC2

  • Zuerst hole ich mir die Information zur Netzwerkkarte und setze sie dann temporär auf 1400
REM Anzeige der Netzwerkkarte mit ihren Einstellungen
Netsh interface ipv4 show interfaces

Idx Met MTU State Name
--- ----------  ----------  ------------  ---------------------------
 1 75 4294967295 connected Loopback Pseudo-Interface 1
 28 70 1500 disconnected WLAN
 21 25 1500 connected Ethernet

REM Setzen der MTU Size
netsh interface ipv4 set subinterface "Ethernet" mtu=1400

Nun sollte ein zu großes Paket von PC1 zu PC2 nicht zugestellt oder fragmentiert werden

Wenn Sie Pakete per Wireshark mitschneiden, dann kann es sein, dass die Netzwerkkarte selbst die Pakete fragmentiert und wieder zusammensetzt und Wireshark daher nicht die realen Pakete sieht

Um den Mitschnitt zu optimieren, können sie im gleichen LAN einen CaptureFilter mit "Host <ip der gegenstelle>" eintragen

ICMP Fragmentation

Zuerst sende ich nun keinen "kleinen Ping" mit 1300 Bytes an die Gegenstelle

  • Hier ist noch keine Überraschung zu erwarten
  • Die Pakete werden mit 1300 Bytes "Payload" gesendet und sind auf dem Kabel 1342 Bytes groß:
ping 192.168.102.183 -l 1300

Datei:Bild4.png

Die 42 Bytes gehen für den ICMP, IP und Ethernet Frame drauf und auch die Antwort ist einfach zu verstehen

Datei:Bild5.png

Interessant wird es nun, wenn wir ein größeres Paket versenden

  • Bei meinem Sender ist die MTU=1500 eingestellt aber der Empfänger kann zumindest nicht mehr senden
ping 192.168.102.183 -l 1450

Das ausgehende Paket 12 hat nun 1450 Bytes Nutzdaten und ist 1492 Bytes auf dem Kabel

  • Eigentlich würde ich nun erwarten, dass die Gegenseite das Paket gar nicht annimmt
  • Dem ist aber nicht so, denn ich habe in dem Test nur die ausgehende MTU-Größe reduziert
  • Daher kommt die Rückantwort reduziert an

Datei:Bild6.png

In dem Fall sehen wir nun zwei Antwortpakete der Gegenseite

  • Der IP-Stack möchte die 1450 Bytes beantworten aber ist durch die MTU-Begrenzung limitiert
  • Also muss er die Pakete aufteilen
  • Das erste Paket selbst ist nur indirekt als ICMP-Paket erkennbar
  • Wireshark zeigt das fragmentierte IP-Paket als "Protocol=IPv4"

Datei:Bild7.png

Es ist einfach in "Raw"-IP-Paket mit einer "Identification" und der Information, dass weitere Fragmente kommen

  • Der Empfänger wartet also nun auf das weitere Paket, welche die gleiche "Identification" beinhaltet:

Datei:Bild8.png

Erst jetzt ist die komplette Antwort zurück gekommen

Wireshark ist smart genug, die beiden Pakete 13/14 zusammenzusetzen und in Paket 14 komplett anzuzeigen

  • Die Fragmente sehen ist also nicht in der , wenn Sie beispielsweise * eine Filter "ICMP" aktivieren, da die Teil-Fragmente nicht als ICMP-Pakete angesehen werden

Sie können aber im Paket 14 sehen, dass es aus mehreren Fragmenten übertragen wurde:

Datei:Bild9.png

Sie haben nun gesehen, wie Fragmentation die Pakete aufteilt und wieder zusammensetzt und dies pro Richtung unterschiedlich sein kann

DoNotFragment und Router

Der Test mit einem PC im gleichen Subnetz ist natürlich nur bedingt sinnvoll

  • Ich möchte ja mal sehen, was ein Router auf dem Weg macht
  • Wenn ich nun ein Paket mit 1500 Bytes versende, dann verlässt dies meinen PC problemlos und der nächste Router kann es so aber nicht über eine DSL-Leitung senden
  • Ich kann aber nicht wissen, ob der Router nun selbst das Paket "fragmentiert" oder nicht
  • Aber ich kann ihn anweisen, keine Fragmentierung zu nutzen
  • Beim Ping ist das Flag "-f" dafür zuständig
C:\> ping www.msxfaq.de -f -l 1500

Ping wird ausgeführt für www.msxfaq.de [178.77.117.98] mit 1500 Bytes Daten: Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt

Diese Paket kann ich allerdings nicht in Wireshark finden, denn es verlässt meinen PC gar nicht erst

  • Wenn ich eine 1500Byte Payload über ein Interface mit 1500 Bytes MTU-Size senden will, dann lehnt das der IP-Stack schon ab, denn die 1500 Bytes müssen ja noch in ICMP und IP eingepackt werden, denn die MTU-Size bezieht sich auf das Ethernet-Paket ohne die 14 Bytes für MAC-Adressen und Type
  • Die maximale Paketgröße ist daher 1500-14 = 1486
  • Davon gehen noch mal 20 Byte für den IP-Header und 16 Bytes für ICMP-Header
 1512 Kabel
 -6 SenderMAC
 -6 EmpfängerMAC
 -2 Type
=========
= 1500  MTU für Daten
- 20 für Version, DSCP, Flags, Protocol, Headerchecksumme, SourceIP, DestIP
=========
= 1480
- 8 für ICMP Typ, Code, Checksumme, Identifier, Sequence
========
= 1872

Erst wenn wir in dem Fall ein ICMP-Ping-Paket mit 1472 Bytes Payload oder kleiner senden, verlässt es meinen PC

PS C:\> ping 178.77.117.98 -f -l 1472

Ping wird ausgeführt für 178.77.117.98 mit 1472 Bytes Daten: Antwort von 80.66.18.137: Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt

Durch das "-f" zeige ich aber an, dass ich keine Fragmentierung möchte

  • Im ausgehenden Paket sehen Sie dies in den Flags:

Datei:Bild10.png

Das Paket kommt nun beim Router an und wenn er es aufgrund der Größe nicht weiterleiten kann aber Fragmentierung auch verboten ist, dann kann er nur mit einem "Fragmentation needed" antworten:

Hinweis: Filtern Sie nicht auf die Zieladresse, denn das "ICMP Destination unreachable" kommt vom Router auf dem Weg

Datei:Bild11.png

Ich muss mein Paket also um mindestens 8 Bytes kleiner machen damit es den nächsten Hop überspringt

  • Mit einem Ping und 1464 Bytes kam das Paket direkt beim Ziel an
PS C:\> ping 178.77.117.98 -f -l 1464

Ping wird ausgeführt für 178.77.117.98 mit 1464 Bytes Daten:
Antwort von 178.77.117.98: Bytes=1464 Zeit=15ms TTL=49
Antwort von 178.77.117.98: Bytes=1464 Zeit=15ms TTL=49
Antwort von 178.77.117.98: Bytes=1464 Zeit=15ms TTL=49

Es gibt auf der ganzen Strecke dann kein Teilstück mit einer kleineren MTU, sofern sich alle Router an das "Don't Fragment (DF)" halten

Hinweis:Um DoS und Spoofing-Attacken zu erschweren, antworten Router nicht auf jedes Paket mit einer "ICMP Fragmentation needed"

  • Der Client merkt sich diese Information

Das sehen Sie auch beim Ping eines übergroßen Pakets

PS C:\> ping 178.77.117.98 -f -l 1470 -t

Ping wird ausgeführt für 178.77.117.98 mit 1470 Bytes Daten: Antwort von 80.66.18.137: Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt Paket müsste fragmentiert werden, DF-Flag ist jedoch gesetzt

Nur die erste Antwort liefert die Details zum Router

  • Sie sollten das "Don't Fragment"-Bit nur setzen, wenn Sie es zwingend benötigen, da dies auch eine Fragmentierung auf ihrem Client unterbindet und ihre Software sich dann selbst drum kümmern muss, die richtige Paketgröße zu schnüren

Fragmentierung mit UDP

Neben ICMP gibt es mit UDP noch ein "verbindungsloses Protokoll", ehe wir uns dann noch TCP anschauen

  • Um zu zeigen, wie ein System auf fragmentierte Pakete umstellt, habe ich ein kleines PowerShell-Skript auf Basis von PowerShell und UDP geschrieben, welches immer größere UDP-Pakete sendet
  • Der Code eignet sich beispielsweise * um die Durchlässigkeit eines Routers, einer Firewall oder eines Loadbalancers zu verifizieren
param (
 [string]$remoteip = "www.msxfaq.de", # IP to send to
 [int]$remoteudpport=5060, # port to send to
 [int]$sourceudpport = 0, # SourcePort, maybe empty uses and available port
 [Parameter(ValueFromPipeline= $True)][int]$size = 100
)

$udpClient = New-Object System.Net.Sockets.Udpclient($sourceudpport)
$udpClient.DontFragment=$false

Write-host "Sending Paket with $($size) bytes to $($remoteip):$($remoteudpport)"
[string]$buffer = ("SendUDP Message by msxfaq").padright($size,"A")
$byteBuffer = [System.Text.Encoding]::ASCII.GetBytes($Buffer)
$sendbytes = $udpClient.Send($byteBuffer, $byteBuffer.length, $remoteip, $remoteudpport)
if ($sendbytes -ne $byteBuffer.length) {
 write-host "Mismatch bytes"
}
$udpClient.close()

Diese Skript sendet ohne Flusskontrolle, Drosselung o.ä

  • ganz schnell UDP-Pakete mit 1000-1500 Bytes an das angegebene Ziel
  • Es wartet nicht auf eine Antwort
  • Sie können damit also schon einen kleinen "Sturm" simulieren

Wenn Sie hier beim Capture Filter ein "UDP.port=5060" eintragen, dann sehen Sie nur die UDP-Pakete und nicht die Fragmentierung

Datei:Bild12.png

Beachten Sie dabei:

Das fragmentierte Paket kommt zuerst und hat nur eine "Identification" mit den Informationen über SourceIP, DesIP und Protokoll=UDP aber keiner Information über UDP-Ports

Das macht es für einen Loadbalancer unmöglich, diese Paket anhand eines "Protokoll" auf eine Regel zu mappen

  • Der Loadbalancer müsste die Pakete zwischenspeichern, bis er das letzte Paket bekommt
  • Erst das enthält die Information und kann anhand der "Identification" zusammengeführt werden

Datei:Bild13.png

Hier sehen Sie den Src-Port und Dest-Port aber auch die errechnete Datenlänger (1472 Bytes), obwohl dieses Paket nur 35 Bytes auf dem Kabel groß war

  • Wireshark führt fragmentierte Pakete zur Analyse zusammen

Theoretisch könnte ein Angreifer nun ein fragmentiertes Paket durch ein anderes Paket ersetzen

  • Daher ist eine zusätzliche Absicherung auf dem Datenlevel per TLS oder SRTP immer ratsam

Für eine Firewall oder Loadbalancer sind das natürlich erschwerte Bedingungen

Genau genommen müsste der Loadbalancer das Fragment puffern, bis das letzte Paket kommt und dann alle entweder defragmentiert weiterleiten oder wieder in der Reihenfolge

  • Wenn nun aber ein sehr großes Paket in viele Pakete fragmentiert wird und die auch noch unterschiedliche Wege nehmen und daher noch die Reihenfolge ändern, dann muss der Loadbalancer auch damit umgehen

Das Problem hierbei ist, dass das Zielsystem solche Aufgaben natürlich übernehmen kann aber Router oder Loadbalancer dazwischen durch solche Fragmentieren nicht nur belastet sondern sogar gezielt gestört werden können

  • Als Angreifer könnte ich ja gezielt "Fragmente" senden und immer Pakete weglassen, so dass das System auf der anderen Seite überlastet wird

Es macht daher schon Sinn, auf Fragmentierung komplett zu verzichten und IPv6 und QUIC machen das ja auch

UDP mit "DontFragment=$true"

Das gleiche Skripte habe ich auch noch einmal angewiesen, keine Fragmentierung zuzulassen

  • Das geht bei der UDP-Klasse ganz einfach durch folgende zusätzliche Zeile nach der Instanzierung des Objekts:
$udpClient = new-Object system.Net.Sockets.Udpclient($sourceudpport)
$udpClient.DontFragment=$false

Wenn ich nun Pakete mit aufsteigender Paketgröße sende, dann bricht irgendwann die Übertragung zusammen und ich bekomme eine Meldung von dem Router, bei dem das Paket nicht mehr weiter gesendet wird

  • In dem Fall die 8.6.18.137
  • Hier kommt der Fehler nun nicht erst bei dem Limit meiner Netzwerkkarte mit 1472Bytes (1514 Ethernet) sondern bei 1466 Bytes

Datei:Bild14.png

Die Rückantwort ist ein ICMP und kein UDP-Paket

  • Beim Wireshark-Filter sollten Sie also beispielsweise "udp.port=5060 or ICMP" nutzen
  • Die Source-IP wird zu viele Daten liefern aber ein Filter auf die RemoteIP blende die ICMP-Antworten auch aus, die vom Router unterwegs kommen
  • Dass dies eine Statusmeldung für das ausgehende UDP-Paket ist, findet sich dann in der Payload

Datei:Bild15.png

Dort geht auch, wir groß die MTU, hier 1492) maximal sein darf

  • Die ICMP Rückantwort wird vom IP-Stack auch an das UDP-Objekt zurück gegeben
  • Ohne entsprechende Fehlerbehandlung sehen Sie den Error direkt in der PowerShell:

Datei:Bild16.png

Interessant ist hierbei, dass im Gegensatz zu dem ICMP-Ping hier der Router auf jedes Paket eine Meldung sendet und meine IP-Stack oder das UDP-Objekt die Größenüberschreitung nicht cached

Das "do Not Fragment" ist ein IP-Flag und kann genauso mit ICMP und UDP genutzt werden

  • Es ist dann in der Verantwortung des Absenders korrekt darauf zu reagieren, beispielsweise: indem es entsprechend kleine Pakete sendet

Beim PING geht das mit dem "-f"-Paramterl

ping -f -l 1500

Interessant ist dazu eine Aussage einer schwedischen Quelle:

3.2.3 IP fragmentation During the year 2000, McCreary et al. [1] observed an increase in the fraction IP packets carrying fragmented traffic from 0.03% to 0.15%

  • Indeed, one year later, Shannon et al. [6] reported fractions of fragmented traffic of up to 0.67%
  • Contrary to this trend, we found a much smaller fraction of 0.06% of fragmented traffic in the analyzed data. ...3.2.4 IP flags The analysis of the IP flags (fragment bits) revealed that 91.3% of all observed IP packets have the don’t fragment bit (DF) set, as proposed by Path MTU Discovery (RFC 1191). 8.65% use neither DF nor MF (more fragments) and 0.04% set solely the MF bit.Quelle: Analysis of Internet Backbone Traffic and Header Anomalies observed  http://conferences.sigcomm.org/imc/2007/papers/imc91.pdf

Es werden also wohl sehr wenige Pakete tatsächlich fragmentiert und die meisten sogar ein "DF"-Flag gesetzt haben

Analysis of Internet Backbone Traffic and Header Anomalies observedhttp://conferences.sigcomm.org/imc/2007/papers/imc91.pdf* Maximum Transmission Unit (MTU) und Fragmentierung

Fragmentierung mit TCP

Heute versuchen System eine Fragmentierung von Paketen vom Anfang an zu vermeiden

  • Aufgrund der "TCP-Verbindung" ist das im Gegensatz zu UDP auch pro Session und der eindeutigen 1:1 Beziehung von Sender und Empfänger sinnvoll
  • Daher gibt es mit "Path MTU Discovery (PMTUD)" eine Spezifikation, mit der die beiden Endpunkte ermitteln, welche Paketgröße maximal möglich ist

Technisch senden Sie wie auch UDP nun ihre TCP-Pakete mit dem "DH-Flag=1" und werten die ICMP-Meldung "Fragmentation needed" aus

  • Das Paket enthält ja die maximale MTU-Size und diese wird vom Sender für alle weiteren Pakete übernommen
  • Diese Rückmeldung kann auch mehrfach eintreffen, wenn verschiedene Router hintereinander immer kleinere MTU-Werte nutzen oder das Routing sich ändert
  • Insofern verhält sich TCP nicht anders als UDP, nur dass bei UDP die eigene Software sich um zur große Pakete kümmern muss, wenn man DF-Flag=1 nutzt

Allerdings kann es sein, dass Sie mit Wireshark gar nicht die entsprechenden Pakete sehen, denn die Funktion wird immer mehr von "intelligenten Netzwerkkarten" übernommen um die Host-CPU zu entlasten

  • Wireshark sieht dann immer erfolgreiche Verbindungen mit bis zu 1514 Bytes

Datei:Bild17.png

Daher kann es sein, dass die Mitschnitte bei der Analyse in die Irre führen und sie immer nur "fehlerfreie Übertragungen" sehen

IPv6 und Fragmentierung

Bei IPv6 ist es nicht mehr erlaubt, dass ein System auf dem Übertragungsweg die Pakete fragmentiert

  • Das, was bei IPv4 noch als Verletzung des OSI-Modells geschimpft wurde, wenn ein IP-Router (OSI-Schicht 3) in den Übertragungsweg (OSI Schicht 2) eingreift, ist bei IPv6 nun empfohlen

IPv6 defines a mechanism that allows large payloads to be divided into fragments, with each fragment sent in a separate packet (see [IPv6-SPEC] section "Fragment Header")

  • However, packetization layers are encouraged to avoid sending messages that will require fragmentationQuelle: RFC 1981 - Path MTU Discovery for IP version 6 - https://tools.ietf.org/html/rfc1981

The Fragment header is used by an IPv6 source to send packets larger than would fit in the path MTU to their destinations. (Note: unlike IPv4, fragmentation in IPv6 is performed only by source nodes, not by routers along a packet's delivery pathIPv6 requires that every link in the internet have an MTU of 576 octets or greater

  • On any link that cannot convey a 576-octet packet in one piece, link-specific fragmentation and reassembly must be provided at a layer below IPv6.Links that have a configurable MTU (for example, PPP links) must be configured to have an MTU of at least 576 octets; it is recommended that a larger MTU be configured, to accommodate possible encapsulations (i.e., tunneling) without incurring fragmentation.Quelle: RFC 1883  Internet Protocol, Version 6 (IPv6) Specification" - https://tools.ietf.org/html/rfc1883

Mit IPv6 kommt bei "Test-Connection" eine MTUSize von 9999 Bytes zustande

PS C:\> Test-Connection fritz.box -MTUSizeDetect -Verbose -IPv6

Source : FC-T480S
Destination : fritz.box
MTUSize : 9999
Status : Success
Address : 2003:ea:a713:2c00:cece:1eff:fe34:3d04
RoundtripTime : 1
Options :
Buffer : {97, 98, 99, 100_}

Da scheint noch ein Bug vorzuliegen, denn auch hier ist die echte Paketgröße auf dem Kabel bei 1502 (eigentlich 1500) aber der IP-Stack scheint zu fragmentieren, ohne das Test-Connection davon etwas merkt

  • Wireshark zeigt schön die vielen Pakete vom Client zum Server und markiert das finale Paket

Datei:Bild18.png

Irgendwie macht das dann aber auch Sinn, wenn ein Versuch das Phänomen mit PING nachzuvollziehen liefert einfach die folgende Ausgabe:

C:> ping fritz.box -6 -f

Die Option "-f" wird nur für IPv4 unterstützt

Interessant finde ich dann aber schon, dass Test-Connection durch den IPv6-Stack ausgetrickst und keine Fehlermeldung liefert, dass IPv6-Adressen nicht geprüft werden können.* RFC 1981 - Path MTU Discovery for IP version 6https://tools.ietf.org/html/rfc1981

SIP mit UDP

Die meisten UDP-Kommunikationen sind Audio/Video-Übertragungen, die von der effektiven Behandlung von Verlusten profitieren

  • Immer, wenn ein verlorenes Paket eh nicht mehr nachgesendet werden muss, da es schon obsolet ist, ist UDP gegenüber TCP von Vorteil
  • Auch IoT-Geräte können per UDP beispielsweise * Energie spare, wenn Sie einfach ein Paket ein oder mehrfach senden und nicht erst einen TCP/TLS-Handshake aufbauen etc
  • Auch DNS-Anfagen sind lange Zeit über UDP erfolgt, weil es eine einfache Kommunikation ist
  • Wobei hier auch TCP zum Einsatz kommt, beispielsweise * bei Zonentransfers, DNSSEC oder auch DNSoverHTTP u.a
  • Einsatzbereichen

Aber im VoIP-Umfeld wurde lange Zeit auch die Signalisierung per SIP über UDP übertragen

  • Heute würde ich das nicht mehr machen, denn TCP hat viele Vorteile hinsichtlich der Behandlung von verlorenen Paketen, Stateful Inspection, Filterung auf Quell-IPs, TLS-Handshake, Paketen über 1472 Bytes etc
  • Dennoch gibt es auch heute noch Carrier, die UDP nutzen und dabei sogar im INVITE sehr große Pakete per UDP mit Fragmentierung senden
  • Hier ein Auszug:

Datei:Bild19.png

Das ist ein INVITE von EWE an einen SBC über UDP, mit Fragmentierung, was im Dez 2022 sogar entsprechend dokumentiert war

"Als Netzwerkprotokoll ist für die SIP Kommunikation UDP zu verwenden."SIP Trunk Spezifikation Technische Beschreibung des EWE SIP Trunkbusiness https://business.ewe.de/dokumente/telekommunikation/04_Broschueren_und_Infomaterial/technische_beschreibung_des_ewe_sip_trunk.pdf

Das Problem dabei ist natürlich, dass nicht alle Firewalls oder Loadbalancer problemlos mit UDP-Fragmentierungen umgehen können

Weitere Links


Anhang

Siehe auch


Links

  1. Kategorie:IP/Fragmentierung
  2. IP/Fragmentierung/IPv4
  3. IP/Fragmentierung/IPv6
  4. Fragmentierung
  5. Path MTU Discovery
  6. Maximum Transmission Unit
  7. IPv6/Header/Extension

Weblinks

  1. https://de.wikipedia.org/wiki/IP-Fragmentierung
  2. Maximum Transmission Unit (MTU)