Buraco negro de MTU: por que pedidos pequenos funcionam mas os envios travam
Pedidos pequenos terminam enquanto um envio grande fica pendurado para sempre, e o emissor nunca descobre que o caminho é mais estreito. Meça o tamanho exato onde quebra.
Uma página carrega, uma chamada de API pequena retorna e depois um envio de arquivo fica pendurado até o cliente desistir. Nada no log do servidor explica isso, porque os pacotes foram descartados no meio do caminho sem que uma resposta útil fosse devolvida. Esse padrão é um buraco negro de MTU: um link mais estreito do que o emissor supõe, mais uma recusa silenciosa de dizê-lo. O tamanho que falha é repetível, e é isso que o torna diagnosticável.
O que torna o buraco negro
Cada link tem uma unidade máxima de transmissão, e um pacote maior que o limite do salto seguinte deve ser fragmentado ou rejeitado com uma mensagem ICMP que o diga. A descoberta do MTU do caminho depende de que essa mensagem chegue e seja respeitada. Filtrá-la ou ignorá-la deixa o emissor repetindo um pacote que nunca cabe.
A encapsulação torna isso comum em torno de VPNs, porque um túnel acrescenta um cabeçalho externo a um pacote que já estava dimensionado para o link físico. O pacote interno é legal com 1500 bytes e o encapsulado não, então ele morre na fronteira enquanto pacotes pequenos passam. Um handshake concluído e uma página de login que funciona provam apenas que pacotes pequenos funcionam. O maior pacote que a aplicação tenta enviar é o que importa.
Encontre o tamanho onde quebra
Busque por bisseção o tamanho da carga com um teste sem fragmentação, de um host de um lado do túnel para um host do outro. A maior carga que passa é o seu MTU de caminho utilizável menos a sobrecarga do cabeçalho.
ping -M do -s 1400 -c 2 192.0.2.20
ping -M do -s 1200 -c 2 192.0.2.20
ping -f -l 1372 192.0.2.20
Uma carga de 1472 bytes passa num caminho Ethernet limpo de 1500 bytes depois que os 28 bytes dos cabeçalhos IPv4 e ICMP são somados. Quando o mesmo teste só passa com uma carga menor depois que o túnel sobe, a diferença é a sobrecarga de encapsulação, e a fronteira do túnel é onde a mensagem de rejeição deveria ter sido gerada. Anote os dois números, antes e depois de conectar, porque esse par é a prova. Repita o teste para IPv6 quando a aplicação o usa, já que o cabeçalho é maior e o limite de falha se desloca.
Leia as evidências antes de culpar o túnel
Erros de aplicações remotas, congestionamento e perda comum também travam envios, então uma transferência falha não identifica um buraco negro. O que os separa é a relação de tamanhos: um sucesso repetível com 1200 bytes e uma parada repetível com 1400 bytes, na mesma direção, pelo mesmo ponto final.
Uma captura nas duas pontas mostra os pacotes grandes saindo e nunca chegando, sem rejeição no meio. Esse é o momento de olhar o dispositivo de fronteira em vez do servidor, que responde a cada pedido que realmente recebe. O congestionamento também trava, mas trava tamanhos diferentes em momentos diferentes, e essa é outra assinatura.
Verifique o reparo nos dois transportes
O reparo suportado é deixar a fronteira relatar o limite real, ou fixar ali o tamanho máximo de segmento do TCP para que nenhum segmento grande demais seja tentado. Baixar cada MTU da rede, ou desativar o firewall, esconde o sintoma e deixa uma configuração sobre a qual ninguém conseguirá raciocinar depois.
ip link show dev tun0
sudo nft list ruleset | grep -i -E 'mtu|mss'
sysctl net.ipv4.tcp_mtu_probing
ping -M do -s 1400 -c 2 192.0.2.20
Verifique com o mesmo teste de tamanho, depois com a aplicação que falhou, e confira um segundo protocolo, porque aplicações UDP nunca recebem a correção de tamanho de segmento do TCP. Guarde os valores originais no ticket, porque um reparo que não pode ser revertido é um segundo problema esperando acontecer. Se o teste de tamanho passa e o envio ainda trava, o buraco negro não era a causa, e a investigação deve seguir em frente em vez de ampliar a mudança.