Du har ett krav som inte böjer sig: den andra sidan måste ta emot samma 1,500-byte IP-paket som avsändaren skickar, inklusive headers. En tunnel kan inte packa in det paketet plus sin egen framing i ett andra 1,500-byte IP-paket, så något i designen måste ge vika. Ordningen nedan är den jag använder i ett ändringsfönster: skriv bytebudgeten, bevisa vad underlaget faktiskt kan bära, välj sedan exakt en transportmekanism och bekräfta det inre paketet på andra sidan.

Skriv bytebudgeten innan du redigerar en profil

Inkapsling lägger till byte på flera lager, och summan är en egenskap hos din profil och inte en konstant du kan slå upp. Adressfamilj, val av chiffer, transportprotokoll och varje komprimerings- eller framingalternativ flyttar talet, och därför är en subtraktion kopierad från en annan utrullning värdelös som budget. Börja med det inre kravet, lägg till den uppmätta overheaden per paket för din egen konfiguration och skriv den resulterande yttre storleken på ändringsärendet innan någon redigerar en fil.

Två tal avgör designen: det största yttre paketet som vägen bär utan fragmentering, och de extra byte som din inkapsling behöver. När det första är mindre än det andra plus 1,500 måste ett av dem ändras. Valet blir då smalt och inte kreativt, och därför skriver jag ned båda talen innan jag diskuterar alternativ. Ingenting på tunnelnivån komprimerar bort de byten, och inget enda MTU-heltal tar bort kravet du fick.

Sondera underlaget med do-not-fragment-ping

Mät vägen i stället för att lita på gränssnittets MTU, eftersom den minsta länken i den yttre vägen är den som räknas. På Linux, -M do sätter do-not-fragment-biten och -s tar ICMP-nyttolasten, så en ram på 1,500 byte svarar med 1,472 byte nyttolast när 20 byte IP-header och 8 byte ICMP-header dragits av. Öka nyttolasten tills sonden misslyckas och hoppa sedan till en jumbostorlek för att se om vägen bär den alls.

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

En väg som klarar 1,472 och misslyckas på 8,972 kan inte bära ett inre paket på 1,500 byte plus overhead i ett enda yttre paket. Det är svaret du behövde innan du öppnade VPN-konfigurationen. Det avgör också vilken av de två följande sektionerna som gäller dig, så håll båda sondresultaten vid ärendet. Att gissa här kostar ett underhållsfönster, eftersom en tunnel som rapporterar sig som up inte säger något om det största paket vägen accepterar.

Höj vägens MTU bara där varje hopp är överens

Jumboramar är en end-to-end-egenskap, inte en inställning du slår på på de två ändpunkter du råkar kontrollera. Varje switch, router och leverantörsöverlämning på den yttre vägen måste vara överens om den större storleken, och ett enda hopp på 1,500 byte kommer tyst att kasta paketet du just gjorde större. Att bara höja det lokala gränssnittet är den klassiska halvåtgärden som får tunneln att se trasig ut medan underlaget tyst tappar.

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

Ändra gränssnittet och sondera sedan samma väg igen innan du ändrar något annat. Om sonden fortfarande misslyckas, rulla tillbaka med ip link set dev eth1 mtu 1500 och gå över till fragmentering i stället för att bråka med en leverantör om en länk du inte äger.

Använd tunnelfragmentering när underlaget inte kan växa

En fragmenteringsmekanism som stöds under det inre paketet låter flera yttre paket bära ett inre paket, och den motsatta tunneländpunkten sätter ihop dem igen innan originalet lämnas till stacken. Community OpenVPN:s UDP-fragmentalternativ är en implementering av den idén och är inte samma sak som vanlig IP-fragmentering av det yttre paketet. Båda parterna måste köra en version som stöder formatet, och datavägen måste vara den du tror: OpenVPN 3-klienter och kernaccelererade datakanaler har olika gränser, så en profil som fungerar på en klient kan misslyckas på en annan.

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

Vanlig yttre fragmentering är det andra alternativet och det är det svagare. IPv6-routrar fragmenterar inte alls ett vidarebefordrat paket, så ett för stort yttre paket dör helt enkelt och avsändaren får veta det först om det relevanta ICMPv6-meddelandet överlever vägen. Fragment bjuder också in till filtrering och förstärkning av förluster, och därför behandlar jag detta som en reserv och inte en plan.

En strömbaserad yttre bärare kringgår storleksfrågan genom att segmentera sin egen byteström, och det rekonstruerade inre paketet kan fortfarande vara 1,500 byte. Det är ett transportbeslut med sin egen kostnad, inklusive det välkända beteendet hos TCP inuti TCP, så ta det medvetet och inte som en bieffekt av en MTU-diskussion.

Bekräfta att det inre paketet anländer oförändrat

Verifiering är inte detsamma som ett lyckat handshake. Fånga på tunnelgränssnittet i båda ändar och jämför storleken och innehållet i paketet som applikationen faktiskt skickade med det som andra sidan tog emot.

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'

Om fångsten visar det fullstora inre paketet i andra änden fungerar transportvalet, och det som återstår är att dokumentera det. Om den inte visar något medan tunneln rapporterar sig som up, kastas det yttre paketet någonstans mellan ändpunkterna, vilket skickar tillbaka dig till sonden och inte till chifferinställningarna.

Skriv tre saker i ändringsärendet innan du stänger det: den uppmätta yttre budgeten, mekanismen du valde och kommandot som bevisade att det inre paketet överlevde. Nästa person som rör den här tunneln behöver alla tre, och ingen av dem kan rekonstrueras enbart från konfigurationsfilen.

Relaterade artiklar