Je hebt een eis die niet buigt: de andere kant moet hetzelfde IP-pakket van 1,500 byte ontvangen dat de afzender uitstuurt, inclusief headers. Een tunnel kan dat pakket plus zijn eigen framing niet in een tweede IP-pakket van 1,500 byte verpakken, dus iets in het ontwerp moet toegeven. De volgorde hieronder is degene die ik in een wijzigingsvenster gebruik: schrijf het bytebudget, bewijs wat de onderlaag werkelijk kan dragen, kies dan precies een transportmechanisme en bevestig het innerlijke pakket aan de andere kant.

Schrijf het bytebudget voordat je een profiel bewerkt

Inkapseling voegt bytes toe op meerdere lagen, en het totaal is een eigenschap van jouw profiel en geen constante die je kunt opzoeken. Adresfamilie, keuze van het cijfer, transportprotocol en elke compressie- of framingoptie verplaatsen het getal, en daarom is een aftrekking die je uit een andere uitrol kopieert waardeloos als budget. Begin bij de innerlijke eis, tel de gemeten overhead per pakket van je eigen configuratie erbij op, en schrijf de resulterende buitenmaat op de wijzigingsticket voordat iemand een bestand bewerkt.

Twee getallen bepalen het ontwerp: het grootste buitenpakket dat het pad zonder fragmentatie draagt, en de extra bytes die je inkapseling nodig heeft. Wanneer het eerste kleiner is dan het tweede plus 1,500, moet een van beide veranderen. De keuze wordt dan smal in plaats van creatief, en daarom schrijf ik beide getallen op voordat ik opties bespreek. Niets op de tunnellaag comprimeert die bytes weg, en geen enkel MTU-geheel getal haalt de eis weg die je kreeg.

Peil de onderlaag met do-not-fragment-ping

Meet het pad in plaats van de interface-MTU te vertrouwen, want de kleinste schakel in het buitenpad is degene die telt. Op Linux, -M do zet de do-not-fragment-bit en -s neemt de ICMP-payload, dus een frame van 1,500 byte antwoordt met 1,472 byte payload zodra de IP-header van 20 byte en de ICMP-header van 8 byte eraf gaan. Verhoog de payload tot de test faalt, en spring dan naar een jumbo-formaat om te zien of het pad die uberhaupt draagt.

ping -M do -s 1472 -c 2 198.51.100.10
ping -M do -s 8972 -c 2 198.51.100.10
tracepath -n 198.51.100.10

Een pad dat 1,472 haalt en op 8,972 faalt, kan een innerlijk pakket van 1,500 byte plus overhead niet in een buitenpakket dragen. Dat is het antwoord dat je nodig had voordat je de VPN-configuratie opende. Het bepaalt ook welke van de volgende twee secties op jou van toepassing is, dus houd beide testresultaten bij de ticket. Gokken kost hier een onderhoudsvenster, want een tunnel die zichzelf als up meldt, vertelt je niets over het grootste pakket dat het pad accepteert.

Verhoog de pad-MTU alleen waar elke hop het eens is

Jumbo-frames zijn een end-to-end-eigenschap, geen instelling die je aanzet op de twee eindpunten die je toevallig beheert. Elke switch, router en provideroverdracht op het buitenpad moet instemmen met de grotere maat, en een hop van 1,500 byte gooit het pakket dat je net groter maakte stil weg. Alleen de lokale interface verhogen is de klassieke halve wijziging waardoor de tunnel kapot lijkt terwijl de onderlaag stil laat vallen.

ip link set dev eth1 mtu 9000
ip link show dev eth1
ping -M do -s 8972 -c 2 198.51.100.10

Wijzig de interface en peil daarna hetzelfde pad opnieuw voordat je iets anders wijzigt. Als de test nog steeds faalt, draai terug met ip link set dev eth1 mtu 1500 en ga over op fragmentatie in plaats van met een provider te discussieren over een link die niet van jou is.

Gebruik tunnelfragmentatie wanneer de onderlaag niet kan groeien

Een ondersteund fragmentatiemechanisme onder het innerlijke pakket laat meerdere buitenpakketten een innerlijk pakket dragen, en het andere tunneleindpunt zet ze weer in elkaar voordat het origineel aan de stack wordt gegeven. De UDP-fragmentoptie van Community OpenVPN is een implementatie van dat idee, en het is niet hetzelfde als gewone IP-fragmentatie van het buitenpakket. Beide peers moeten een versie draaien die het formaat ondersteunt, en het datapad moet het pad zijn dat je denkt: OpenVPN 3-clients en door de kernel versnelde datakanalen hebben verschillende limieten, dus een profiel dat op de ene client werkt, kan op een andere falen.

openvpn --config client.ovpn --tun-mtu 1500 --fragment 1400 --verb 4

Gewone buitenfragmentatie is de andere optie, en het is de zwakkere. IPv6-routers fragmenteren een doorgestuurd pakket helemaal niet, dus een te groot buitenpakket sterft gewoon, en de afzender leert het pas als het relevante ICMPv6-bericht het pad overleeft. Fragmenten nodigen ook uit tot filtering en versterking van verlies, en daarom beschouw ik dit als terugvaloptie en niet als plan.

Een streamgebaseerde buiten-drager omzeilt de maatvraag door zijn eigen bytestream te segmenteren, en het gereconstrueerde innerlijke pakket kan nog steeds 1,500 byte zijn. Dat is een transportbeslissing met eigen kosten, inclusief het bekende gedrag van TCP in TCP, dus neem die bewust en niet als bijeffect van een MTU-discussie.

Bevestig dat het innerlijke pakket onveranderd aankomt

Verificatie is geen geslaagde handshake. Leg vast op de tunnelinterface aan beide uiteinden en vergelijk de grootte en inhoud van het pakket dat de applicatie werkelijk stuurde met dat wat de andere kant ontving.

ip link show dev tun0
ping -M do -s 1472 -c 2 10.8.0.1
tcpdump -ni tun0 -c 5 'icmp and greater 1000'

Als de opname het volledige innerlijke pakket aan de andere kant toont, werkt de transportkeuze en is het resterende werk die vastleggen. Als ze niets toont terwijl de tunnel zich als up meldt, wordt het buitenpakket ergens tussen de eindpunten weggegooid, wat je terugstuurt naar de test en niet naar de cijferinstellingen.

Leg drie dingen vast in de wijzigingsticket voordat je hem sluit: het gemeten buitenbudget, het mechanisme dat je koos, en de opdracht die bewees dat het innerlijke pakket overleefde. De volgende persoon die deze tunnel aanraakt, heeft alle drie nodig, en geen ervan is uit het configuratiebestand alleen te reconstrueren.

Gerelateerde artikelen