IPIP in WireGuard: die 20 zusätzlichen Bytes, die niemand eingeplant hat
IPIP kostet 20 Bytes mehr innerhalb von WireGuard. Rechnen Sie das Budget auf der richtigen Ebene, bevor Sie die Fragmentierung für einen hängenden Transfer auf einem laufenden Tunnel verantwortlich machen.
Kleine Pings durchqueren den Tunnel den ganzen Tag, das SSH-Banner kommt an, und dann friert die Sitzung in dem Moment ein, in dem eine Dateiübertragung beginnt. Dieses Muster deutet auf ein Byte-Budget hin, das auf der falschen Ebene gezählt wurde, wo der äußere Tunnel auf seinen eigenen Overhead ausgelegt wurde und niemand den inneren abzog. Ein verschachteltes IPIP-Paket ist für WireGuard nur ein weiteres IP-Paket, und genau deshalb verbraucht es Bytes, die Sie nie reserviert haben. Die Korrektur ist Arithmetik, und sie passt in drei Befehle und eine Tabelle.
Das Symptom, das es verrät
Fragmentierungsprobleme kündigen sich durch die Größe an, nie durch Adressen. Ihr Peer antwortet eine Stunde lang auf ein 56-Byte-ping und verstummt dann bei 1400 Bytes, während der Tunnel oben bleibt und sich keine Route geändert hat. Der Handshake passt, das erste volle TCP-Fenster nicht, und die Übertragung stockt Sekunden, nachdem sie gesund aussah.
Messen Sie die Obergrenze, bevor Sie irgendetwas bearbeiten, denn eine ungemessene Obergrenze ist eine, der Sie zweimal hinterherjagen. Senden Sie eine Sonde unterhalb der vermuteten Größe mit gesetztem do-not-fragment-Bit, ping -M do -s 1000 10.9.0.2, und wiederholen Sie sie dann bei einer Größe, von der Sie bereits wissen, dass sie zu groß ist. Wenn der Umschlag der Nutzlastgröße folgt, während das Ziel unverändert bleibt, erledigt das Routing seine Aufgabe, und im Budget fehlt ein Header.
Zählen Sie jeden Header einmal, auf der richtigen Ebene
Beginnen Sie mit der kleinsten MTU auf dem Pfad statt mit der Tunnel-Schnittstelle, denn die Wand liegt oberhalb beider Endpunkte. WireGuard verbraucht 60 Bytes für einen IPv4-Außentransport: 20 für IP, 8 für UDP und 32 für seinen eigenen Header, und 80 Bytes, wenn dieser Transport IPv6 ist. Ein wg0 mit 1420 Bytes hält 20 Bytes Reserve unter den 1440, die ein 1500-Byte-Pfad wirklich liefern kann, und deshalb passt die aus einem Wiki kopierte Zahl hier immer noch. Zeichnen Sie den ganzen Stapel ins Diagramm, denn wer als Nächstes die MTU ändert, wählt sonst eine neue runde Zahl und erbt Ihren Fehler.
| Layer | Bytes | Remaining |
|---|---|---|
| Path MTU on the wired link | none yet | 1500 |
| WireGuard outer: IP, UDP, WG header | 60 | 1440 |
| Slack kept for safety | 20 | 1420 (wg0) |
| IPIP header inside the tunnel | 20 | 1400 (ipip0) |
| Original IPv4 and TCP headers | 40 | 1360 payload |
Die fünfte Zeile ist der Ort, an dem Budgets schiefgehen, weil die 1400 Bytes, die eine verschachtelte Schnittstelle trägt, bereits die eigenen 40 Bytes Header des ursprünglichen Pakets enthalten. Nur 1360 dieser Bytes erreichen den Prozess, der die Datei liest. Behandeln Sie 1400 als Anwendungsnutzlast, wozu jedes Diagramm ohne diese Spalte Sie einlädt, und das innere Gerät endet 40 Bytes zu großzügig gegenüber einer Wand, die sich nicht bewegt hat.
Setzen Sie die beiden MTUs getrennt
Der Träger und das verschachtelte Gerät sind getrennte Objekte, also braucht jedes seinen eigenen Wert. Wenden Sie sie in dieser Reihenfolge an, denn das verschachtelte Gerät erbt nichts vom Träger:
ip link set wg0 mtu 1420
ip tunnel add ipip0 mode ipip remote 203.0.113.9 local 198.51.100.4
ip link set ipip0 mtu 1400
Die Regel, die es sich zu merken lohnt: innere MTU = äußere MTU - 20, wenn das Paket, das der IPIP-Tunnel trägt, IPv4 ist, und - 40, sobald eine Seite des inneren Pakets IPv6 ist, weil der verschachtelte Header von 20 Bytes auf 40 wächst. Nichts anderes gehört in diese Subtraktion. WireGuards Overhead wurde bereits verbraucht, als Sie 1420 wählten, und ihn zweimal zu berechnen erzeugt einen Tunnel, der perfekt funktioniert und langsam bleibt, solange niemand ihn misst. Ein Deployment, bei dem beide Geräte runde 1400 tragen, ist der Fingerabdruck genau dieses Fehlers.
IPv6 auf jeder Seite des verschachtelten Pakets entwertet jede Zahl oben, also rechnen Sie neu, statt eine Zahl von einer ähnlichen Seite zu kopieren. Die abgezogenen Header sind jeweils 40 Bytes, sobald IPv6 im äußeren Pfad oder im ursprünglichen Datagramm auftaucht, und die Nutzlastzahl fällt genau um so viel.
Die Firewall-Regel, die Sie wahrscheinlich nicht brauchen
Zwischen zwei WireGuard-Peers ist das Einzige auf der Leitung UDP, daher schafft eine eingehende Regel für Protokoll 4, die Nummer, die RFC 2003 der IPv4-in-IPv4-Kapselung zuweist, den verschachtelten Pfad weder noch hält sie ihn am Leben. Der IPIP-Header lebt innerhalb der verschlüsselten Nutzlast, wo ihn keine Edge-Firewall sieht. Protokoll 4 trotzdem zu öffnen, bringt nichts außer einem weiteren erlaubten Weg in den Host.
Richtlinien, die Quellen und Ziele des ursprünglichen Pakets erwähnen, gehören hinter die Entkapselung, auf die Tunnel-Schnittstellen und in die Routing-Tabelle. Legen Sie sie dort ab, und die Edge-Regel kann geschlossen bleiben.
Was WireGuard tatsächlich validiert
AllowedIPs beurteilt die Quelle des Pakets, das WireGuard trägt, und was es trägt, ist das IPIP-gekapselte Paket. Eine erlaubte IPIP-Quelle wird akzeptiert, selbst wenn der Header darin einen Host nennt, den Sie lieber nicht routen würden. Die ursprüngliche Quelle ist also nicht das, was der Peer für Sie geprüft hat, und dieses innere Adresspaar braucht nach der Entkapselung seine eigene Durchsetzung.
Der Wrapper liefert Routing-Struktur, keine zweite Kryptographieschicht. IPIP als zusätzlichen Schutz innerhalb von WireGuard zu bezeichnen, beschreibt ein anderes Design.
Prüfen Sie mit einer Leiter, nicht mit einem einzelnen Ping
Prüfen Sie Größen, die die berechnete Grenze umschließen, und bestätigen Sie dann, was der Kernel über beide Geräte glaubt. Bei 1360 Bytes Nutzlast plus 40 Bytes Header, was 1400 ergibt, passt das erste Echo unten, und das zweite sitzt ein Byte jenseits der Obergrenze:
ping -M do -s 1372 10.9.0.2
ping -M do -s 1373 10.9.0.2
wg show wg0
ip -d link show ipip0
Ein sauberer Durchlauf unterhalb der Obergrenze und ein Fehlschlag bei der ersten Größe darüber bedeuten, dass die Arithmetik von Ende zu Ende hält. Führen Sie dann die Übertragung erneut aus, die ursprünglich stockte, denn eine synthetische Sonde beweist das Budget und sagt nichts über die Schreibgrößen des Senders. Wenn der verschachtelte Pfad bei einer Größe, die Sie als passend nachgewiesen haben, immer noch bricht, prüfen Sie die Entkapselung und die Routen des fernen Endpunkts, bevor Sie weitere zehn Bytes von der MTU abziehen.