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

9

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

Antecedentes

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

Agora, quero iniciar um contêiner docker gogs de tal forma que gogs.mydomain.com aponte para o contêiner gogs. Então eu começo este contêiner de gogs com a porta 8000 vinculada a 127.0.0.1:8001 no host. E um proxy do site nginx solicita gogs.mydomain.com a http://127.0.0.1:8001 e funciona bem ...

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

(Isso não parece funcionar; quando eu envio para uma origem com uri assim, git exige a senha do usuário git on gogs.mydomain.com - em vez de gogs.mydomain.com:8022 - mas isso é provavelmente algo que eu sou fazendo errado e fora do escopo para esta questão, no entanto, gostaria de receber qualquer diagnóstico para isso também)

Problema

Minha principal preocupação é que eu queira que a porta ssh <gogs container>:22 seja intermediada por proxy, assim como eu estou fazendo proxies portas http usando nginx; Ou seja, quaisquer conexões ssh para gogs.mydomain.com são passadas para a porta% cont_de% do contêiner. 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 quaisquer conexões com 22 são passadas para o sshd do contêiner.

Eu quero conexões ssh para:

  • *.mydomain.com mydomain.com ou o endereço IP do mydomain a ser aceito e encaminhado para o sshd no host
  • host.mydomain.com ou gogs.mydomain.com a ser aceito e repassado para o sshd no contêiner de gogs
  • git.mydomain.com (onde *.mydomain.com é algo diferente das possibilidades acima) a ser rejeitado

Se fosse http, eu poderia facilmente fazer esse trabalho através do nginx. Existe uma maneira de fazer isso para o ssh?

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

Qualquer insight sobre a maneira como estou tentando fazer isso aqui também é bem-vindo. Não me importo de saber quando o que estou tentando fazer é totalmente estúpido.

O que eu já tenho em mente:

Talvez eu possa compartilhar o soquete sshd no host com o contêiner como * volume? Isso significaria que o sshd dentro do contêiner poderia coletar todas as conexões para ro . Poderia haver uma maneira de tornar o sshd dentro do container rejeitar todas as conexões diferentes de *.mydomain.com ou gogs.mydomain.com ? No entanto, o sshd no host irá coletar todas as conexões para git.mydomain.com , incluindo *.mydomain.com ; então haveria um conflito. Eu não sei, eu realmente não tentei. Devo experimentar?

    
por Zia Ur Rehman 13.04.2016 / 05:28

2 respostas

2

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

O SSHd no lado de recebimento nunca pode saber a que nome de host você solicitou que seu cliente se conecte, pois esta informação não é passada dentro do protocolo.

Se você precisar apenas de alguns clientes para trabalhar com isso, configure cada cliente para se conectar ao seu servidor e, em seguida, pule para o contêiner da janela de encaixe da seguinte forma:

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

Desta forma, o ssh invocará o comando proxy, que abrirá uma sessão ssh para seu host e chamará netcat para estabelecer uma conexão com seu contêiner. Desta forma, você realmente não precisa expor sua porta ssh de contêineres para o mundo exterior.

    
por 28.07.2017 / 16:22
0

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

ssh -J proxyuser@jumphost user@target
    
por 23.08.2017 / 08:40