Acessando o servidor ssh através de uma conexão muito congestionada

Este artigo é o resultado da minha visita a uma oficina mecânica. Enquanto esperava o carro, conectei meu laptop à rede wi-fi para convidados e li as notícias. Para minha surpresa, descobri que não conseguia visitar alguns sites. Sabendo do sshuttle (e sendo um grande fã desse projeto), tentei estabelecer uma sessão do sshuttle com meu servidor, mas não funcionou. A porta 22 estava totalmente bloqueada. Ao mesmo tempo, o nginx na porta 443 respondeu normalmente. Na próxima visita ao serviço do carro, instalei o multiplexador sslh no servidor .O servidor está executando o gentoo e adicionei a seguinte linha ao arquivo /etc/conf.d/sslh:



DAEMON_OPTS="-p 0.0.0.0:443 --ssl 127.0.0.1:8443 --ssh 127.0.0.1:22 --user nobody"
      
      





Dependendo do tipo de conexão, as conexões para a porta 443 são encaminhadas para a porta local:



  • 8433 no caso de https (nginx está sendo executado nesta porta)
  • 22 no caso de ssh


Mas quando tentei estabelecer uma conexão ssh com o servidor, falhei novamente. Aparentemente, a filtragem foi realizada não apenas pelas portas, mas também foi usada uma investigação profunda de pacotes. Isso torna a tarefa mais difícil. O tráfego Ssh deve ser agrupado em https. Felizmente, isso não é difícil graças ao projeto websocat . Na página do projeto, você pode encontrar muitos binários pré-construídos. Se por algum motivo você deseja compilar o binário a partir do código-fonte, isso também não é muito difícil. Eu faço isso com o empacotador do hashicorp com a seguinte configuração:



{
  "min_packer_version": "1.6.5",
  "builders": [
    {
      "type": "docker",
      "image": "ubuntu:20.04",
      "privileged": true,
      "discard": true,
      "volumes": {
        "{{pwd}}": "/output"
      }
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "skip_clean": true,
      "environment_vars": [
        "DEBIAN_FRONTEND=noninteractive"
      ],
      "inline": [
        "apt-get update && apt-get install -y git curl gcc libssl-dev pkg-config gcc-arm-linux-gnueabihf",
        "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs >/tmp/rustup.sh && chmod +x /tmp/rustup.sh && /tmp/rustup.sh -y",
        "git clone https://github.com/vi/websocat.git && cd websocat/",
        ". $HOME/.cargo/env && cargo build --release --features=ssl",
        "printf '[target.armv7-unknown-linux-gnueabihf]\nlinker = \"arm-linux-gnueabihf-gcc\"\n' >$HOME/.cargo/config",
        "rustup target add armv7-unknown-linux-gnueabihf",
        "cargo build --target=armv7-unknown-linux-gnueabihf --release",
        "strip target/release/websocat",
        "tar czf /output/websocat.tgz target/armv7-unknown-linux-gnueabihf/release/websocat target/release/websocat",
        "chown --reference=/output /output/websocat.tgz"
      ]
    }
  ]
}

      
      





O lado do cliente está no ubuntu 20.04, o servidor roda em nvidia tegra jetson tk1, então para ele estou fazendo uma montagem cruzada para a plataforma armv7. Observe que a construção do servidor é feita sem suporte a ssl, já que a terminação SSL é feita pelo nginx, que lida com as conexões de entrada. A configuração do nginx é semelhante a esta:



http {
    server {
        listen 0.0.0.0:8443 ssl;
        server_name your.host.com;
        ssl_certificate /etc/letsencrypt/live/your.host.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your.host.com/privkey.pem;
        location /wstunnel/ {
            proxy_pass http://127.0.0.1:8022;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        }
    }
}

      
      





Eu executo o Websocat da coroa do meu usuário:



* * * * * netstat -lnt|grep -q :8022 || $HOME/bin/websocat -E --binary ws-l:127.0.0.1:8022 tcp:127.0.0.1:22|logger -t websocat &
      
      





Agora você pode se conectar ao seu servidor desta forma:



ssh -o ProxyCommand='websocat --binary wss://your.host.com/wstunnel/' your.host.com
      
      





Quanto o empacotamento em https reduz a largura de banda? Para verificar isso, usei o seguinte comando:



ssh -o ProxyCommand='websocat --binary wss://your.host.com/wstunnel/' your.host.com 'dd if=/dev/zero count=32768 bs=8192' >/dev/null
      
      





Em meus experimentos, obtive uma redução de 2x na largura de banda. Ao usar o protocolo ws: //, ou seja, http, a largura de banda da conexão é idêntica ao ssh não empacotado.



Veja como você pode configurar uma sessão sshuttle:



sshuttle -e 'ssh -o ProxyCommand="websocat --binary wss://your.host.com/wstunnel/"' -r your.host.com 0/0 -x $(dig +short your.host.com)/32
      
      





Na próxima visita ao serviço de automóveis, certifiquei-me de que tudo funcionava como deveria. Como um bom bônus, o número de tentativas de login no servidor via ssh dos endereços à esquerda caiu drasticamente.



All Articles