Comment empêcher le gel de la connexion TCP sur un réseau OpenVPN?


19

Nouveaux détails ajoutés à la fin de cette question; il est possible que je me concentre sur la cause.

J'ai un VPN basé sur UDP OpenVPN configuré en tapmode (j'ai besoin tapparce que j'ai besoin du VPN pour passer des paquets de multidiffusion, ce qui ne semble pas être possible avec les tunréseaux) avec une poignée de clients sur Internet. J'ai rencontré des gels de connexion TCP fréquents sur le VPN. C'est-à-dire que j'établirai une connexion TCP (par exemple une connexion SSH, mais d'autres protocoles ont des problèmes similaires), et à un moment donné de la session, il semble que le trafic cessera d'être transmis sur cette session TCP.

Cela semble être lié à des points où des transferts de données importants se produisent, comme si j'exécute une lscommande dans une session SSH, ou si j'ai catun long fichier journal. Certaines recherches Google révèlent un certain nombre de réponses comme celle-ci sur la défaillance du serveur , indiquant que le coupable probable est un problème de MTU: que pendant les périodes de trafic élevé, le VPN essaie d'envoyer des paquets qui sont déposés quelque part dans les tuyaux entre le Points de terminaison VPN. La réponse liée ci-dessus suggère d'utiliser les paramètres de configuration OpenVPN suivants pour atténuer le problème:

fragment 1400
mssfix

Cela devrait limiter le MTU utilisé sur le VPN à 1400 octets et fixer la taille de segment maximale TCP pour empêcher la génération de paquets plus volumineux. Cela semble atténuer un peu le problème, mais je constate toujours fréquemment des blocages. J'ai essayé un certain nombre de tailles comme arguments de la fragmentdirective: 1200, 1000, 576, toutes avec des résultats similaires. Je ne peux pas penser à une topologie de réseau étrange entre les deux extrémités qui pourrait déclencher un tel problème: le serveur VPN fonctionne sur une machine pfSense connectée directement à Internet, et mon client est également connecté directement à Internet à un autre endroit.

Une autre pièce étrange du puzzle: si je lance l' tracepathutilitaire, cela semble résoudre le problème. Un exemple de cycle ressemble à:

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

L'exécution ci-dessus se fait entre deux clients sur le VPN: j'ai initié la trace de 192.168.100.90à la destination de 192.168.100.91. Les deux clients ont été configurés avec fragment 1200; mssfix;pour tenter de limiter le MTU utilisé sur la liaison. Les résultats ci-dessus semblent suggérer qu'il tracepatha pu détecter un chemin MTU de 1500 octets entre les deux clients. Je suppose qu'il serait un peu plus petit en raison des paramètres de fragmentation spécifiés dans la configuration OpenVPN. J'ai trouvé ce résultat quelque peu étrange.

Encore plus étrange, cependant: si j'ai une connexion TCP à l'état bloqué (par exemple une session SSH avec une liste de répertoires qui a gelé au milieu), alors l' exécution de la tracepathcommande ci-dessus provoque la connexion à redémarrer ! Je ne peux pas trouver d'explication raisonnable pour expliquer pourquoi cela serait le cas, mais je pense que cela pourrait indiquer une solution pour éradiquer le problème.

Quelqu'un a-t-il des recommandations pour d'autres choses à essayer?

Edit: Je suis revenu et j'ai regardé cela un peu plus loin, et je n'ai trouvé que des informations plus confuses:

  • J'ai défini la connexion OpenVPN pour fragmenter à 1400 octets, comme indiqué ci-dessus. Ensuite, je me suis connecté au VPN sur Internet et j'ai utilisé Wireshark pour regarder les paquets UDP qui ont été envoyés au serveur VPN pendant le blocage. Aucun n'était supérieur au nombre spécifié de 1400 octets, de sorte que la fragmentation semble fonctionner correctement.

  • Pour vérifier que même un MTU de 1400 octets serait suffisant, j'ai envoyé une requête ping au serveur VPN à l'aide de la commande (Linux) suivante:

    ping <host> -s 1450 -M do
    

    Cela (je crois) envoie un paquet de 1450 octets avec la fragmentation désactivée (j'ai au moins vérifié que cela ne fonctionnait pas si je le définissais sur une valeur évidemment trop grande comme 1600 octets). Ceux-ci semblent très bien fonctionner; Je reçois des réponses de l'hôte sans problème.

Donc, ce n'est peut-être pas du tout un problème de MTU. Je suis juste confus quant à ce que cela pourrait être d'autre!

Edit 2: Le trou du lapin ne cesse de s'approfondir: j'ai maintenant un peu plus isolé le problème. Il semble être lié au système d'exploitation exact que le client VPN utilise. J'ai dupliqué le problème avec succès sur au moins trois machines Ubuntu (versions 12.04 à 13.04). Je peux dupliquer de manière fiable un gel de connexion SSH en une minute environ en juste cat-ing un gros fichier journal.

Cependant , si je fais le même test en utilisant une machine CentOS 6 en tant que client, je ne vois pas le problème! J'ai testé en utilisant exactement la même version du client OpenVPN que j'utilisais sur les machines Ubuntu. Je peux catenregistrer des fichiers pendant des heures sans voir le gel de la connexion. Cela semble fournir un aperçu de la cause ultime, mais je ne suis tout simplement pas sûr de ce qu'est cet aperçu.

J'ai examiné le trafic sur le VPN à l'aide de Wireshark. Je ne suis pas un expert TCP, donc je ne sais pas quoi faire des détails sanglants, mais l'essentiel est qu'à un moment donné, un paquet UDP est abandonné en raison de la bande passante limitée de la liaison Internet, provoquant des retransmissions TCP à l'intérieur le tunnel VPN. Sur le client CentOS, ces retransmissions se produisent correctement et les choses évoluent joyeusement. À un certain point avec les clients Ubuntu, cependant, l'extrémité distante commence à retransmettre le même segment TCP encore et encore (avec le délai de transmission augmentant entre chaque retransmission). Le client envoie ce qui ressemble à un ACK TCP valide à chaque retransmission, mais l'extrémité distante continue de transmettre périodiquement le même segment TCP. Cela s'étend à l'infini et la connexion est interrompue. Ma question ici serait:

  • Quelqu'un at-il des recommandations sur la façon de dépanner et / ou de déterminer la cause première du problème TCP? C'est comme si l'extrémité distante n'acceptait pas les messages ACK envoyés par le client VPN.

Une différence commune entre le nœud CentOS et les différentes versions d'Ubuntu est qu'Ubuntu a une version du noyau Linux beaucoup plus récente (de 3.2 dans Ubuntu 12.04 à 3.8 en 13.04). Un pointeur vers un nouveau bug du noyau peut-être? Je suppose que s'il en était ainsi, je ne serais pas le seul à rencontrer le problème; Je ne pense pas que cela semble être une configuration particulièrement exotique.


Le routage de paquets de multidiffusion sur un tunréseau devrait être possible en exécutant des démons de routage de multidiffusion (tels que pimd ) et en ayant le serveur OpenVPN utiliser les --topologyoptions définies sur "sous-réseau" - voir le manuel
kostix

Le client ou le serveur VPN indique-t-il quelque chose dans les journaux au moment de ces problèmes?
mgorven

@mgorven: Certainement pas sur le client. Je vais devoir faire un peu de travail pour accéder aux journaux du serveur.
Jason R

@mgorven: J'ai enfin eu l'occasion d'y revenir. Rien du tout dans les journaux du client ou du serveur lorsque cela se produit. C'est vraiment déroutant.
Jason R

1
Y a-t-il une possibilité que les clients qui gèlent aient des pare-feu locaux qui abandonnent les paquets nécessaires à la fragmentation ICMP, alors que ceux qui ne le font pas, ne le font pas et se fragmentent donc correctement?
MadHatter prend en charge Monica

Réponses:


10

Cette commande le résout pour moi:

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

Vous pouvez vérifier les paramètres tun0 avec

$ ip a s

À votre santé!


Côté client ou serveur ??
Matt

Merci beaucoup! @Matt, cela dépend où se situe le problème. Pour nous, c'était sur le serveur, mais c'est peut-être du côté client. La valeur peut également différer, vous pouvez tester avec ping <host> -s 1350 -M dopour trouver la bonne valeur
Eino Gourdin

2

Désactivez la mise à l'échelle des fenêtres dans TCP, avec:

sysctl -w net.ipv4.tcp_window_scaling=0

Après cela, SSH vers les systèmes Debian / Ubuntu via VPN fonctionne bien pour moi.


0

Sur Windows en utilisant Putty, vous devez changer le MTU en allant à la connexion locale pour la connexion vpn -> détails sur l'interface réseau (adaptateur Windows TAP ou quelque chose comme ça) -> Avancé -> Propriétés -> MTU (changez-le en quelque chose inférieur à 1500). Vous devrez peut-être vous reconnecter. Cela a fonctionné pour moi sur Windows et Putty


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.