Enorme penalidade de desempenho no link do gbit com o encaminhamento de ip / mascarada através de túnel VPN claro

1

Eu tenho um problema com o encaminhamento de IP entre meu computador doméstico e um servidor remoto (de online.net). Minha conexão doméstica é um FTTH de 1 Gbit / s e o servidor remoto tem uma largura de banda de 2,5 Gbit / s.

O contexto

Estou executando um túnel OpenVPN clear entre meu computador doméstico e um servidor remoto em online.net. No momento, eu não uso nenhuma criptografia, por isso não enfrento nenhuma penalidade de desempenho devido à criptografia.

Máquina servidor: Intel Atom C2750 / 2GB de RAM / SSD | Máquina cliente: VMware hospedado servidor Ubuntu 16,04 64 bits com 8 GB de RAM / SSD / Intel i5 (Mac mini 2013 para trás)

Comando

server openvpn:

 # openvpn --dev tun --proto tcp-server --port 11000 --ifconfig 10.200.0.1 10.200.0.2 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 0 --rcvbuf 0
Comando

client openvpn:

 # openvpn --dev tun --proto tcp-client --port 11000 --ifconfig 10.200.0.2 10.200.0.1 --cipher none --auth none --remote dedibox --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 0 --rcvbuf 0

Eu configurei um servidor vsftpd no servidor remoto. Se eu baixar algo do servidor FTP remoto através do túnel OpenVPN, estou a toda velocidade.

lftp [email protected]:~> pget 1GB.dat
1073741824 bytes transferred in 11 seconds (95.68 MiB/s)

O problema

O problema é quando eu quero acessar a internet do cliente através do túnel OpenVPN.

Vamos adicionar uma rota na máquina cliente para um site específico do qual testo minha velocidade de download usando wget / curl.

ip route add 62.34.91.0/24 via 10.200.0.1

Em seguida, permita o encaminhamento de ipv4 no servidor remoto:

> # sysctl -w net.ipv4.ip_forward=1

Por fim, permita conexões VPN de um lado para outro na Web:

iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o eth0 -j MASQUERADE

E quando eu testo minha velocidade de download do cliente:

wget -O /dev/null http://3-ipv4.testdebit.info/fichiers/1000Mo.dat
...
2016-05-17 20:24:45 (17.7 MB/s) - ‘/dev/null’ saved [1000000000/1000000000]

Então, isso é quase 5 vezes menor do que quando eu faço o download de um arquivo do servidor remoto usando o túnel VPN.

Qual poderia ser o motivo?

  1. O link do servidor remoto para o site 3-ipv4.testdebit.info está lento? Não, não, usando o mesmo wget do servidor remoto diretamente e recebo 225 MB / s
  2. O servidor remoto não pode receber e enviar a mesma quantidade de dados ao mesmo tempo a 1 Gbit / s? Sim pode. Eu fiz uma transferência de arquivos FTP do servidor e baixei no mesmo no servidor remoto usando wget, eu estava em 100+ MB / s em ambas as transferências.
  3. sobrecarga de CPU? De acordo com o top, estou usando 15% da capacidade da CPU, então não acho que seja devido à CPU.
  4. iptables mascarando todos os pacotes? Eu acho que é, mas não tenho certeza. Alguém pode confirmar / negar?

Qualquer ajuda é muito apreciada, me dá dores de cabeça desde dois dias! Se você precisar de algum log ou despejo TCP, posso fornecê-lo a você.

Editar 2016/05/22 às 14:09 GMT

Eu joguei pacotes TCP usando o tcpdump no servidor . Todos os despejos estão disponíveis aqui: link

Aqui estão os detalhes sobre cada arquivo:

  • dump-server-direct-eth0.pcap Descarrega a eth0 de um download http direto do servidor. Nenhuma VPN nem o encaminhamento de ip usado aqui. Comando usado (eu filtro meu endereço IP usado para conexão ssh): tcpdump -i eth0 '((not net XXX.XXX.XXX.XXX) and port 80)' -C 100 -vvv -w dump-server-direct-eth0.pcap

  • dump-server-forward-http-[tcp|udp]-eth0.pcap Descarrega a eth0 quando o cliente faz o download de um arquivo http através do túnel UDP / TCP OpenVPN, usando o encaminhamento de IP. Comando usado (eu filtro meu endereço IP usado para conexão ssh): tcpdump -i eth0 '((not net XXX.XXX.XXX.XXX) and (port 80 or port 11000))' -C 100 -vvv -w dump-server-forward-http-[tcp|udp]-eth0.pcap

  • dump-server-forward-http-[tcp|udp]-tun0.pcap O mesmo que acima, mas desta vez capturando a partir da interface tun0. Comando utilizado:
    tcpdump -i tun0 -C 100 -vvv -w dump-server-forward-http-[tcp|udp]-tun0.pcap

  • dump-server-http-through-tcp-tunnel-eth0.pcap Descarrega a eth0 quando o cliente baixa um arquivo ftp através do túnel UDP / TCP OpenVPN, sem encaminhamento de IP. O servidor http é hospedado no próprio servidor OpenVPN e eu uso o endereço do servidor OpenVPN para conectar ao servidor (10.200.0.1), portanto não há nenhum encaminhamento de IP. Comando usado (eu filtro com o endereço IP do cliente): tcpdump -i eth0 'net YYY.YYY.YYY.YYY' -C 100 -vvv -w dump-server-ftp-through-tcp-tunnel eth0.pcap

  • dump-server-http-through-tcp-tunnel-tun0.pcap O mesmo que acima, mas desta vez capturando a partir da interface tun0. Comando utilizado:
    tcpdump -i tun0 -C 100 -vvv -w dump-server-http-through-tcp-tunnel-tun0.pcap

Editar 2016/05/19 às 10:31 GMT

Os comentários e as respostas que recebo falam sobre o fato de eu usar o protocolo TCP com o OpenVPN ao invés do udp. Como eu disse no meu post acima, não há problemas de desempenho de velocidade entre o meu servidor e meu computador doméstico através do túnel TCP VPN:

lftp [email protected]:~> pget 1GB.dat
1073741824 bytes transferred in 11 seconds (95.68 MiB/s)

Mas, para agradar a todos e interromper as observações sobre o tcp versus o udp, aqui está um teste usando o udp:

servidor :

# openvpn --dev tun --proto udp --port 11000 --ifconfig 10.200.0.1 10.200.0.2 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 393216 --rcvbuf 393216

client :

# openvpn --dev tun --proto udp --port 11000 --ifconfig 10.200.0.2 10.200.0.1 --cipher none --auth none --fragment 0 --mssfix 0 --tun-mtu 48000 --sndbuf 393216 --rcvbuf 393216 --remote dedibox

teste iperf3 do servidor para o cliente usando o túnel udp vpn:

#  iperf3 -c 10.200.0.2  -i 1 -p 5201 -f m -b 1G -u

Connecting to host 10.200.0.2, port 5201
[  4] local 10.200.0.1 port 55287 connected to 10.200.0.2 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec   111 MBytes   935 Mbits/sec  14265
[  4]   1.00-2.00   sec   119 MBytes  1000 Mbits/sec  15258
[  4]   2.00-3.00   sec   119 MBytes  1000 Mbits/sec  15258
[  4]   3.00-4.00   sec   119 MBytes  1000 Mbits/sec  15260
[  4]   4.00-5.00   sec   119 MBytes  1000 Mbits/sec  15259
[  4]   5.00-6.00   sec   119 MBytes  1000 Mbits/sec  15258
[  4]   6.00-7.00   sec   119 MBytes  1000 Mbits/sec  15253
[  4]   7.00-8.00   sec   119 MBytes  1000 Mbits/sec  15266
[  4]   8.00-9.00   sec   119 MBytes  1000 Mbits/sec  15255
[  4]   9.00-10.00  sec   119 MBytes  1000 Mbits/sec  15262
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec  1.16 GBytes   993 Mbits/sec  0.763 ms  141473/150989 (94%)
[  4] Sent 150989 datagrams

iperf Done.

E finalmente, um teste de velocidade do cliente e um servidor de teste de velocidade hospedado no testdebit.info, através do meu túnel vpn:

# ip route add 62.34.91.3 via 10.200.0.1

# wget -O /dev/null http://3-ipv4.testdebit.info/fichiers/1000Mo.dat
/dev/null               100%[============================>] 953.67M  12.4MB/s    in 79s
2016-05-19 12:27:40 (12.1 MB/s) - ‘/dev/null’ saved [1000000000/1000000000]

Conclusão: não há diferença entre o UDP e o TCP!

Como eu disse, o problema é com iptables ou ipv4.ip_forwarding, mas não com o OpenVPN / TCP / UDP

    
por aixki 17.05.2016 / 20:40

1 resposta

1

Eu dei uma olhada rápida no seu último arquivo de captura. Podemos ver imediatamente que o RTT na sessão TCP de ponta a ponta está em torno de 50ms ou pior. Seu cliente está promovendo uma janela em torno de 3MB (não 300MB como eu digitei originalmente). Coloque-os juntos e você terá um máximo absoluto de 480Mbps, assumindo um hardware infinitamente rápido em cada extremidade da conexão TCP. Presumivelmente, nem o fim é infinitamente rápido.
Então, se eu fosse você, eu também:

aceite o desempenho que você recebe (dependendo dos requisitos reais)

ou:

represente o RTT em toda a sessão para obter precisão | Use o produto de atraso de largura de banda para entender exatamente qual largura de banda é máxima para um único fluxo TCP. investigar de onde vêm os componentes de atraso (por exemplo, instalando um toque no servidor de encapsulamento)

ATUALIZAÇÃO: O atraso é causado no servidor de encapsulamento. Os arquivos de captura não tornam isso óbvio, mas a latência de ponta a ponta é muito maior do que eu pensava inicialmente. Os arquivos de captura baseados em host ocultam o tempo que cada pacote passa no servidor. O ideal é que você faça uma captura no cliente e acho que isso mostrará RTTs muito mais altos.

dump-server-forward-http-tcp-eth0 frame 17854 é um caso em questão. Ele contém dados do host da Internet que é (supostamente) transmitido para o cliente em 17856. No entanto, 17856 não é reconhecido até 18614, alguns 222ms depois. Permitindo um RTT de 40 ms para o cliente, incluindo algum processamento, o servidor está adicionando pelo menos 180 ms à viagem de ida da recepção do host da Internet para colocá-lo no fio em direção ao cliente. Dado que o frame 17854 claramente não é um frame físico, mas foi remontado (possivelmente erroneamente), pode haver atrasos similares em relação ao host da Internet.

Se o RTT for de 222 ms e o RWIN for de 3 MB, o TCP só poderá fornecer 13,5 Mbps

Parece-me que há um offload de segmentação TCP ativado e que, por qualquer razão, o TCP está sendo processado no servidor de encapsulamento quando você realmente quer que ele seja encaminhado. Agora você precisa investigar por que isso pode acontecer.

UPDATE: Eu também notei que você diz que a CPU é de apenas 15%. Se isso se refere ao servidor de encapsulamento, você diz que é um C250 Atom, 8-core. Com uma CPU multi-thread qualquer carga de CPU sustentada em ou um pouco acima de 100% / number-of-cores (no seu caso 12,5%) pode ser um único thread principal saturando um núcleo.

    
por 23.05.2016 / 17:34