VPN-MTU-mythes: waarom je pakketten krimpen en waar de ruimte blijft
Inkapseling en PPPoE vreten pakketruimte, maar een lagere MTU is geen diagnose. Scheid binnen- en buitenmaten voordat je een getal wijzigt.
Iemand vertelt je dat de VPN "pakketten verliest door MTU", je zet de tunnel op 1400, en de overdracht werkt weer. Dat resultaat voelt als een diagnose. Meestal is het een toeval van rekenwerk: je koos een getal dat klein genoeg is om onder een grens te passen die je nooit hebt geïdentificeerd, en je zult dezelfde grens weer tegenkomen op het volgende netwerk met een ander budget.
Twee mythes veroorzaken het meeste hiervan. De eerste is dat de MTU van de tunnelinterface de MTU van het pad is. De tweede is dat inkapseling "één header" kost en dat PPPoE niets kost dat het tellen waard is. Beide zijn onjuist op manieren die het getal dat je kiest willekeurig laten lijken terwijl het feitelijk bepaald is.
Mythe één: de MTU van de tunnel is de pad-MTU
De waarde die je op een tunnelinterface zet, is een lokale belofte over het grootste binnenpakket dat de implementatie naar beneden doorgeeft. De werkelijke capaciteit van het pad is een eigenschap van elke schakel tussen jou en het verre uiteinde, en die kan veranderen wanneer een route verandert, wanneer een mobiele verbinding wordt overgedragen of wanneer verkeer een andere peering neemt. Een ingestelde 1500 vertelt je wat je host bouwt, niet wat het netwerk draagt.
Pad-MTU-ontdekking bestaat om beide met elkaar te verzoenen, en het hangt af van terugkoppeling. Bij IPv4 hoort een router die geen pakket van volledige grootte kan doorsturen een ICMP-bericht "fragmentation needed" te sturen, en de verzender verlaagt zijn schatting. Bij IPv6 is het equivalent een Packet Too Big-bericht, en routers fragmenteren onderweg helemaal niet. Wordt die terugkoppeling gefilterd, dan blijft de verzender pakketten maken die het pad niet kan dragen, en niets vertelt hem waarom.
Mythe twee: inkapseling kost één header
Tel de buitenste lagen eerlijk. Een buitenste IP-header is 20 bytes bij IPv4 of 40 bij IPv6. UDP-inkapseling voor NAT-traversal voegt 8 toe. Het tunnelprotocol voegt zijn eigen header toe, een initialisatievector of nonce, opvulling tot de blok- of uitlijningsgrens van het cijfer, een trailer en een integriteitscontrolewaarde. Afhankelijk van protocol en cijfer ligt het totaal gerust in de tientallen bytes voordat het binnenpakket überhaupt begint.
Trek daarna weer af voor de eigen headers van het binnenpakket. Een TCP-segment in de tunnel draagt zijn eigen IP-header van 20 bytes en TCP-header van 20 bytes, en de MSS van TCP wordt afgeleid van de MTU, niet van de nominale payload van de tunnel. Daarom kan ping met een kleinere payload slagen terwijl een bestandsoverdracht vastloopt: de gereedschappen testen verschillende dingen, en slechts één ervan oefent een TCP-segment van volledige grootte.
ip link show tun0
ping -M do -s 1472 192.0.2.10
ping -M do -s 1400 192.0.2.10
De eerste opdracht rapporteert de ingestelde tunnel-MTU. De twee probes sturen een payload van 1472 bytes, wat met 28 bytes IPv4- en ICMP-headers een pakket van 1500 bytes is, en dan een kleinere. Als de grote probe volledig mislukt en de kleine slaagt, heb je een grootteafhankelijke fout en geen algemeen routeringsprobleem.
Mythe drie: PPPoE geeft je nog steeds schone 1500
Een conventionele PPPoE-toegangslijn draagt geen IP-pakket van 1500 bytes. De PPPoE-header plus het PPP-protocolveld nemen 8 bytes in het Ethernet-frame, waardoor 1492 overblijft voor het IP-pakket. Dat is de traditionele grens die in RFC 2516 wordt beschreven. Draai je een VPN over zo'n lijn, dan komt de overhead van de tunnel uit die 1492, niet uit 1500.
RFC 4638 definieert een manier om een grotere PPP-payload te onderhandelen wanneer zowel de toegangsconcentrator als de apparatuur van de klant dit ondersteunen, waardoor "deze verbinding gebruikt PPPoE" op zichzelf geen specifiek getal bewijst. Een lokale instelling kan een tussenliggend apparaat niet dwingen een pakket te accepteren waarvoor het nooit is geconfigureerd, dus de nuttige vraag is wat de lijn werkelijk heeft onderhandeld, niet wat het label zegt.
Waarom de fout selectief lijkt
Dat kleine verzoeken slagen en grote overdrachten vastlopen, is de klassieke signatuur van een zwart gat in de pad-MTU. De handshake, de DNS-query en de API-aanroep passen allemaal; de bulkoverdracht produceert segmenten van volledige grootte die bij één schakel sterven, en het ICMP-bericht dat het probleem had moeten melden, komt nooit aan. De verbinding ziet er goed uit en de download hangt, waardoor mensen naar de server kijken in plaats van naar het pad.
Een tweede, verwante fout is drie getallen door elkaar halen: de interface-MTU, de TCP-MSS en de eigen fragmentatie- of opvulinstelling van het protocol. MSS-clamping op een router herschrijft de aangekondigde MSS zodat de verzender kleinere segmenten bouwt; het verandert de tunnel-MTU niet en het helpt UDP-verkeer niet. Alle drie hetzelfde getal geven omdat ze verwant lijken, is hoe een goedbedoelde wijziging een werkende opstelling breekt.
Wat te wijzigen, en in welke volgorde
Begin met bewijs. Bevestig met de probes hierboven dat de fout grootteafhankelijk is, en zoek dan de kleinste grootte die doorkomt en de grootste die mislukt. Controleer de werkelijke MTU van de toegangslijn voordat je de tunnel de schuld geeft; een PPPoE-lijn begrenst het budget voordat je VPN hem raakt. Noteer de oorspronkelijke waarden zodat de wijziging kan worden teruggedraaid.
Pas daarna de kleinste aanpassing toe die de client documenteert. Veel clients bieden een tunnel-MTU plus een MSS-fixoptie, en de MSS-optie is voor TCP vaak de betere hefboom omdat hij de verzender bereikt zonder elk pakket te verkleinen. Test dezelfde bestemming en dezelfde overdracht opnieuw, en noteer de getallen waarop je uitkwam. Een tunnelwaarde die op één toegangsnetwerk werkt, is geen universele constante, en de volgende locatie heeft zijn eigen budget.