Como evito que a conexão TCP congele em uma rede OpenVPN?

19

Novos detalhes adicionados no final desta pergunta; é possível que eu esteja me concentrando na causa.

Eu tenho uma VPN baseada em UDP OpenVPN configurada no tapmodo (eu preciso tapporque preciso que a VPN passe pacotes multicast, o que não parece ser possível com as tunredes) com um punhado de clientes na Internet. Eu tenho experimentado freios de conexão TCP freqüentes através da VPN. Ou seja, estabelecerei uma conexão TCP (por exemplo, uma conexão SSH, mas outros protocolos têm problemas semelhantes) e, em algum momento da sessão, parece que o tráfego deixará de ser transmitido nessa sessão TCP.

Isso parece estar relacionado aos pontos nos quais ocorrem grandes transferências de dados, como se eu execute um lscomando em uma sessão SSH ou se eu for catum arquivo de log longo. Algumas pesquisas no Google exibem várias respostas como essa anterior na falha do servidor , indicando que o provável culpado é um problema de MTU: que durante períodos de tráfego intenso, a VPN está tentando enviar pacotes que caem em algum lugar nos tubos entre o Pontos finais de VPN. A resposta vinculada acima sugere o uso das seguintes configurações do OpenVPN para atenuar o problema:

fragment 1400
mssfix

Isso deve limitar o MTU usado na VPN a 1400 bytes e corrigir o tamanho máximo do segmento TCP para impedir a geração de pacotes maiores que isso. Isso parece atenuar um pouco o problema, mas ainda vejo frequentemente os congelamentos. Eu tentei vários tamanhos como argumentos para a fragmentdiretiva: 1200, 1000, 576, todos com resultados semelhantes. Não consigo pensar em nenhuma topologia de rede estranha entre as duas extremidades que possa desencadear esse problema: o servidor VPN está sendo executado em uma máquina pfSense conectada diretamente à Internet, e meu cliente também está conectado diretamente à Internet em outro local.

Outra peça estranha do quebra-cabeça: se eu executar o tracepathutilitário, isso parece ajudar o problema. Uma amostra de execução é semelhante a:

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 hops 1 back 64 

A execução acima é entre dois clientes na VPN: iniciei o rastreamento do 192.168.100.90destino de 192.168.100.91. Ambos os clientes foram configurados com fragment 1200; mssfix;uma tentativa de limitar o MTU usado no link. Os resultados acima parecem sugerir que tracepathfoi possível detectar um caminho MTU de 1500 bytes entre os dois clientes. Eu assumiria que seria um pouco menor devido às configurações de fragmentação especificadas na configuração do OpenVPN. Achei esse resultado um tanto estranho.

Ainda mais estranho, no entanto: se eu tiver uma conexão TCP no estado parado (por exemplo, uma sessão SSH com uma lista de diretórios que congelou no meio), a execução do tracepathcomando mostrado acima fará com que a conexão seja reiniciada novamente ! Não consigo encontrar uma explicação razoável para o motivo, mas acho que isso pode estar apontando uma solução para erradicar o problema.

Alguém tem alguma recomendação para outras coisas para tentar?

Edit: Voltei e olhei para isso um pouco mais e encontrei apenas mais informações confusas:

  • Defino a conexão OpenVPN para fragmentar em 1400 bytes, como mostrado acima. Em seguida, conectei-me à VPN pela Internet e usei o Wireshark para verificar os pacotes UDP que foram enviados ao servidor VPN durante a paralisação. Nenhum foi maior que a contagem de 1400 bytes especificada; portanto, a fragmentação parece estar funcionando corretamente.

  • Para verificar se mesmo uma MTU de 1400 bytes seria suficiente, executei ping no servidor VPN usando o seguinte comando (Linux):

    ping <host> -s 1450 -M do
    

    Isso (acredito) envia um pacote de 1450 bytes com a fragmentação desabilitada (pelo menos verifiquei que não funcionava se o definisse como um valor obviamente muito grande, como 1600 bytes). Estes parecem funcionar muito bem; Recebo respostas do host sem problemas.

Portanto, talvez este não seja um problema de MTU. Estou apenas confuso quanto ao que mais pode ser!

Edit 2: A toca do coelho está ficando cada vez mais profunda: agora eu isolei o problema um pouco mais. Parece estar relacionado ao sistema operacional exato que o cliente VPN usa. Dupliquei o problema com êxito em pelo menos três máquinas Ubuntu (versões 12.04 a 13.04). Posso duplicar com segurança um congelamento da conexão SSH dentro de um minuto ou mais apenas catpressionando um arquivo de log grande.

No entanto , se eu fizer o mesmo teste usando uma máquina CentOS 6 como cliente, não vejo o problema! Testei usando exatamente a mesma versão do cliente OpenVPN que estava usando nas máquinas Ubuntu. Posso catregistrar arquivos por horas sem ver a conexão congelar. Isso parece fornecer algumas dicas sobre a causa final, mas não sei ao certo qual é essa visão.

Examinei o tráfego pela VPN usando o Wireshark. Eu não sou um especialista em TCP, por isso não tenho certeza do que fazer com os detalhes sangrentos, mas o essencial é que, em algum momento, um pacote UDP é descartado devido à largura de banda limitada do link da Internet, causando retransmissões TCP dentro o túnel da VPN. No cliente CentOS, essas retransmissões ocorrem corretamente e as coisas acontecem felizes. Em algum momento com os clientes Ubuntu, no entanto, a extremidade remota começa a retransmitir o mesmo segmento TCP repetidamente (com o atraso de transmissão aumentando entre cada retransmissão). O cliente envia o que parece ser um TCP ACK válido para cada retransmissão, mas a extremidade remota ainda continua a transmitir o mesmo segmento TCP periodicamente. Isso aumenta ad infinitum e a conexão é interrompida. Minha pergunta aqui seria:

  • Alguém tem alguma recomendação sobre como solucionar problemas e / ou determinar a causa raiz do problema de TCP? É como se a extremidade remota não estivesse aceitando as mensagens ACK enviadas pelo cliente VPN.

Uma diferença comum entre o nó CentOS e as várias versões do Ubuntu é que o Ubuntu possui uma versão do kernel Linux muito mais recente (de 3.2 no Ubuntu 12.04 para 3.8 em 13.04). Um ponteiro para algum novo bug do kernel, talvez? Suponho que, se assim fosse, não seria o único a enfrentar o problema; Eu não acho que isso pareça uma configuração particularmente exótica.

Jason R
fonte
Encaminhamento de pacotes multicast através de uma tunrede deve ser possível por meio da execução de daemons multicast roteamento (como pimd ) e ter o uso do servidor OpenVPN as --topologyopções definidas para "sub-rede" - veja o manual
kostix
O cliente ou servidor VPN indica alguma coisa nos logs no momento desses problemas?
mgorven
@ mgorven: Definitivamente não no cliente. Vou ter que fazer algum trabalho para acessar os logs do servidor.
Jason R
@mgorven: Finalmente tive a chance de voltar a isso. Nada nos logs do cliente ou servidor quando isso acontece. É realmente desconcertante.
Jason R
11
Existe alguma possibilidade de que os clientes que congelam tenham firewalls locais que estão descartando pacotes necessários para fragmentação de ICMP, onde, como aqueles que não o fazem, não o fazem e, portanto, estão se fragmentando corretamente?
MadHatter apoia Monica

Respostas:

10

Este comando resolve para mim:

$ sudo ip link set dev tun0 mtu 1350 && echo ":)"

Você pode verificar as configurações tun0 com

$ ip a s

Felicidades!

Sebastián A. La Spina
fonte
No cliente ou no servidor?
Matt
Muito obrigado! @ Matt, depende de onde o problema está localizado. Para nós, estava no servidor, mas pode estar no lado do cliente. Além disso, o valor pode ser diferente, você pode testar com ping <host> -s 1350 -M doa encontrar o valor correto
Eino Gourdin
2

Desative o dimensionamento de janelas no TCP, com:

sysctl -w net.ipv4.tcp_window_scaling=0

Depois disso, o SSH para sistemas Debian / Ubuntu através de VPN está funcionando bem para mim.

Mifpi
fonte
0

No Windows usando o Putty, você deve alterar a MTU acessando a conexão local para a conexão VPN -> detalhes na interface de rede (adaptador TAP do Windows ou algo parecido) -> Avançado -> Propriedades -> MTU (altere para algo inferior a 1500). Você pode precisar se reconectar. Funcionou para mim no Windows e Putty

Nick_K
fonte