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

27

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

O Servidor A e 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, obtive uma taxa de transferência de cerca 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 de IPVer 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 estrangulando a CPU no servidor. O OpenVPN é de thread único e ambos os servidores executam processadores Intel Xeon L5520, que não são os mais rápidos. No entanto, executei um topcomando durante um dos testes do iperf e pressionei 1para exibir a utilização da CPU por núcleo e constatei que a carga da CPU era 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 60ms (normal). Mas quando o iperf está rodando e gerando tráfego intenso, os tempos de ping se tornam irregulares. 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, executei o iperf fora do túnel OpenVPN e a taxa de transferência era normal - ~ 88 Mbps de forma consistente.

O que eu tentei:

1. Pensei que a compactação estivesse atrapalhando as coisas, então desativei a compactação removendo as comp-lzoduas configurações e reiniciando o OpenVPN. Nenhuma melhoria.

2. Embora eu tenha achado anteriormente que a utilização da CPU era baixa, achei que a cifra padrão poderia ser um pouco intensa para o sistema acompanhar. Então, adicionei cipher RC2-40-CBCàs duas 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, o mssfix e o mtu-tun podem ajudar no desempenho. Joguei com algumas variações, conforme descrito neste artigo , mas, novamente, nenhuma melhoria.

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

Elliot B.
fonte
Algum link ou comentário daqui ajuda? forums.openvpn.net/topic10593.html
Matt
A maioria das sugestões já contém algumas coisas que eu já tentei: 1. verifique o gargalo da CPU, 2. verifique as velocidades de transferência sem VPN, 3. alterne a compactação, 4. escolha uma cifra mais rápida, etc. Sem sorte com nenhuma delas ainda: - / É bizarro. Além da velocidade lenta e dos tempos de ping alto / volátil, não vejo outra indicação de onde possa estar o gargalo.
Elliot B.
As duas máquinas estão no mesmo datacenter? 60ms no mesmo data center é bastante alto. Eu posso ficar tentado a tentar, cipher noneembora duvide que isso ajude.
Zoredache
@ Zoredache Desculpe - eu não estava claro sobre a localização dos servidores - o servidor A está em Dallas e o servidor B está em Seattle.
Elliot B.
Você verificou o MTU? Esp: parâmetros tun-mtu, fragment e mssfix? Documentação
Lenniey

Respostas:

26

Após muitos ajustes no Google e no arquivo de configuração, encontrei a solução. Agora estou obtendo velocidades sustentadas de 60 Mbps e estourou até 80 Mbps. É um pouco mais lento que as taxas de transferência que recebo fora da VPN, mas acho que é o melhor possível.

A primeira etapa foi definir sndbuf 0e rcvbuf 0na configuração do OpenVPN para o servidor e o cliente.

Fiz essa alteração depois de receber uma sugestão em uma postagem pública do fórum (que é uma tradução em inglês de uma postagem original em russo ) que cito aqui:

É julho de 2004. A velocidade usual da internet doméstica nos países desenvolvidos é de 256 a 1024 Kbit / s, nos países menos desenvolvidos é de 56 Kbit / s. O Linux 2.6.7 foi lançado há pouco tempo e o 2.6.8, em que o TCP Windows Size Scaling seria ativado por padrão, é lançado apenas em um mês. O OpenVPN está em desenvolvimento ativo há 3 anos, a versão 2.0 está quase lançada. Um dos desenvolvedores decide adicionar algum código para o buffer de soquete, penso em unificar os tamanhos de buffer entre os sistemas operacionais. No Windows, algo dá errado com a MTU dos adaptadores se tamanhos de buffers personalizados estiverem definidos; portanto, finalmente, ele será transformado no seguinte código:

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

Se você usou o OpenVPN, deve saber que ele pode funcionar com TCP e UDP. Se você definir um valor de buffer de soquete TCP personalizado como mínimo de 64 KB, o algoritmo TCP Window Size Scaling não poderá ajustar o Tamanho da Janela para mais de 64 KB. O que isso significa? Isso significa que, se você estiver se conectando a outro site VPN por um longo link de gordura, ou seja, dos EUA à Rússia com ping de cerca de 100 ms, não poderá obter velocidade superior a 5,12 Mbit / s com as configurações padrão do buffer OpenVPN. Você precisa de pelo menos 640 KB de buffer para obter 50 Mbit / s nesse link. O UDP funcionaria mais rápido porque não possui tamanho de janela, mas também não funcionará muito rápido.

Como você já deve imaginar, a versão mais recente do OpenVPN ainda usa o tamanho do buffer de soquete de 64 KB. Como devemos corrigir esse problema? A melhor maneira é desabilitar o OpenVPN para definir tamanhos de buffer personalizados. Você deve adicionar o seguinte código nos arquivos de configuração do servidor e do cliente:

sndbuf 0
rcvbuf 0

O autor continua 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 20 Mbps. Vi então que a utilização da CPU era um pouco alta em um único núcleo e removi comp-lzo(compactação) da configuração no cliente e no servidor. Eureka! As velocidades de transferência saltaram até 60Mbps sustentadas e 80Mbps estouraram.

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

Elliot B.
fonte
4

Após algumas tentativas, cheguei a uma boa solução. No meu caso, a resposta de @ Elliot não ajudou. Pesquisando mais, descobri esse trecho para adicionar na 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 um downlink de 71 Mbps e um uplink de 16 Mbps . O download é limitado, pois 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 OpenSSL 1.0.2l

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

[EDIT] Meu arquivo client.ovpn está estruturado da seguinte maneira:

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>
Núcleo
fonte
Definir tamanhos de buffer me ajudou.
Rolf
o que você colocou no arquivo .ovpn do cliente?
Patoshi シ ト シ 13/01
@Patoshi シ ト シ Comentei sndbuf e recbuf, coloquei a cifra e a compactação de acordo e deixei os parâmetros padrão.
Kernel
@Kernel, você pode me mostrar o que tem no seu cliente? Estou fazendo uma conexão OpenVPN de Hong Kong a Nova York e é aleatoriamente lenta e às vezes desconecta. Não sei por que.
Patoshi シ ト シ 14/01
@Patoshi パ ト シ Eu editei minha resposta, verifique novamente. No entanto, sugiro que você tente usar o UDP, pois isso pode ajudá-lo a resolver o problema de um link instável com o servidor. Na verdade, é apenas uma suposição: nunca tentei comparar essa solução nessa situação.
Kernel
1

De acordo com as configurações, você está usando o TCP como transporte para o túnel. Considere usar UDP em vez de TCP, pois 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

Lairsdragon
fonte
Infelizmente, o UDP não é uma opção para nós. Precisamos garantir que os pacotes de dados que transmitimos cheguem conforme o esperado. No entanto, experimentamos o UDP mais cedo e as baixas taxas de transferência ainda eram um problema.
Elliot B.
6
We need to ensure that the data packets we transmit arrive as expected.e isso não é tratado pelo protocolo que está sendo encapsulado? Por que você acha que seu túnel precisa ser o que impõe isso?
Zoredache
Provavelmente é esse o caso, mas estamos usando o OpenVPN para uma implementação DRBD assíncrona a longa distância (ou seja, replicação do sistema de arquivos). A integridade dos dados é realmente importante, portanto, embora o DRBD provavelmente tenha mecanismos internos para verificar a integridade da transferência, prefiro mantê-lo no TCP. De qualquer forma, quando o tínhamos no UDP, ainda tínhamos o baixo rendimento.
Elliot B.
3
@ElliotB. Como o próprio DRBD usa o TCP para replicação, ele será retransmitido caso o pacote OpenVPN UDP seja perdido. Na verdade, usando o TCP, neste caso, você fará duas retransferências em vez de uma ... uma das quais será descartada. E você pode estar criando uma janela bastante longa sem tráfego DRBD (até mesmo uma replicação interrompida por causa disso). Depois de obter alguns pacotes perdidos na rota, você verá como isso é ruim.
Fox
@ Fox Obrigado por fornecer esclarecimentos! De fato, o DRBD usa TCP (drbd.linbit.com/users-guide/s-prepare-network.html). A sugestão anterior do Lairsdragon de mudar para o UDP não era relevante no momento porque o UDP também estava com taxas de transferência extremamente baixas, mas desde que implementamos a solução que eu postei acima, fizemos a mudança para o UDP e experimentamos outro ganho de desempenho de alguns Mbps.
Elliot B.
1

Temos dois servidores intercontinentais vinculados entre si, as velocidades entre eles oscilando em torno de 220 Mbit / s.

No entanto, dentro do túnel OpenVPN (UDP), as velocidades seriam médias de 21 Mbit / s - aproximadamente 10 vezes mais lenta.

(Existe 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 até o momento da redação deste documento 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 no túnel OpenVPN.

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

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

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

Se, por algum motivo, você precisar usar a VPN para encapsular dois locais com links com perdas, aconselho a considerar o uso de algum tipo de encapsulamento de correção de erro de encaminhamento (FEC) na própria VPN. Os dois que eu consegui encontrar e trabalhar são:

  • O mencionado UDPspeeder , que encapsula as conexões UDP;
  • kcptun , que encapsula conexões TCP;

Ambos podem ajudar muito com a perda de pacotes (gastando mais largura de banda em primeiro lugar) e, finalmente, levando a uma maior taxa de transferência de dados, mesmo com a sobrecarga adicional, o que é realmente interessante, se você me perguntar.

(Isso ocorre porque a perda de pacotes pode realmente atrapalhar uma rede , especialmente o TCP . Consulte a página 6.)

Eu teria preferido usar o OpenVPN no UDP, por todos os motivos usuais, mas achei difícil lidar com o UDPspeeder quando você tem latência superior a 100ms e velocidades> 10 Mbit / s.

O kcptun, no entanto, funcionou muito bem com pouquíssimos ajustes e, na verdade, aumentou realmente a taxa de transferência de nossos servidores. =)

Em uma nota extensa, aqui você pode encontrar explicações mais detalhadas sobre como ajustar algumas partes do desempenho do OpenVPN.

Vinícius M
fonte
0

Para mim, eu tinha um servidor VPS com configuração de servidor openvpn no Japão e minha conexão de cliente estava usando um DDWRT no modo de cliente OpenVPN em Nova York. Eu estava recebendo apenas 1-2mbps em uma conexão de 100mbit. O melhor que pude otimizá-lo foi de 5 Mbps, o suficiente para o que eu precisava, o mais otimizado possível.

Minhas configurações do servidor 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

Minhas configurações do cliente DDWRT OpenVPN também são vistas na minha captura de tela:

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

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Patoshi パ ト シ
fonte