Taxa de transferência de TCP OpenVPN muito baixa (porta de 100 Mbit, baixa utilização da CPU)

22

Estou experimentando taxas de transferência extremamente lentas do OpenVPN entre dois servidores. Para essa pergunta, chamarei os servidores Servidor A e Servidor B.

Tanto o Servidor A quanto o Servidor B estão executando o CentOS 6.6. Ambos estão localizados em datacenters com uma linha de 100Mbit e as transferências de dados entre os dois servidores fora do OpenVPN são executadas perto de ~ 88Mbps.

No entanto, quando tento transferir arquivos pela conexão OpenVPN que estabeleci entre o Servidor A e o Servidor B, recebo uma taxa de transferência de 6,5 Mbps.

Resultados do teste do 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

Além desses testes iperf do OpenVPN, os dois servidores estão praticamente ociosos com carga zero.

O servidor A recebe o IP 10.0.0.1 e é o servidor OpenVPN. O servidor B recebe o IP 10.0.0.2 e é o cliente OpenVPN.

A configuração do OpenVPN para o Servidor A é a seguinte:

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

A configuração do OpenVPN para o Servidor B é a seguinte:

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

O que eu notei:

1. Meu primeiro pensamento foi que eu estava colocando um gargalo na CPU no servidor. O OpenVPN é single-threaded e ambos os servidores executam processadores Intel Xeon L5520 que não são os mais rápidos. No entanto, executei um comando top durante um dos testes do iperf e pressionei 1 para visualizar a utilização da CPU pelo núcleo e descobri que a carga da CPU estava muito baixa em cada núcleo:

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. Os tempos de ping aumentam consideravelmente no túnel OpenVPN enquanto o iperf está em execução. Quando o iperf não está em execução, os tempos de ping no túnel são consistentemente de 60 ms (normal). Mas quando o iperf está rodando e enviando tráfego pesado, os tempos de ping se tornam erráticos. Você pode ver abaixo como os tempos de ping são estáveis até o 4º ping quando iniciei o teste 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. Como mencionado acima, eu corri iperf fora do túnel OpenVPN e a taxa de transferência era normal - ~ 88Mbps consistentemente.

O que eu tentei:

1. Eu pensei que a compactação poderia estar estragando tudo, então eu desliguei a compactação removendo comp-lzo das configurações e reiniciando o OpenVPN. Nenhuma melhoria.

2. Embora eu tenha descoberto anteriormente que a utilização da CPU estava baixa, achei que a criptografia padrão poderia ser um pouco intensiva demais para o sistema acompanhar. Então eu adicionei cipher RC2-40-CBC para ambas as configurações (uma cifra muito leve) e reiniciei o OpenVPN. Nenhuma melhoria.

3. Eu li em vários fóruns sobre como ajustar o fragmento, mssfix e mtu-tun pode ajudar com o desempenho. Joguei com algumas variações, conforme descrito em este artigo , mas, novamente, sem melhora.

Alguma idéia do que poderia estar causando um desempenho tão ruim do OpenVPN?

    
por Elliot B. 28.04.2015 / 23:43

4 respostas

22

Depois de vários ajustes no Googling e no arquivo de configuração, encontrei a solução. Agora estou obtendo velocidades sustentadas de 60Mbps e estouro de até 80Mbps. É um pouco mais lento do que as taxas de transferência que recebo fora da VPN, mas acho que isso é o melhor possível.

O primeiro passo foi definir sndbuf 0 e rcvbuf 0 na configuração do OpenVPN para o servidor e o cliente.

Eu fiz essa alteração depois de ver uma sugestão para fazê-lo em um postagem no fórum público (que é uma tradução em inglês de uma postagem original em russo ) que citarei aqui:

It's July, 2004. Usual home internet speed in developed countries is 256-1024 Kbit/s, in less developed countries is 56 Kbit/s. Linux 2.6.7 has been released not a long ago and 2.6.8 where TCP Windows Size Scaling would be enabled by default is released only in a month. OpenVPN is in active development for 3 years already, 2.0 version is almost released. One of the developers decides to add some code for socket buffer, I think to unify buffer sizes between OSes. In Windows, something goes wrong with adapters' MTU if custom buffers sizes are set, so finally it transformed to the following code:

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

If you used OpenVPN, you should know that it can work over TCP and UDP. If you set custom TCP socket buffer value as low as 64 KB, TCP Window Size Scaling algorithm can't adjust Window Size to more than 64 KB. What does that mean? That means that if you're connecting to other VPN site over long fat link, i.e. USA to Russia with ping about 100 ms, you can't get speed more than 5.12 Mbit/s with default OpenVPN buffer settings. You need at least 640 KB buffer to get 50 Mbit/s over that link. UDP would work faster because it doesn't have window size but also won't work very fast.

As you already may guess, the latest OpenVPN release still uses 64 KB socket buffer size. How should we fix this issue? The best way is to disallow OpenVPN to set custom buffer sizes. You should add the following code in both server and client config files:

sndbuf 0
rcvbuf 0

O autor prossegue descrevendo como enviar ajustes de tamanho do buffer para o cliente se você não estiver no controle da configuração do cliente.

Depois de fazer essas alterações, minha taxa de transferência aumentou para 20Mbps. Vi então que a utilização da CPU estava um pouco alta em um único núcleo, então removi comp-lzo (compactação) da configuração no cliente e no servidor. Eureka! As velocidades de transferência aumentaram para 60Mbps sustentadas e 80Mbps de burst.

Espero que isso ajude alguém a resolver seus próprios problemas com a lentidão do OpenVPN!

    
por 29.04.2015 / 23:47
3

Depois de algumas tentativas, cheguei a uma boa solução. No meu caso, a resposta do @ Elliot não ajudou. Pesquisando mais, descobri este snippet para adicionar a configuração do servidor que fez o trabalho

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

Eu tenho um pequeno servidor OpenVPN rodando em um Raspberry PI3 e agora recebo downlink de 71 Mbps e 16Mbps uplink . O download é limitado desde o poder da CPU. No momento, minha configuração é a seguinte:

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 com o OpenSSL 1.0.2l

Parece tão estranho que esse problema sobre a configuração padrão de um buffer ainda exista.

    
por 16.12.2017 / 14:50
1

De acordo com o Config, você está usando TCP como transporte para o Tunnel. Considere o uso de UDP em vez de TCP, já que as conexões TCP empilhadas tentam criar problemas em situações de perda de pacotes.

Como referência, consulte Por que o TCP sobre TCP é uma má idéia

    
por 29.04.2015 / 00:28
1

Temos dois servidores intercontinentais que se ligam entre si, com velocidades entre eles de 220 Mbit / s.

Dentro do túnel OpenVPN (UDP), no entanto, a velocidade seria de 21 Mbit / s - aproximadamente 10x mais lenta.

(Há uma latência significativa entre os servidores: cerca de 130 ms e as transferências foram medidas usando o Iperf3 no modo TCP.)

Tentei todas as sugestões de respostas aqui enquanto escrevia, e nada ajudou.

A única coisa que finalmente ajudou foi um pouco:

--txqueuelen 4000

De acordo com o manual de referência do OpenVPN:

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

Depois de definir esse parâmetro no servidor e no cliente, consegui atingir as mesmas velocidades de 'link direto' (~ 250Mbit / s) também sob o túnel OpenVPN.

Eu já estava usando o rcvbuf 0 e sndbuf 0 , mas pelo menos sozinho , eles não ajudaram em nada.

Encontrei estas recomendações em ambas: esta página nos fóruns do OpenVPN e também em esta página no wiki do UDPspeeder .

Em outra nota: eu consegui atingir velocidades mais altas usando transferências UDP no iperf, mas isso também causaria uma perda de pacotes razoavelmente alta.

Se por algum acaso você precisar usar VPN para encapsular dois locais com links com perdas, aconselho considerar o uso de algum tipo de encapsulamento FEC (Forward-Error-Correction) sob a própria VPN. Os dois que eu consegui encontrar e trabalhar são:

  • O UDPspeeder acima mencionado, que encapsula as conexões UDP;
  • kcptun , que encapsula conexões TCP;
Ambos podem ajudar muito com o packetloss (gastando mais largura de banda em primeiro lugar) e, em última análise, até mesmo levando a uma maior taxa de transferência de dados, mesmo com a sobrecarga adicionada, o que é realmente interessante se você me perguntar.

(Isso porque perda de pacotes pode realmente estragar um rede , especialmente TCP . Veja a página 6.)

Eu preferiria usar o OpenVPN no UDP, por todos os motivos usuais, mas achei difícil lidar com o UDPspeeder quando você tem mais de 100ms de latência & > velocidades de 10 Mbit / s.

No entanto, o kcptun funcionou muito bem com muito poucos ajustes e, na verdade, realmente aumentaram a taxa de transferência de nossos servidores uns com os outros. =)

Em uma nota extensa, aqui você pode encontrar explicações mais detalhadas sobre ajustes em algumas partes do Desempenho do OpenVPN.

    
por 05.11.2018 / 18:11