Gostei bastante de proxies reversos HTTP em nosso ambiente de desenvolvimento e achei o proxy reverso de host virtual baseado em DNS bastante útil. Ter apenas uma porta (e a padrão) aberta no firewall facilita muito o gerenciamento.
Gostaria de encontrar algo semelhante para fazer conexões SSH, mas não tive muita sorte. Prefiro não usar simplesmente o encapsulamento SSH, pois isso exige a abertura de intervalos de portas diferentes do padrão. Existe algo lá fora que possa fazer isso?
O HAProxy poderia fazer isso?
ssh
reverse-proxy
ahanson
fonte
fonte
Respostas:
Não acredito que o SSH baseado em nome seja algo possível, considerando o funcionamento do protocolo.
Aqui estão algumas alternativas.
Você poderia fazer é configurar o host que responde pela porta 22 para atuar como um gateway. Em seguida, você pode configurar o servidor ssh para encaminhar solicitações para o interior com base na chave. Exemplo de gateway SSH com chaves
Você pode ajustar seu cliente para usar esse host como proxy. Ou seja, seria ssh para o host do gateway e, em seguida, utilizaria esse host para estabelecer uma conexão com o host interno. Proxy SSH com configuração do cliente .
Você também pode configurar um proxy HTTP simples na borda. Em seguida, use isso para permitir conexões de entrada. SSH via proxy HTTP .
Obviamente, com todas as opções acima, certifique-se de configurar e bloquear corretamente o gateway é muito importante.
fonte
Eu tenho procurado uma solução para este problema dentro e fora nos últimos 16 meses. Mas, cada vez que olho, parece impossível fazer isso com o protocolo SSH, conforme especificado nas RFCs relevantes e implementado pelas principais implementações.
No entanto, se você estiver disposto a usar um cliente SSH levemente modificado e estiver disposto a utilizar protocolos de maneira que não foi exatamente planejada quando eles foram projetados, é possível obter isso. Mais sobre isso abaixo.
Por que não é possível
O cliente não envia o nome do host como parte do protocolo SSH.
Ele pode enviar o nome do host como parte de uma pesquisa de DNS, mas isso pode ser armazenado em cache, e o caminho do cliente através dos resolvedores para servidores autoritativos pode não cruzar o proxy e, mesmo que isso ocorra, não existe uma maneira robusta de associar pesquisas de DNS específicas a clientes SSH específicos.
Também não há nada que você possa fazer com o próprio protocolo SSH. Você precisa escolher um servidor sem ter visto o banner da versão SSH do cliente. Você precisa enviar um banner para o cliente, antes que ele envie qualquer coisa para o proxy. Os banners dos servidores podem ser diferentes e você não tem chance de adivinhar qual é o correto para usar.
Mesmo que este banner seja enviado sem criptografia, você não pode modificá-lo. Cada parte desse banner será verificada durante a configuração da conexão; portanto, você estará causando uma falha na conexão um pouco abaixo da linha.
A conclusão para mim é bastante clara: é preciso mudar algo no lado do cliente para fazer essa conectividade funcionar.
A maioria das soluções alternativas está encapsulando o tráfego SSH dentro de um protocolo diferente. Pode-se também imaginar uma adição ao próprio protocolo SSH, no qual o banner da versão enviado pelo cliente inclui o nome do host. Isso pode permanecer compatível com os servidores existentes, já que parte do banner está atualmente especificada como um campo de identificação de formulário livre e, embora os clientes normalmente esperem o banner de versão do servidor antes de enviar o seu próprio, o protocolo permite que o cliente envie seu banner primeiro. Algumas versões recentes do cliente ssh (por exemplo, no Ubuntu 14.04) enviam o banner sem aguardar o banner do servidor.
Não conheço nenhum cliente que tenha tomado medidas para incluir o nome do host do servidor nesse banner. Enviei um patch para a lista de discussão do OpenSSH para adicionar esse recurso. Mas foi rejeitado com base no desejo de não revelar o nome do host a ninguém bisbilhotando no tráfego SSH. Como um nome de host secreto é fundamentalmente incompatível com a operação de um proxy baseado em nome, não espere ver uma extensão SNI oficial para o protocolo SSH tão cedo.
Uma solução real
A solução que melhor funcionou para mim foi usar o IPv6.
Com o IPv6, posso ter um endereço IP separado atribuído a cada servidor, para que o gateway possa usar o endereço IP de destino para descobrir para qual servidor enviar o pacote. Às vezes, os clientes SSH podem estar em execução nas redes em que a única maneira de obter um endereço IPv6 seria usando o Teredo. Sabe-se que o Teredo não é confiável, mas apenas quando o final do IPv6 nativo da conexão está usando uma retransmissão pública do Teredo. Pode-se simplesmente colocar um relé Teredo no gateway, onde você executaria o proxy. O Miredo pode ser instalado e configurado como um relé em menos de cinco minutos.
Uma solução alternativa
Você pode usar um host de salto / host de bastião. Essa abordagem é direcionada para casos em que você não deseja expor a porta SSH dos servidores individuais diretamente à Internet pública. Ele tem o benefício adicional de reduzir o número de endereços IP externos que você precisa para SSH, e é por isso que é utilizável nesse cenário. O fato de ser uma solução destinada a adicionar outra camada de proteção por motivos de segurança não impede que você a use quando não precisar da segurança adicionada.
Um truque sujo para fazê-lo funcionar se a solução real (IPv6) estiver fora do seu alcance
O truque que estou prestes a descrever deve ser usado apenas como o último recurso. Antes mesmo de pensar em usar esse hack, recomendo fortemente obter um endereço IPv6 para cada um dos servidores que você deseja alcançar externamente através do SSH. Use o IPv6 como método principal para acessar seus servidores SSH e use esse hack apenas quando precisar executar um cliente SSH a partir de uma rede somente IPv4, onde você não tem nenhuma influência sobre a implantação do IPv6.
A ideia é que o tráfego entre o cliente e o servidor precise ser um tráfego SSH perfeitamente válido. Mas o proxy só precisa entender o suficiente sobre o fluxo de pacotes para identificar o nome do host. Como o SSH não define uma maneira de enviar um nome de host, você pode considerar outros protocolos que oferecem essa possibilidade.
HTTP e HTTPS permitem que o cliente envie um nome de host antes que o servidor envie quaisquer dados. A questão agora é se é possível construir um fluxo de bytes que seja simultaneamente válido como tráfego SSH e como HTTP e HTTPS. HTTPs é praticamente um não iniciador, mas HTTP é possível (para definições suficientemente liberais de HTTP).
Isso parece SSH ou HTTP para você? É SSH e completamente compatível com RFC (exceto que alguns dos caracteres binários foram distorcidos um pouco pela renderização do SF).
A cadeia de caracteres da versão SSH inclui um campo de comentário, que acima tem o valor
/ HTTP/1.1
. Após a nova linha, o SSH possui alguns dados binários do pacote. O primeiro pacote é umaMSG_SSH_IGNORE
mensagem enviada pelo cliente e ignorada pelo servidor. A carga útil a ser ignorada é:Se um proxy HTTP for suficientemente liberal no que aceita, a mesma sequência de bytes será interpretada como um método HTTP chamado
SSH-2.0-OpenSSH_6.6.1
e os dados binários no início da mensagem de ignorar serão interpretados como um nome de cabeçalho HTTP.O proxy não entenderia nem o método HTTP nem o primeiro cabeçalho. Mas ele pode entender o
Host
cabeçalho, que é tudo o que precisa para encontrar o back-end.Para que isso funcione, o proxy teria que ser projetado com o princípio de que ele precisa entender apenas HTTP suficiente para encontrar o back-end e, uma vez encontrado o back-end, o proxy simplesmente passará o fluxo de bytes brutos e deixará a real terminação. da conexão HTTP a ser feita pelo back-end.
Pode parecer um pouco exagerado fazer tantas suposições sobre o proxy HTTP. Mas se você estava disposto a instalar um novo software desenvolvido com a intenção de oferecer suporte ao SSH, os requisitos para o proxy HTTP não parecem muito ruins.
No meu próprio caso, achei que esse método funcionava em um proxy já instalado, sem alterações no código, na configuração ou de outra forma. E isso foi para um proxy escrito com apenas HTTP e sem SSH em mente.
Prova de conceito cliente e proxy . (Isenção de responsabilidade de que o proxy é um serviço operado por mim. Sinta-se à vontade para substituir o link depois que qualquer outro proxy for confirmado para suportar esse uso.)
Advertências deste hack
fonte
the gateway can use the destination IP address to find out which server to send the packet to
, na solução IPv6?-J
, para que você possa usar: ssh -J user1 @ front user2 @ targetNão acredito que isso seja possível, pelo menos da maneira que você descreveu, embora eu adorasse provar que estou errado. Não parece que o cliente envie o nome do host ao qual deseja se conectar (pelo menos de forma clara). A primeira etapa da conexão SSH parece ser configurar a criptografia.
Além disso, você teria problemas com a verificação da chave do host. Os clientes SSH verificarão as chaves com base em um endereço IP e também em um nome de host. Você teria vários nomes de host com chaves diferentes, mas o mesmo IP ao qual está se conectando.
Uma solução possível seria ter um host 'bastião', no qual os clientes possam acessar a máquina, obter um shell normal (ou restrito, se desejado) e, em seguida, transferir para hosts internos a partir daí.
fonte
Há um garoto novo no quarteirão. O SSH piper roteará sua conexão com base em nomes de usuário predefinidos, que devem ser mapeados para os hosts internos. Esta é a melhor solução no contexto do proxy reverso.
Piper SSh no github
Meus primeiros testes confirmaram, SSH e SFTP funcionam.
fonte
debug1: Sending subsystem: sftp
. Acontece que a frente da camisa não suporta subsistemas. Você suporta bainha no SSh piper?Gostaria de saber se Honeytrap (o honeypot de baixa interação) que tem um modo proxy não pôde ser modificado para conseguir isso.
Este honeypot pode encaminhar qualquer protocolo para outro computador. Adicionar um sistema vhost baseado em nome (conforme implementado pelo Apache) pode torná-lo um proxy reverso perfeito para qualquer protocolo, não?
Não tenho as habilidades necessárias para conseguir isso, mas talvez possa ser um ótimo projeto.
fonte
À medida que aumenta o número de portas / hosts que você deseja acessar por trás de um firewall, aumenta a conveniência das VPNs.
Eu não gosto de VPNs, no entanto.
fonte
por causa de como o ssh funciona, acho que não é possível. Semelhante ao https, você teria que ter IPs (externos) diferentes para hosts diferentes, porque o gateway não sabe onde você deseja se conectar, porque tudo no ssh está criptografado
fonte