Qualcuno ti dice che la VPN «perde pacchetti a causa dell'MTU», imposti il tunnel a 1400 e il trasferimento riprende a funzionare. Quel risultato sembra una diagnosi. Di solito è una coincidenza aritmetica: hai scelto un numero abbastanza piccolo da stare sotto un limite che non hai mai identificato, e incontrerai lo stesso limite sulla prossima rete con un budget diverso.

Due miti causano la maggior parte di questo. Il primo è che l'MTU dell'interfaccia del tunnel sia l'MTU del percorso. Il secondo è che l'incapsulamento costi «un'intestazione» e che il PPPoE non costi nulla che valga la pena contare. Entrambi sono falsi in modi che fanno sembrare arbitrario il numero che scegli quando in realtà è determinato.

Mito uno: l'MTU del tunnel è l'MTU del percorso

Il valore che imposti su un'interfaccia di tunnel è una promessa locale sul più grande pacchetto interno che l'implementazione consegnerà verso il basso. La capacità reale del percorso è una proprietà di ogni collegamento tra te e l'estremità remota, e può cambiare quando cambia una rotta, quando una connessione mobile passa a un'altra rete o quando il traffico prende un altro peering. Un 1500 configurato ti dice cosa costruirà il tuo host, non cosa trasporterà la rete.

La scoperta dell'MTU del percorso esiste per riconciliare i due e dipende dal feedback. Con IPv4, un router che non può inoltrare un pacchetto a dimensione piena dovrebbe inviare un messaggio ICMP «fragmentation needed», e il mittente abbassa la sua stima. Con IPv6, l'equivalente è un messaggio Packet Too Big e i router non frammentano affatto in transito. Quando quel feedback viene filtrato, il mittente continua a produrre pacchetti che il percorso non può trasportare, e nulla gli dice perché.

Mito due: l'incapsulamento costa un'intestazione

Conta gli strati esterni con onestà. Un'intestazione IP esterna è di 20 byte con IPv4 o 40 con IPv6. L'incapsulamento UDP per attraversare il NAT aggiunge 8. Il protocollo del tunnel aggiunge la propria intestazione, un vettore di inizializzazione o nonce, il padding fino al limite di blocco o allineamento del cifrario, una coda e un valore di controllo dell'integrità. A seconda del protocollo e del cifrario, il totale si colloca comodamente nelle decine di byte prima ancora che il pacchetto interno inizi.

Poi sottrai di nuovo le intestazioni del pacchetto interno stesso. Un segmento TCP dentro il tunnel porta la propria intestazione IP di 20 byte e la propria intestazione TCP di 20 byte, e l'MSS di TCP deriva dall'MTU, non dal carico utile nominale del tunnel. Per questo ping con un carico minore può riuscire mentre un trasferimento di file si blocca: gli strumenti provano cose diverse, e solo uno di essi esercita un segmento TCP a dimensione piena.

ip link show tun0
ping -M do -s 1472 192.0.2.10
ping -M do -s 1400 192.0.2.10

Il primo comando riporta l'MTU configurato del tunnel. Le due sonde inviano un carico di 1472 byte, che con 28 byte di intestazioni IPv4 e ICMP è un pacchetto di 1500 byte, poi uno più piccolo. Se la sonda grande fallisce del tutto e quella piccola riesce, hai un guasto dipendente dalla dimensione e non un problema generale di routing.

Mito tre: il PPPoE ti dà ancora 1500 puliti

Un collegamento di accesso PPPoE convenzionale non trasporta un pacchetto IP da 1500 byte. L'intestazione PPPoE più il campo protocollo PPP occupano 8 byte dentro la trama Ethernet, lasciando 1492 per il pacchetto IP. Questo è il limite tradizionale descritto nella RFC 2516. Se esegui una VPN su un collegamento del genere, l'overhead del tunnel esce da quei 1492, non da 1500.

La RFC 4638 definisce un modo per negoziare un carico PPP più grande quando sia il concentratore di accesso sia l'apparecchiatura del cliente lo supportano, per questo «questa connessione usa PPPoE» da solo non dimostra un numero preciso. Un'impostazione locale non può obbligare un dispositivo intermedio ad accettare un pacchetto per il quale non è mai stato configurato, quindi la domanda utile è cosa ha realmente negoziato il collegamento, non cosa dice l'etichetta.

Perché il guasto sembra selettivo

Il fatto che le richieste piccole riescano e i trasferimenti grandi si blocchino è la firma classica di un buco nero dell'MTU del percorso. La stretta di mano, la query DNS e la chiamata API ci stanno tutte; il trasferimento in blocco produce segmenti a dimensione piena che muoiono su un collegamento, e il messaggio ICMP che avrebbe dovuto segnalare il problema non arriva mai. La connessione sembra a posto e il download si blocca, il che porta le persone a guardare il server invece del percorso.

Un secondo errore correlato è confondere tre numeri: l'MTU dell'interfaccia, l'MSS di TCP e l'impostazione di frammentazione o padding del protocollo stesso. Il pinzamento dell'MSS su un router riscrive l'MSS annunciato perché il mittente costruisca segmenti più piccoli; non cambia l'MTU del tunnel e non aiuta il traffico UDP. Dare lo stesso numero a tutti e tre perché sembrano correlati è il modo in cui una modifica ben intenzionata rompe una configurazione che funziona.

Cosa cambiare, e in quale ordine

Inizia con le prove. Conferma con le sonde sopra che il guasto dipende dalla dimensione, poi trova la dimensione più piccola che passa e la più grande che fallisce. Controlla l'MTU reale del collegamento di accesso prima di incolpare il tunnel; un collegamento PPPoE limita il budget prima che la VPN lo tocchi. Annota i valori originali perché la modifica possa essere annullata.

Poi applica la modifica più piccola documentata dal client. Molti client espongono un MTU del tunnel più un'opzione di correzione MSS, e l'opzione MSS è spesso la leva migliore per TCP perché raggiunge il mittente senza ridurre ogni pacchetto. Riprova la stessa destinazione e lo stesso trasferimento, e annota i numeri su cui ti sei fermato. Un valore di tunnel che funziona su una rete di accesso non è una costante universale, e il prossimo sito avrà il proprio budget.

Articoli correlati