3 pontos por GN⁺ 2023-12-25 | 1 comentários | Compartilhar no WhatsApp
  • Mesmo que a porta de SSH esteja bloqueada em uma rede restritiva, é possível criar um caminho de acesso remoto usando a porta HTTPS 443 e o método CONNECT
  • No servidor, o apache2 abre o CONNECT com mod_proxy_connect, mas limita o escopo do proxy permitindo apenas o destino ssh-server:22
  • No cliente, conecta-se o ProxyCommand do OpenSSH com o socat, e no caso de HTTPS o script envia diretamente os cabeçalhos CONNECT
  • Alguns firewalls ou o httpd podem fechar conexões ociosas, então ServerAliveInterval 30 ajuda a manter a sessão
  • Esse método encapsula o SSH dentro de TLS, facilitando escapar de bloqueios, mas ainda traz o custo de criptografia dupla e da configuração no cliente

Criando um caminho de acesso SSH em uma rede restrita

  • Em um ambiente de Wi‑Fi hospitalar, a maioria dos tipos de conexão era bloqueada, e em geral apenas HTTP na TCP 80 e HTTPS na TCP 443 eram permitidos
  • O DNS na UDP 53 e o DoT na TCP 853 pareciam funcionar para provedores de DNS conhecidos
  • SSH na TCP 22 e a maior parte das portas personalizadas eram totalmente bloqueados
  • Havia uma conexão alternativa GSM que permitia reconfigurar o servidor remoto, então foi possível testar vários métodos de contorno

Compartilhar uma porta e encapsular protocolos

  • Existe uma forma de receber SSH e HTTPS na mesma porta e separar os fluxos de forma transparente
    • O projeto sslh estima o protocolo por heurística e redireciona para o backend real, como SSH, HTTPS ou outro protocolo compatível
    • A vantagem é que o cliente ssh não precisa de configuração especial, bastando indicar uma porta não padrão
    • A desvantagem é a necessidade de configurar um serviço extra, o fato de que o HTTPS também precisa passar pelo sslh, e que o endereço de origem da conexão pode ficar oculto no backend, dificultando o logging
  • Outra opção é encapsular completamente um protocolo dentro de outro
    • O ProxyCommand do OpenSSH permite que o usuário defina qual meio de transporte o protocolo ssh vai usar
    • Como o SSH é envolvido em outro fluxo sem heurísticas, pode ser mais difícil para softwares de DPI bloquearem a conexão
    • O próprio HTTPS não é redirecionado nem afetado
    • Em compensação, a criptografia dupla pode reduzir o desempenho, e é necessário configurar o cliente

Configuração de SSH sobre HTTP

  • Primeiro foi testada uma forma de fazer o SSH passar por HTTP
  • No lado do servidor, a configuração do apache2 carrega mod_proxy_connect e permite CONNECT para a porta 22 com AllowCONNECT 22
  • <Proxy *> nega tudo por padrão, e apenas <Proxy ssh-server> é permitido, restringindo o destino a ssh-server:22
  • No lado do cliente, o .ssh/config usa em ProxyCommand o PROXY:http-server:%h:%p,proxyport=80 do socat
  • Com essa configuração, ao executar $ ssh ssh-via-http, é possível acessar o SSH pela porta 80
  • ServerAliveInterval 30 envia sondas periódicas para evitar situações em que conexões HTTP ociosas sejam fechadas silenciosamente no caminho
  • O httpd padrão usa TimeOut 60, que fecha o túnel quando 60 segundos se passam sem entrada ou saída

Configuração de SSH sobre HTTPS

  • O socat aparentemente não oferece suporte a proxy HTTPS via método CONNECT, apenas a HTTP
  • Em vez disso, usa-se o recurso de encapsulamento TLS do socat, enquanto a solicitação baseada em CONNECT é implementada diretamente em um script
  • O ~/.ssh/https-tunnel.bash funciona com o seguinte fluxo
    • Primeiro imprime os cabeçalhos CONNECT ssh-server:22 HTTP/1.1 e Host: ssh-server
    • Depois encaminha a entrada padrão sem alterações
    • Todo o fluxo é enviado para socat - "SSL:$3:$4", criando uma conexão TLS
  • No .ssh/config, define-se ProxyCommand ~/.ssh/https-tunnel.bash para Host ssh-via-https
  • Ao executar $ ssh ssh-via-https, a conexão com ssh-server passa pelo túnel HTTPS como esperado

Pontos de atenção na operação

  • Em ambientes onde HTTPS é amplamente permitido, dá para transmitir dados passando por equipamentos intermediários extremamente restritivos
  • O método CONNECT pode parecer um vestígio antigo, mas é útil para encapsular um fluxo arbitrário de payload TCP dentro de um fluxo hospedado em TLS
  • ServerAliveInterval ajuda a manter a conexão OpenSSH quando a camada de transporte subjacente não lida bem com conexões ociosas
  • Uma variação da configuração com nginx está em CONNECT passthrough on nginx

1 comentários

 
GN⁺ 2023-12-25
Opiniões do Hacker News
  • O trecho do texto que diz que “como HTTPS está em todo lugar, até equipamentos intermediários muito restritivos conseguem deixar os dados passarem” é exatamente o motivo pelo qual quase todos os protocolos proprietários de VPN, as chamadas “SSL VPNs”, implementam um modo que abre um túnel via HTTPS
    Mesmo que não seja o comportamento padrão, ele é mantido ao menos como caminho alternativo, com o objetivo de ter um modo que funcione em praticamente qualquer conexão da internet no mundo
    Sou um dos principais desenvolvedores do https://gitlab.com/openconnect/openconnect, que implementa vários protocolos de VPN baseados em TLS, e também criei o https://github.com/dlenski/what-vpn, que detecta e identifica mais tipos de servidores VPN baseados em TLS

    • É uma pena que tentativas de restringir grosseiramente a utilidade de uma conexão tornem difícil usar as portas conforme sua finalidade original
  • Antigamente, o provedor de internet holandês XS4ALL oferecia exatamente esse recurso
    Eles liberavam acesso SSH pela porta 80, e isso me ajudou várias vezes quando eu estava viajando e o WiFi de hotéis bloqueava tudo exceto a porta 80

  • Muitas vezes há uma terceira opção: colocar SSH nas portas 80 ou 443 de outro host e, a partir dele, usar ProxyJump até o destino
    Ou então abrir SOCKS para esse host e obter uma conexão à internet de modo geral menos filtrada
    Eu uso SOCKS e também encaminho DNS baseado em TLS por port forwarding da conexão SSH
    Alguns anos atrás, quando configurei um proxy SOCKS pela primeira vez e usei bastante WiFi, não encontrei nenhum lugar que fosse além de verificar a porta, mas esses equipamentos existem e talvez sejam mais comuns hoje

    • No primeiro ano do ensino médio, eu tinha acabado de começar com hospedagem própria, e a escola bloqueava sites, mas não fazia nenhum bloqueio de portas
      Então eu simplesmente acessava meu servidor via SSH e usava normalmente
      Mais tarde, enquanto criava um arquivo de imagens .iso do Windows, baixei-as para o notebook e as enviei para o servidor com scp; usar dezenas de GB somando upload e download em uma porta que não era 80/443 aparentemente foi suficiente para disparar uma inspeção de tráfego, e por volta do almoço o pessoal de TI bloqueou a porta 22
      Como eles não bloquearam outras portas, movi o SSH para a 443 no encaminhamento de portas e continuei usando
      Depois disso, o TI da escola percebeu que eu estava usando SSH na 443 e adicionou uma análise básica de tráfego para bloquear SSH em 80/443, mas todas as outras portas continuavam abertas
      No fim, bloquearam meu servidor por IP, mas todos os outros IPs continuavam liberados
      Daria para contornar usando ProxyJump por um VPS, mas, como era um programa de ensino médio com entrada antecipada na faculdade, quase não fui mais à escola depois do segundo ano, então não valia muito o esforço
      Na próxima vez que eu for, pretendo tentar só para provar que é possível; se bloquearem SSH em todas as portas, basta colocar SSH sobre HTTPS em um VPS
      Depois de me formar, pretendo voltar a investigar até onde dá para ir no WiFi de visitantes
  • É uma divulgação um pouco descarada, mas na Adaptive [1] estamos construindo infraestrutura de segurança de dados
    Em um dos produtos, encaminhamos SSH e vários outros protocolos sobre HTTP/3 para permitir que usuários se conectem a bancos de dados, servidores e outros recursos por uma única porta de saída
    É parecido com algo no estilo Ngrok, mas pode ser auto-hospedado e permite acesso sem senha, ou com credenciais temporárias e proteção maker-checker
    [1] https://adaptive.live/

  • Na prática, só fazer o openssh escutar na porta 443 já era suficiente para contornar a maioria dos firewalls

  • Legal. Estranhamente, eu nunca tinha pensado no método CONNECT como uma espécie de proxy reverso, em vez de um proxy direto
    No meu caso, porém, só CONNECT não bastava, então usei SSH sobre WebSocket para atravessar o proxy corporativo
    Esse proxy inspecionava conexões HTTPS com uma CA personalizada
    Modifiquei o socat para expor meu servidor SSH via WebSocket através do Apache e, no lado do cliente, usei isso com o ProxyCommand do OpenSSH
    Sempre fico pensando que deveria publicar esse patch, mas também há outras opções, como websocat

    • Por isso parece que muitos proxies ou firewalls corporativos bloqueiam WebSocket por padrão
    • Soa como se você tivesse recriado sem querer o huproxy
  • Há quase 20 anos, usei uma ferramenta chamada corkscrew[0], que fazia exatamente isso, para abrir um buraco no firewall da empresa
    A implementação independente e o texto são bem limpos
    0: https://github.com/bryanpkc/corkscrew

    • Pelo que entendo, o corkscrew só funciona em condições específicas: você precisa estar atrás de um proxy HTTP, e esse proxy HTTP precisa dar suporte ao método CONNECT
      Em um contrato curto que fiz há cerca de 20 anos, a primeira condição existia, mas a segunda não
      Felizmente, há uma ferramenta que também funciona nesses casos, embora, é claro, exija configuração no lado do servidor
      https://github.com/larsbrinkhoff/httptunnel
  • No geral, tunelamento via HTTP/2 acabou se mostrando uma boa escolha
    Existe o gRPC[1], um protocolo de chamada de procedimento remoto construído sobre HTTP/2
    Isso porque o HTTP/2 é forte em multiplexação, usando uma única conexão TCP para enviar e receber várias estruturas de dados simultaneamente
    Porém, como o próprio QUIC oferece multiplexação, talvez não haja motivo para usar HTTP/3
    Daqui para a frente, como os fabricantes de equipamentos intermediários não conseguem parar de discriminar tráfego, parece provável que a maior parte da comunicação passe por HTTP/2 criptografado e QUIC
    Para mitigar sondagem ativa[2], talvez seja necessário servir conteúdo HTTP/2·HTTP/3 aleatório, possivelmente gerado por IA
    [1] <https://grpc.io>
    [2] <https://blog.torproject.org/learning-more-about-gfws-active-...>

    • Não entendo muito bem por que colocar mais um protocolo de chamada de procedimento remoto em cima de HTTP
      O próprio HTTP já é um protocolo de requisição/resposta e, basicamente, pode ser usado para chamadas de procedimento remoto
      Não vejo grande diferença entre HTTP 1, 2 ou 3
      A própria evolução desse protocolo também me parece um tanto suspeita, e ele foi projetado para aproveitar coisas que não são necessárias em um ambiente de chamadas de procedimento remoto
      Em essência, ele foi projetado mais para a internet pública do que para serviços locais
    • No caso do SSH, há apenas uma única conexão e, na prática, o próprio SSH implementa sua própria multiplexação, então não vejo muito a vantagem do HTTP/2
    • HTTP/2 ainda é TCP, então sofre com bloqueio head-of-line do TCP
      HTTP/3 funciona sobre QUIC
  • Eu, pelo contrário, prefiro HTTP sobre SSH
    Meio brincando, mas eu gostaria que os navegadores tivessem gerenciamento de identidade equivalente ao do SSH embutido
    Fiquei animado quando li pela primeira vez sobre o hobo, uma proposta de autenticação HTTP por chave pública, mas descobri que não havia implementação de servidor nem implementação de cliente para navegador
    Existe uma implementação em JavaScript, mas não era o formato que eu queria

    • ssh -D “*:8080” host
      Esse comando sobe um proxy SOCKS na porta 8080
      Uso isso o tempo todo no Firefox, e funciona como uma espécie de VPN raiz
      Também é prático para usos suspeitos, mas eu também uso para acessar o dashboard rmq em uma rede privada da AWS
    • E quanto a certificados de cliente HTTPS?
      https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
      Não conheço em detalhes suficientes para saber se atende aos requisitos, mas já usei para autenticação de servidor na faculdade
    • Você não está falando de passkeys?
    • Seria bom se fosse possível usar ssh://google.com no navegador
    • Se você perdeu na semana passada, houve um texto em uma direção parecida: SSH3, SSHv2 usando HTTP/3 e QUIC
      https://news.ycombinator.com/item?id=38664729
  • Por que o sslh não recebe mais amor?
    Ele detecta HTTP, TLS/SSL (incluindo SNI e ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5, e também consegue reconhecer outros protocolos que possam ser inspecionados por regex
    O uso típico é oferecer vários serviços juntos na porta 443
    Por exemplo, você pode se conectar por SSH de dentro do firewall da empresa e, ao mesmo tempo, continuar oferecendo HTTPS na mesma porta
    https://www.rutschle.net/tech/sslh/README.html

    • A primeira metade do texto era sobre escolher entre sslh e encapsulamento completo
      O motivo para escolher encapsulamento completo parece ser: um serviço a menos para configurar, o servidor HTTP lida com a conexão, então o endereço remoto nos logs fica correto, e talvez, pelo espírito hacker, a preferência por uma solução nova em vez de uma existente