Encaminhar conexões ssh ao contêiner do docker pelo nome do host

10

Eu entrei em uma situação muito específica e, embora haja outras maneiras de fazer isso, fiquei meio obcecado com isso e gostaria de descobrir uma maneira de fazer exatamente assim:

fundo

Digamos que eu tenha um servidor executando vários serviços escondidos em contêineres isolados. Como a maioria desses serviços é http, estou usando um proxy nginx para expor subdomínios específicos a cada serviço. Por exemplo, um servidor de nó está sendo executado em um contêiner de docker com sua porta 80vinculada ao 127.0.0.1:8000host. Vou criar um vhost no nginx que proxies todos os pedidos myapp.mydomain.compara http://127.0.0.1:8000. Dessa forma, o contêiner do docker não pode ser acessado de fora, exceto através myapp.mydomain.com.

Agora, quero iniciar um contêiner do gogs docker de forma que gogs.mydomain.comaponte para o contêiner do gogs. Então, inicio esse contêiner gogs com a porta 8000vinculada ao 127.0.0.1:8001host. E um site nginx proxy solicita gogs.mydomain.compara http://127.0.0.1:8001e funciona bem ...

No entanto, gogs sendo um contêiner git, eu também gostaria de acessar os repositórios como através, [email protected]:org/repomas isso não funciona com a configuração atual. Uma maneira de fazer esse trabalho seria vincular a porta 22do contêiner à porta 0.0.0.0:8022do host e, em seguida, o URL do git ssh pode ser algo como [email protected]:8022/repo.

(Isso não parece funcionar; quando eu for para uma origem com uri assim, o git exige a senha do usuário - gitem gogs.mydomain.comvez de gogs.mydomain.com:8022- mas isso é provavelmente algo que estou fazendo de errado e fora do escopo para essa pergunta, no entanto, Agradeço qualquer diagnóstico por isso também)

Problema

Minha principal preocupação é que eu quero que a porta ssh <gogs container>:22seja submetida a proxy, da mesma forma que proxy as portas http usando o nginx; ou seja, qualquer conexão ssh a gogs.mydomain.comser passada para a porta do contêiner 22. Agora não consigo vincular a porta ssh do contêiner à porta ssh do host, porque já existe um sshd em execução no host. Além disso, isso significaria que todas as conexões *.mydomain.compassassem para o sshd do contêiner.


Quero conexões ssh para:

  • mydomain.com host.mydomain.com ou o endereço IP do meu domínio seja aceito e encaminhado para o sshd no host
  • gogs.mydomain.comou git.mydomain.compara ser aceito e passado para o sshd no contêiner gogs
  • *.mydomain.com(onde *existe algo diferente das possibilidades acima) a ser rejeitado

Se fosse http, eu poderia facilmente fazer isso funcionar através do nginx. Existe uma maneira de fazer isso pelo ssh?


(Também gostaria de sair em um membro e perguntar: existe uma maneira de fazer isso com qualquer serviço tcp em geral?)

Quaisquer insights sobre o modo como estou tentando fazer isso aqui também são bem-vindos. Não me importo de saber quando o que estou tentando fazer é totalmente estúpido.


O que eu já tenho em mente:

Talvez eu pudesse compartilhar o soquete sshd no host com o contêiner como um rovolume? Isso significaria que o sshd dentro do contêiner poderia pegar todas as conexões *.mydomain.com. Poderia haver uma maneira de fazer o sshd dentro do contêiner rejeitar todas as conexões que não sejam gogs.mydomain.comou git.mydomain.com? No entanto, o sshd no host selecionará todas as conexões de *.mydomain.comqualquer maneira, inclusive gogs.mydomain.com; então haveria um conflito. Não sei, na verdade não tentei. Devo tentar?

Zia Ur Rehman
fonte

Respostas:

2

Fazer isso "pelo nome do host" simplesmente não está dentro do escopo do ssh. O próprio protocolo ssh não suporta hospedagem virtual baseada em nome (na verdade, o HTTP é a exceção da regra aqui).

O SSHd no lado receptor nunca pode saber a qual nome do host você pediu ao seu cliente para se conectar, pois essas informações não são passadas dentro do protocolo.

Se você precisar apenas de alguns clientes para trabalhar com isso, poderá configurar cada cliente para se conectar ao servidor e, em seguida, pular para o contêiner do docker da seguinte maneira:

Host yourcontainer
        Hostname internal.ip.of.your.container
        ProxyCommand ssh your.docker.host nc %h %p

Dessa forma, o ssh chamará o comando proxy que abrirá uma sessão ssh para o host e chamará netcatpara estabelecer uma conexão com o contêiner. Dessa forma, você realmente não precisa expor a porta ssh de seus contêineres para o mundo exterior.

Andreas Rogge
fonte
0

As versões recentes do OpenSSH têm a diretiva ProxyJump e o sinalizador -J:

ssh -J proxyuser@jumphost user@target
ptman
fonte