¿Cómo evito que la conexión TCP se congele en una red OpenVPN?


19

Nuevos detalles agregados al final de esta pregunta; Es posible que me esté concentrando en la causa.

Tengo una VPN basada en UDP OpenVPN configurada en tapmodo (necesito tapporque necesito que la VPN pase paquetes de multidifusión, lo que no parece posible con las tunredes) con un puñado de clientes a través de Internet. He estado experimentando frecuentes bloqueos de conexión TCP a través de la VPN. Es decir, estableceré una conexión TCP (por ejemplo, una conexión SSH, pero otros protocolos tienen problemas similares), y en algún momento durante la sesión, parece que el tráfico dejará de transmitirse a través de esa sesión TCP.

Esto parece estar relacionado con puntos en los que ocurren grandes transferencias de datos, como si ejecuto un lscomando en una sesión SSH o si hago catun archivo de registro largo. Algunas búsquedas de Google muestran varias respuestas como esta anterior en Falla del servidor , lo que indica que el culpable probable es un problema de MTU: que durante los períodos de alto tráfico, la VPN está tratando de enviar paquetes que se caen en algún lugar en las tuberías entre el Puntos finales de VPN. La respuesta vinculada anteriormente sugiere utilizar las siguientes opciones de configuración de OpenVPN para mitigar el problema:

fragment 1400
mssfix

Esto debería limitar la MTU utilizada en la VPN a 1400 bytes y fijar el tamaño máximo de segmento TCP para evitar la generación de paquetes más grandes que eso. Esto parece mitigar un poco el problema, pero con frecuencia veo las congelaciones. He intentado varios tamaños como argumentos de la fragmentdirectiva: 1200, 1000, 576, todos con resultados similares. No puedo pensar en ninguna topología de red extraña entre los dos extremos que pueda desencadenar tal problema: el servidor VPN se ejecuta en una máquina pfSense conectada directamente a Internet, y mi cliente también está conectado directamente a Internet en otra ubicación.

Otra pieza extraña del rompecabezas: si ejecuto la tracepathutilidad, parece que eso ayuda a resolver el problema. Una ejecución de muestra se ve así:

[~]$ 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 

La ejecución anterior es entre dos clientes en la VPN: inicié el rastreo desde 192.168.100.90el destino de 192.168.100.91. Ambos clientes se configuraron fragment 1200; mssfix;en un intento de limitar la MTU utilizada en el enlace. Los resultados anteriores parecen sugerir que tracepathfue capaz de detectar una ruta MTU de 1500 bytes entre los dos clientes. Supongo que sería algo más pequeño debido a la configuración de fragmentación especificada en la configuración de OpenVPN. Encontré ese resultado algo extraño.

Sin embargo, aún más extraño: si tengo una conexión TCP en estado estancado (por ejemplo, una sesión SSH con un listado de directorio que se congeló en el medio), ¡ ejecutar el tracepathcomando que se muestra arriba hace que la conexión se inicie nuevamente ! No puedo encontrar ninguna explicación razonable de por qué este sería el caso, pero siento que esto podría estar apuntando hacia una solución para finalmente erradicar el problema.

¿Alguien tiene alguna recomendación para probar otras cosas?

Editar: Regresé y lo miré un poco más, y solo encontré más información confusa:

  • Configuré la conexión OpenVPN para fragmentar a 1400 bytes, como se muestra arriba. Luego, me conecté a la VPN a través de Internet y utilicé Wireshark para ver los paquetes UDP que se enviaron al servidor VPN mientras ocurría el bloqueo. Ninguno fue mayor que el recuento de 1400 bytes especificado, por lo que la fragmentación parece estar funcionando correctamente.

  • Para verificar que incluso una MTU de 1400 bytes sería suficiente, fijé el servidor VPN usando el siguiente comando (Linux):

    ping <host> -s 1450 -M do
    

    Esto (creo) envía un paquete de 1450 bytes con fragmentación desactivada (al menos verifiqué que no funcionaba si lo configuraba en un valor obviamente demasiado grande como 1600 bytes). Estos parecen funcionar bien; Recibo respuestas del host sin problemas.

Entonces, tal vez esto no sea un problema de MTU en absoluto. ¡Estoy confundido sobre qué más podría ser!

Edición 2: La madriguera del conejo sigue profundizándose: ahora he aislado el problema un poco más. Parece estar relacionado con el sistema operativo exacto que utiliza el cliente VPN. He duplicado con éxito el problema en al menos tres máquinas Ubuntu (versiones 12.04 a 13.04). Puedo duplicar de manera confiable un congelamiento de conexión SSH en un minuto más o menos simplemente haciendo catun gran archivo de registro.

Sin embargo , si hago la misma prueba usando una máquina CentOS 6 como cliente, ¡entonces no veo el problema! He probado usando exactamente la misma versión de cliente OpenVPN que estaba usando en las máquinas Ubuntu. Puedo catregistrar archivos durante horas sin ver la conexión congelada. Esto parece proporcionar una idea de la causa final, pero no estoy seguro de cuál es esa idea.

He examinado el tráfico a través de la VPN usando Wireshark. No soy un experto en TCP, por lo que no estoy seguro de qué hacer con los detalles sangrientos, pero lo esencial es que en algún momento, un paquete UDP se descarta debido al ancho de banda limitado del enlace de Internet, lo que provoca retransmisiones TCP en el interior El túnel VPN. En el cliente CentOS, estas retransmisiones se producen correctamente y las cosas se mueven felizmente. Sin embargo, en algún momento con los clientes de Ubuntu, el extremo remoto comienza a retransmitir el mismo segmento TCP una y otra vez (con el retraso de transmisión aumentando entre cada retransmisión). El cliente envía lo que parece un ACK TCP válido a cada retransmisión, pero el extremo remoto sigue transmitiendo periódicamente el mismo segmento TCP. Esto se extiende hasta el infinito y la conexión se detiene. Mi pregunta aquí sería:

  • ¿Alguien tiene alguna recomendación sobre cómo solucionar problemas y / o determinar la causa raíz del problema de TCP? Es como si el extremo remoto no aceptara los mensajes ACK enviados por el cliente VPN.

Una diferencia común entre el nodo CentOS y las diversas versiones de Ubuntu es que Ubuntu tiene una versión de kernel de Linux mucho más reciente (de 3.2 en Ubuntu 12.04 a 3.8 en 13.04). ¿Un puntero a algún nuevo error del kernel quizás? Supongo que si fuera así, entonces no sería el único que experimentaría el problema; No creo que esto parezca una configuración particularmente exótica.


El enrutamiento de paquetes de multidifusión a través de una tunred debería ser posible mediante la ejecución de daemons de enrutamiento de multidifusión (como pimd ) y hacer que el servidor OpenVPN use las --topologyopciones establecidas en "subred" - consulte el manual
kostix

¿El cliente o servidor VPN indica algo en los registros en el momento de estos problemas?
mgorven

@mgorven: Definitivamente no en el cliente. Tendré que hacer un trabajo para llegar a los registros del servidor.
Jason R

@mgorven: Finalmente tuve la oportunidad de volver a esto. Nada de esto se registra en el cliente o en el servidor cuando esto sucede. Es realmente desconcertante.
Jason R

1
¿Existe alguna posibilidad de que los clientes que se congelen tengan firewalls locales que descarten los paquetes necesarios para la fragmentación de ICMP, mientras que aquellos que no lo hacen, y por lo tanto se fragmentan correctamente?
MadHatter apoya a Monica el

Respuestas:


10

Este comando lo resuelve por mí:

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

Puede verificar la configuración de tun0 con

$ ip a s

¡Salud!


¿En el lado del cliente o del servidor?
Matt

¡Muchas gracias! @ Matt, depende de dónde se encuentre el problema. Para nosotros fue en el servidor, pero puede estar en el lado del cliente. También el valor puede diferir, puede probar con ping <host> -s 1350 -M dopara encontrar el valor correcto
Eino Gourdin

2

Deshabilite el escalado de ventanas en TCP, con:

sysctl -w net.ipv4.tcp_window_scaling=0

Después de hacer eso, los sistemas SSH a Debian / Ubuntu a través de VPN están funcionando bien para mí.


0

En Windows que usa Putty, debe cambiar la MTU yendo a la conexión local para la conexión vpn -> detalles en la interfaz de red (adaptador de Windows TAP o algo así) -> Avanzado -> Propiedades -> MTU (cámbielo a algo inferior a 1500). Puede que tenga que volver a conectar. Funcionó para mí en Windows y Putty


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.