Débit TCP OpenVPN très faible (port 100Mbit, faible utilisation CPU)

27

Je connais des taux de transfert OpenVPN extrêmement lents entre deux serveurs. Pour cette question, je vais appeler les serveurs Serveur A et Serveur B.

Le serveur A et le serveur B exécutent CentOS 6.6. Les deux sont situés dans des centres de données avec une ligne de 100 Mbits et les transferts de données entre les deux serveurs en dehors d'OpenVPN tournent près de ~ 88 Mbps.

Cependant, lorsque j'essaie de transférer des fichiers via la connexion OpenVPN que j'ai établie entre le serveur A et le serveur B, j'obtiens un débit d'environ 6,5 Mbps.

Résultats des tests d'iperf:

[  4] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49184
[  4]  0.0-10.0 sec  7.38 MBytes  6.19 Mbits/sec
[  4]  0.0-10.5 sec  7.75 MBytes  6.21 Mbits/sec
[  5] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49185
[  5]  0.0-10.0 sec  7.40 MBytes  6.21 Mbits/sec
[  5]  0.0-10.4 sec  7.75 MBytes  6.26 Mbits/sec

Mis à part ces tests OpenVPN iperf, les deux serveurs sont pratiquement complètement inactifs avec une charge nulle.

Le serveur A se voit attribuer l'IP 10.0.0.1 et c'est le serveur OpenVPN. Le serveur B se voit attribuer l'IP 10.0.0.2 et c'est le client OpenVPN.

La configuration OpenVPN pour le serveur A est la suivante:

port 1194
proto tcp-server
dev tun0
ifconfig 10.0.0.1 10.0.0.2
secret static.key
comp-lzo
verb 3

La configuration OpenVPN pour le serveur B est la suivante:

port 1194
proto tcp-client
dev tun0
remote 204.11.60.69
ifconfig 10.0.0.2 10.0.0.1
secret static.key
comp-lzo
verb 3

Ce que j'ai remarqué:

1. Ma première pensée a été que je goulot d'étranglement du CPU sur le serveur. OpenVPN est monothread et ces deux serveurs exécutent des processeurs Intel Xeon L5520 qui ne sont pas les plus rapides. Cependant, j'ai exécuté une topcommande lors de l'un des tests iperf et j'ai appuyé 1pour afficher l'utilisation du processeur par cœur et j'ai constaté que la charge du processeur était très faible sur chaque cœur:

top - 14:32:51 up 13:56,  2 users,  load average: 0.22, 0.08, 0.06
Tasks: 257 total,   1 running, 256 sleeping,   0 stopped,   0 zombie
Cpu0  :  2.4%us,  1.4%sy,  0.0%ni, 94.8%id,  0.3%wa,  0.0%hi,  1.0%si,  0.0%st
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Cpu3  :  0.3%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu7  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu8  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu9  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu10 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu11 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu12 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu13 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu14 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu15 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    946768k total,   633640k used,   313128k free,    68168k buffers
Swap:  4192188k total,        0k used,  4192188k free,   361572k cached

2. Les temps de ping augmentent considérablement sur le tunnel OpenVPN pendant que iperf est en cours d'exécution. Lorsque iperf n'est pas en cours d'exécution, les temps de ping sur le tunnel sont systématiquement de 60 ms (normal). Mais lorsque iperf fonctionne et pousse un trafic dense, les temps de ping deviennent irréguliers. Vous pouvez voir ci-dessous comment les temps de ping sont stables jusqu'au 4ème ping lorsque j'ai commencé le test iperf:

PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=60.2 ms
** iperf test begins **
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=146 ms
64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=114 ms
64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=85.6 ms
64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=176 ms
64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=204 ms
64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=231 ms
64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=197 ms
64 bytes from 10.0.0.2: icmp_seq=11 ttl=64 time=233 ms
64 bytes from 10.0.0.2: icmp_seq=12 ttl=64 time=152 ms
64 bytes from 10.0.0.2: icmp_seq=13 ttl=64 time=216 ms

3. Comme mentionné ci-dessus, j'ai exécuté iperf en dehors du tunnel OpenVPN et le débit était normal - ~ 88 Mbps en permanence.

Ce que j'ai essayé:

1. Je pensais que la compression pouvait salir les choses, j'ai donc désactivé la compression en supprimant les comp-lzodeux configurations et en redémarrant OpenVPN. Pas d'amélioration.

2. Même si j'avais précédemment constaté que l'utilisation du processeur était faible, je pensais que le chiffrement par défaut pouvait être un peu trop intensif pour que le système puisse suivre. J'ai donc ajouté cipher RC2-40-CBCaux deux configurations (un chiffrement très léger) et redémarré OpenVPN. Pas d'amélioration.

3. J'ai lu sur divers forums comment l'ajustement du fragment, de mssfix et de mtu-tun pourrait améliorer les performances. J'ai joué avec quelques variations comme décrit dans cet article , mais encore une fois, aucune amélioration.

Avez-vous des idées sur ce qui pourrait causer de si mauvaises performances OpenVPN?

Elliot B.
la source
Est-ce que des liens, des commentaires d'ici aident? forums.openvpn.net/topic10593.html
Matt
La plupart des suggestions qu'il contient sont des choses que j'ai déjà essayées: 1. vérifier les goulots d'étranglement du processeur, 2. vérifier les vitesses de transfert sans VPN, 3. basculer la compression, 4. choisir un chiffrement plus rapide, etc. Pas de chance avec l'un d'eux pourtant: - / C'est bizarre. Mis à part la vitesse lente et les temps de ping élevés / volatils, je ne vois aucune autre indication de l'emplacement du goulot d'étranglement.
Elliot B.
Les deux machines se trouvent-elles dans le même centre de données? 60 ms dans le même centre de données est assez élevé. Je pourrais être tenté d'essayer cipher nonemême si je doute que cela puisse aider.
Zoredache
@Zoredache Désolé - je n'étais pas clair sur l'emplacement des serveurs - le serveur A est à Dallas et le serveur B est à Seattle.
Elliot B.
Avez-vous vérifié MTU? Esp: paramètres tun-mtu, fragment et mssfix? Documentation
Lenniey

Réponses:

26

Après beaucoup de recherches sur Google et de fichiers de configuration, j'ai trouvé la solution. J'obtiens maintenant des vitesses soutenues de 60 Mbps et j'éclate jusqu'à 80 Mbps. C'est un peu plus lent que les taux de transfert que je reçois en dehors du VPN, mais je pense que c'est aussi bon que possible.

La première étape consistait à définir sndbuf 0et rcvbuf 0dans la configuration OpenVPN pour le serveur et le client.

J'ai fait ce changement après avoir vu une suggestion de le faire sur un post du forum public (qui est une traduction anglaise d'un post original russe ) que je citerai ici:

Nous sommes en juillet 2004. La vitesse Internet domestique habituelle dans les pays développés est de 256-1024 Kbit / s, dans les pays moins développés, elle est de 56 Kbit / s. Linux 2.6.7 a été publié il n'y a pas longtemps et 2.6.8, où la mise à l'échelle de la taille TCP Windows serait activée par défaut, n'est publié que dans un mois. OpenVPN est en développement actif depuis 3 ans déjà, la version 2.0 est presque sortie. L'un des développeurs décide d'ajouter du code pour le tampon de socket, je pense que pour unifier les tailles de tampon entre les systèmes d'exploitation. Dans Windows, quelque chose ne va pas avec le MTU des adaptateurs si des tailles de tampons personnalisées sont définies, donc finalement il est transformé en le code suivant:

#ifndef WIN32
o->rcvbuf = 65536;
o->sndbuf = 65536;
#endif

Si vous avez utilisé OpenVPN, vous devez savoir qu'il peut fonctionner sur TCP et UDP. Si vous définissez une valeur de tampon de socket TCP personnalisée aussi faible que 64 Ko, l'algorithme de mise à l'échelle de la taille de la fenêtre TCP ne peut pas ajuster la taille de la fenêtre à plus de 64 Ko. Qu'est-ce que ça veut dire? Cela signifie que si vous vous connectez à un autre site VPN via un lien long, c'est-à-dire des États-Unis à la Russie avec un ping d'environ 100 ms, vous ne pouvez pas obtenir une vitesse supérieure à 5,12 Mbit / s avec les paramètres de tampon OpenVPN par défaut. Vous avez besoin d'au moins 640 Ko de mémoire tampon pour obtenir 50 Mbit / s sur cette liaison. UDP fonctionnerait plus rapidement car il n'a pas de taille de fenêtre mais ne fonctionnera pas non plus très rapidement.

Comme vous pouvez déjà le deviner, la dernière version d'OpenVPN utilise toujours une taille de tampon de socket de 64 Ko. Comment devrions-nous résoudre ce problème? La meilleure façon consiste à interdire à OpenVPN de définir des tailles de tampon personnalisées. Vous devez ajouter le code suivant dans les fichiers de configuration du serveur et du client:

sndbuf 0
rcvbuf 0

L'auteur poursuit en décrivant comment pousser les ajustements de la taille de la mémoire tampon vers le client si vous ne contrôlez pas vous-même la configuration du client.

Après avoir effectué ces modifications, mon débit a augmenté jusqu'à 20 Mbps. J'ai ensuite vu que l'utilisation du processeur était un peu élevée sur un seul cœur, j'ai donc supprimé comp-lzo(compression) de la configuration à la fois sur le client et le serveur. Eureka! Les vitesses de transfert ont grimpé jusqu'à 60 Mbps en continu et 80 Mbps en rafale.

J'espère que cela aide quelqu'un d'autre à résoudre ses propres problèmes avec la lenteur d'OpenVPN!

Elliot B.
la source
4

Après quelques essais, j'ai trouvé une bonne solution. Dans mon cas, la réponse de @ Elliot n'a pas aidé. Googler plus, j'ai découvert cet extrait pour ajouter la configuration du serveur qui a fait le travail

sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"

J'ai un petit serveur OpenVPN fonctionnant sur un Raspberry PI3 et maintenant je reçois 71 Mbps en liaison descendante et 16Mbps en liaison montante . Le téléchargement est limité car la puissance du processeur. En ce moment, ma configuration est la suivante:

client-to-client
duplicate-cn
keepalive 10 120
cipher AES-128-CBC
#cipher AES-256-CBC <<<---- lowers the speed to around 50Mbps, still not bad
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
tun-mtu 9000

OpenVPN 2.4.0 arm-unknown-linux-gnueabihf avec OpenSSL 1.0.2l

Cela semble tellement bizarre qu'un tel problème concernant la configuration par défaut d'un tampon existe toujours.

[ MODIFIER ] Mon fichier client.ovpn est structuré comme suit:

client
dev tun
proto tcp
remote SERVER.IP.ADDRESS.HERE
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
tun-mtu 9000
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
<ca>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
[...]
-----END OpenVPN Static key V1-----
</tls-auth>
Noyau
la source
La définition de tailles de tampon m'a aidé.
Rolf
qu'avez-vous mis dans le fichier .ovpn du client?
Patoshi パ ト シ
@Patoshi パ ト シ J'ai commenté sndbuf et recbuf, mis le chiffrement et la compression correspondants et laissé les paramètres par défaut.
Noyau
@Kernel pouvez-vous me montrer ce que vous avez chez votre client? Je fais une connexion OpenVPN de Hong Kong à NYC et ses déconnexions lentes et parfois aléatoires. Je ne sais pas pourquoi.
Patoshi パ ト シ
@Patoshi パ ト シ J'ai modifié ma réponse, vérifiez-la à nouveau. Néanmoins, je vous suggère d'essayer d'utiliser UDP à la place, car cela pourrait vous aider à résoudre le problème d'une liaison instable avec votre serveur. En effet, c'est juste une hypothèse, je n'ai jamais essayé de comparer cette solution dans cette situation.
Noyau
1

Selon la configuration, vous utilisez TCP comme transport pour le tunnel. Envisagez d'utiliser UDP au lieu de TCP, car la tente de connexions TCP empilées crée des problèmes dans les situations de perte de paquets.

Comme référence, voir Pourquoi TCP sur TCP est une mauvaise idée

Lairsdragon
la source
Malheureusement, UDP n'est pas une option pour nous. Nous devons nous assurer que les paquets de données que nous transmettons arrivent comme prévu. Néanmoins, nous avons expérimenté l'UDP plus tôt et les faibles taux de transfert étaient toujours un problème.
Elliot B.
6
We need to ensure that the data packets we transmit arrive as expected.et n'est-ce pas géré par le protocole qui est tunnelisé? Pourquoi pensez-vous que votre tunnel doit être la chose qui impose cela?
Zoredache
C'est probablement le cas, mais nous utilisons OpenVPN pour une implémentation asynchrone DRBD longue distance (c'est-à-dire la réplication du système de fichiers). L'intégrité des données est vraiment importante, donc même si DRBD a probablement des mécanismes internes pour vérifier l'intégrité du transfert, je préfère le garder sur TCP. Quoi qu'il en soit, lorsque nous l'avions sur UDP, nous avions toujours le faible débit.
Elliot B.
3
@ElliotB. Comme DRBD lui-même utilise TCP pour la réplication, il retransmettra en cas de perte du paquet OpenVPN UDP. En fait, en utilisant TCP dans ce cas, vous ferez deux retransfert au lieu d'un ... dont l'un va être jeté. Et vous pouvez créer une fenêtre assez longue sans trafic DRBD (même obtenir une réplication interrompue à cause de cela). Une fois que vous aurez perdu des paquets sur l'itinéraire, vous verrez à quel point c'est mauvais de penser.
Fox
@Fox Merci d'avoir fourni des éclaircissements! En effet, DRBD utilise TCP (drbd.linbit.com/users-guide/s-prepare-network.html). La suggestion précédente de Lairsdragon de passer à UDP n'était pas pertinente à l'époque, car UDP connaissait également des taux de transfert extrêmement bas, mais depuis la mise en œuvre de la solution que j'ai postée ci-dessus, nous sommes passés à UDP et avons connu un autre gain de performances de quelques Mbps.
Elliot B.
1

Nous avons deux serveurs intercontinentaux reliés entre eux, les vitesses entre eux oscillant autour de 220 Mbit / s.

Cependant, à l'intérieur du tunnel OpenVPN (UDP), les vitesses seraient en moyenne de 21 Mbit / s, soit environ 10 fois plus lentement.

(Il y a une latence importante entre les serveurs: environ 130 ms, et les transferts ont été mesurés en utilisant Iperf3 en mode TCP.)

J'ai essayé toutes les suggestions de réponses ici au moment de la rédaction de cet article, et rien n'a aidé.

La seule chose qui a finalement aidé est ce petit peu:

--txqueuelen 4000

Selon le manuel de référence OpenVPN:

–txqueuelen n 
(Linux only) Set the TX queue length on the TUN/TAP interface. Currently defaults to 100.

Après avoir défini ce paramètre sur le serveur et le client, j'ai pu atteindre les mêmes vitesses de «liaison directe» (~ 250 Mbit / s) également sous le tunnel OpenVPN.

J'utilisais déjà le rcvbuf 0 et sndbuf 0, mais au moins seul , ils n'ont pas aidé du tout.

J'ai trouvé ces recommandations dans les deux: cette page dans les forums OpenVPN , et aussi dans cette page dans le wiki UDPspeeder .

Sur une autre note: j'ai pu atteindre des vitesses plus élevées en utilisant des transferts UDP dans iperf, mais cela entraînerait également une perte de paquets raisonnablement élevée.

Si, par hasard, vous avez besoin d'utiliser un VPN pour tunneler deux endroits avec des liaisons avec perte, je vous conseille d'envisager d'utiliser une sorte de tunnel de correction d'erreur vers l'avant (FEC) sous le VPN lui-même. Les deux que j'ai réussi à trouver et à travailler sont:

Les deux peuvent aider beaucoup avec la perte de paquets (en dépensant plus de bande passante en premier lieu), et finalement même conduire à un débit de données plus élevé, même avec la surcharge supplémentaire, ce qui est vraiment bien si vous me demandez.

(C'est parce que la perte de paquets peut vraiment gâcher un réseau , spécialement TCP . Voir page 6.)

J'aurais préféré utiliser OpenVPN sur UDP, pour toutes les raisons habituelles, mais j'ai eu du mal à gérer UDPspeeder lorsque vous avez à la fois une latence de plus de 100 ms et des vitesses de> 10 Mbit / s.

Cependant, kcptun a très bien fonctionné avec très peu de réglages et a vraiment augmenté le débit de nos serveurs les uns avec les autres. =)

Sur une note étendue, vous trouverez ici des explications plus détaillées sur la modification de certaines parties des performances d'OpenVPN.

Vinícius M
la source
0

Pour moi, j'avais un serveur VPS avec une configuration de serveur openvpn au Japon et ma connexion client utilisait un DDWRT en mode client OpenVPN à New York. J'obtenais seulement 1-2mbps sur une connexion de 100mbit. Le mieux que j'ai pu l'optimiser était de 5 Mbps, ce qui était suffisant pour ce dont j'avais besoin, qui est aussi optimisé que possible, je crois.

Paramètres de mon serveur OpenVPN:

tun-mtu 9000
sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
comp-lzo
txqueuelen 4000
######
port 10111
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server x.x.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 1.0.0.1"
push "dhcp-option DNS 1.1.1.1"
push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
#tls-crypt tls-crypt.key 0
crl-verify crl.pem
ca ca.crt
cert server_IzA1QdFzHLRFfEoQ.crt
key server_IzA1QdFzHLRFfEoQ.key
auth SHA256
#cipher AES-128-GCM
#cipher AES-128-CBC
#ncp-ciphers AES-128-GCM
#ncp-ciphers AES-128-CBC
#tls-server
#tls-version-min 1.2
#tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
#tls-cipher TLS-DHE-RSA-WITH-AES-128-CBC-SHA
status /var/log/openvpn/status.log
verb 3

Mes paramètres client DDWRT OpenVPN sont également visibles dans ma capture d'écran:

tun-mtu 9000
comp-lzo
##########
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_IzA1QdFzHLRFfEoQ name
auth SHA256
auth-nocache
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3

entrez la description de l'image ici

entrez la description de l'image ici

Patoshi パ ト シ
la source