AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 434825
Accepted
ttsiodras
ttsiodras
Asked: 2018-04-02 04:03:06 +0800 CST2018-04-02 04:03:06 +0800 CST 2018-04-02 04:03:06 +0800 CST

A velocidade do SSH melhorou muito por meio do ProxyCommand - mas por quê?

  • 772

A versão TL;DR

Assista a este elenco ASCII ou a este vídeo - e depois pense em algum motivo para isso estar acontecendo. A descrição do texto a seguir fornece mais contexto.

Detalhes da configuração

  • A máquina 1 é um laptop Arch Linux, no qual sshé gerado, conectando-se a um SBC executando Armbian (um Orange PI Zero).
  • O próprio SBC está conectado via Ethernet a um roteador DSL e possui um IP de 192.168.1.150
  • O laptop está conectado ao roteador por WiFi - usando um dongle Raspberry PI WiFi oficial.
  • Há também outro laptop (Máquina 2) conectado via Ethernet ao roteador DSL.

Topologia

Fazendo benchmarking do link com iperf3

Quando comparado com iperf3o , o link entre o laptop e o SBC é menor que os 56 MBits/s teóricos - como esperado, já que se trata de uma conexão Wi-Fi dentro de um "2,4 GHz" muito "lotado" (prédio de apartamentos) .

Mais especificamente: após a execução iperf3 -sno SBC, os seguintes comandos são executados no laptop:

# iperf3 -c 192.168.1.150
Connecting to host 192.168.1.150, port 5201
[  5] local 192.168.1.89 port 57954 connected to 192.168.1.150 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  2.99 MBytes  25.1 Mbits/sec    0    112 KBytes       
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  28.0 MBytes  23.5 Mbits/sec    5             sender
[  5]   0.00-10.00  sec  27.8 MBytes  23.4 Mbits/sec                  receiver

iperf Done.

# iperf3 -c 192.168.1.150 -R
Connecting to host 192.168.1.150, port 5201
Reverse mode, remote host 192.168.1.150 is sending
[  5] local 192.168.1.89 port 57960 connected to 192.168.1.150 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  3.43 MBytes  28.7 Mbits/sec                  
...                
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  39.2 MBytes  32.9 Mbits/sec  375             sender
[  5]   0.00-10.00  sec  37.7 MBytes  31.6 Mbits/sec                  receiver

Então, basicamente, o upload para o SBC atinge cerca de 24 MBits/s e o download dele ( -R) atinge 32 MBits/s.

Benchmarking com SSH

Dado isso, vamos ver como o SSH se sai. Eu experimentei pela primeira vez os problemas que levaram a esta postagem ao usar rsynce borgbackup- ambos usando SSH como uma camada de transporte ... Então, vamos ver como o SSH funciona no mesmo link:

# cat /dev/urandom | \
    pv -ptebar | \
    ssh  [email protected] 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]

Bem, isso é uma velocidade abismal! Muito mais lento que a velocidade de link esperada... (Caso você não saiba pv -ptevar: ele exibe a taxa atual e média de dados passando por ele. Nesse caso, vemos que ler /dev/urandome enviar os dados por SSH para o SBC atinge, em média, 400 KB/s - ou seja, 3,2 MBits/s, um valor bem menor do que os 24 MBits/s esperados.)

Por que nosso link está operando a 13% de sua capacidade?

É talvez nossa /dev/urandomculpa?

# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]

Não, definitivamente não.

É talvez o próprio SBC? Talvez seja muito lento para processar? Vamos tentar executar o mesmo comando SSH (ou seja, enviar dados para o SBC), mas desta vez de outra máquina (Máquina 2) conectada pela Ethernet:

# cat /dev/urandom | \
    pv -ptebar | \
    ssh  [email protected] 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s] 

Não, isso funciona bem - o daemon SSH no SBC pode (facilmente) lidar com 11 MBytes/seg (ou seja, 100 MBits/seg) que seu link Ethernet fornece.

E a CPU do SBC é carregada ao fazer isso?

A CPU está lidando com isso facilmente

Não.

Então...

  • em termos de rede (conforme iperf3), devemos ser capazes de fazer 10x a velocidade
  • nossa CPU pode facilmente acomodar a carga
  • ... e não envolvemos nenhum outro tipo de E/S (por exemplo, drives).

O que diabos está acontecendo?

Netcat e ProxyCommand para o resgate

Vamos tentar netcatconexões antigas simples - elas rodam tão rápido quanto esperávamos?

No SBC:

# nc -l -p 9988 | pv -ptebar > /dev/null

No portátil:

# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s] 

Funciona! E roda na velocidade esperada - muito melhor, 10x melhor.

Então, o que acontece se eu executar o SSH usando um ProxyCommand para usar o nc?

# cat /dev/urandom | \
    pv -ptebar | \
    ssh -o "Proxycommand nc %h %p" [email protected] 'cat >/dev/null'
101MiB 0:00:30 [3.38MiB/s] [3.33MiB/s]

Funciona! velocidade 10x.

Agora estou um pouco confuso - ao usar um "naked" nccomo um Proxycommand, você não está basicamente fazendo exatamente a mesma coisa que o SSH faz? ou seja, criar um soquete, conectar-se à porta 22 do SBC e, em seguida, transferir o protocolo SSH sobre ele?

Por que existe essa enorme diferença na velocidade resultante?

PS Este não foi um exercício acadêmico - meu borgbackup é executado 10 vezes mais rápido por causa disso. Só não sei porque :-)

EDIT : Adicionado um "vídeo" do processo aqui . Contando os pacotes enviados da saída do ifconfig, fica claro que em ambos os testes estamos enviando 40MB de dados, transmitindo-os em aproximadamente 30K pacotes - só que bem mais lento quando não estamos usando ProxyCommand.

networking ssh
  • 1 1 respostas
  • 4781 Views

1 respostas

  • Voted
  1. Best Answer
    ttsiodras
    2018-04-02T13:09:13+08:002018-04-02T13:09:13+08:00

    Muito obrigado às pessoas que enviaram ideias nos comentários. Eu passei por todos eles:

    Gravando pacotes com tcpdump e comparando o conteúdo no WireShark

    # tcpdump -i wlan0 -w good.ssh & \
         cat signature | ssh -o "ProxyCommand nc %h %p" \
            [email protected] 'cat | md5sum' ; \
         killall tcpdump
    # tcpdump -i wlan0 -w bad.ssh & \
         cat signature | ssh [email protected] 'cat | md5sum' ; \
         killall tcpdump
    

    Não houve diferença de importância nos pacotes registrados.

    Verificando a modelagem de tráfego

    Não tinha ideia disso - mas depois de olhar a página de manual "tc", pude verificar que

    • tc filter shownão retorna nada
    • tc class shownão retorna nada
    • tc qdisc show

    ...retorna estes:

    qdisc noqueue 0: dev lo root refcnt 2
    qdisc noqueue 0: dev docker0 root refcnt 2
    qdisc fq_codel 0: dev wlan0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 32Mb ecn 
    

    ...que não parecem diferenciar entre "ssh" e "nc" - na verdade, nem tenho certeza se o modelagem de tráfego pode operar no nível do processo (eu esperaria que funcionasse em endereços/portas/diferenciados Campo de serviços no cabeçalho IP).

    Debian Chroot, para evitar potencial "inteligência" no cliente Arch Linux SSH

    Não, mesmos resultados.

    Finalmente - Nagle

    Fazendo um strace no sender...

    pv data | strace -T -ttt -f ssh 192.168.1.150 'cat | md5sum' 2>bad.log
    

    ... e observando o que exatamente acontece no soquete que transmite os dados, notei esta "configuração" antes do início da transmissão real:

    1522665534.007805 getsockopt(3, SOL_TCP, TCP_NODELAY, [0], [4]) = 0 <0.000025>
    1522665534.007899 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0 <0.000021>
    

    Isso configura o soquete SSH para desabilitar o algoritmo de Nagle. Você pode pesquisar no Google e ler tudo sobre isso - mas o que isso significa é que o SSH está dando prioridade à capacidade de resposta sobre a largura de banda - ele instrui o kernel a transmitir qualquer coisa escrita neste soquete imediatamente e não "atrasar" a espera de confirmações do controle remoto.

    O que isso significa, em termos simples, é que em sua configuração padrão, o SSH NÃO é uma boa maneira de transportar dados - não quando o link usado é lento (o que é o caso de muitos links WiFi). Se estamos enviando pacotes pelo ar que são "principalmente cabeçalhos", a largura de banda é desperdiçada!

    Para provar que este era realmente o culpado, usei LD_PRELOAD para "descartar" esta syscall específica:

    $ cat force_nagle.c
    
    #include <stdio.h>
    #include <dlfcn.h>
    #include <netinet/in.h>
    #include <netinet/tcp.h>
    #include <sys/socket.h>
    
    int (*osetsockopt) (int socket, int level, int option_name,
               const void *option_value, socklen_t option_len) = NULL;
    
    int setsockopt(int socket, int level, int option_name,
               const void *option_value, socklen_t option_len)
    {
        int ret;
        if (!osetsockopt) {
            osetsockopt = dlsym(RTLD_NEXT, "setsockopt");
        }
    
        if (option_name == TCP_NODELAY) {
            puts("No, Mr Nagle stays.");
            return 0;
        }
        ret = osetsockopt(socket, level, option_name, option_value, option_len);
        return ret;
    }
    
    $ gcc -fPIC -D_GNU_SOURCE -shared -o force_nagle.so force_nagle.c -ldl
    
    $ pv /dev/shm/data | LD_PRELOAD=./force_nagle.so ssh [email protected] 'cat >/dev/null'
    No, Mr Nagle stays.
    No, Mr Nagle stays.
     100MiB 0:00:29 [3.38MiB/s] [3.38MiB/s] [================================>] 100%   
    

    Lá - velocidade perfeita (bem, tão rápido quanto iperf3).

    moral da história

    Nunca desista :-)

    E se você usar ferramentas como rsyncou borgbackupque transportam seus dados por SSH, e seu link for lento, tente impedir que o SSH desative o Nagle (como mostrado acima) - ou use ProxyCommandpara alternar o SSH para conectar via nc. Isso pode ser automatizado em seu $HOME/.ssh/config:

    $ cat .ssh/config
    ...
    Host orangepi
        Hostname 192.168.1.150
        User root
        Port 22
        # Compression no
        # Cipher None
        ProxyCommand nc %h %p
    ...
    

    ...para que todos os usos futuros de "orangepi" como um host de destino em ssh/rsync/borgbackup sejam usados ​​doravante ncpara conectar (e, portanto, deixar Nagle em paz).

    • 16

relate perguntas

  • Execute o aplicativo X remotamente, execute a GUI no host remoto [fechado]

  • rsync porta 22 e 873 uso

  • Aborto repentino do SCP: tubo quebrado, código de autenticação de mensagem incorreto

  • Incapaz de identificar qual saída de endereço MAC do comando arp ou comando ip está correta

  • Roteador estranho funciona com centos 6 [fechado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve