Como posso configurar uma conexão SSH reversa para o computador conectado?

20

Vou implantar várias máquinas em um futuro próximo, que estarão atrás de roteadores. Não será viável configurar o DNS dinâmico em cada roteador e encaminhamento de porta; portanto, existe uma maneira de configurar essas máquinas para iniciar uma conexão TCP com o meu computador e depois fazer com que o meu computador inicie uma conexão SSH com o computador remoto. essa conexão?

IE:

COMPUTER A OPENS TCP CONNECTION TO COMPUTER B
COMPUTER B OPENS SSH CONNECTION OVER THE EXISTING TCP CONNECTION TO COMPUTER A
COMPUTER B NOW HAS SSH CONNECTION TO COMPUTER A

Isso é possível? Em caso afirmativo, como posso fazer isso?

Naftuli Kay
fonte
2
Relacionado (como e por que funciona): Como funciona o encapsulamento SSH reverso?
Gilles 'SO- stop be evil'

Respostas:

21

Em /etc/ssh/sshdpara computador B set:

AllowTcpForwarding yes
TCPKeepAlive yes

Do Computador A :

$ ssh -R 2222:localhost:22 ip.of.computer.b

Do computador B :

$ ssh localhost -p 2222

Observe que 2222 é um número arbitrário de porta alta que eu escolhi. Essa porta no Computador B será encapsulada de volta através da conexão SSH inicializada no Computador A para a porta 22. Se você tiver várias máquinas, deverá usar uma porta diferente para cada máquina.

Para o seu caso de uso, você provavelmente desejará executá-lo a partir de um script para torná-lo um daemon e periodicamente tentar se reconectar se o link for descartado. Você provavelmente desejará uma conta especial com um shell apenas /bin/trueno Computador B para lidar com as conexões de entrada. Você pode configurar uma única chave ou várias chaves para cada máquina que pode "ligar para casa".

No Computador A que você pode encontrar o -n, -Ne -Topções úteis para desconectá-lo da entrada local (para que ele possa ser executado em segundo plano), não tente executar qualquer comando remoto, basta abrir o túnel, e não criar um tty.

A maioria dos métodos normais de gerar um daemon não funciona muito bem com a configuração de um túnel de rede como este. Um problema na conectividade de rede faria com que tentasse derrubar o muro para superar. Um loop simples com um sono para aguardar deve fazer o truque. Dez minutos é um bom número, porque não inunda a rede e os arquivos de log com tentativas, se houver um problema (como o Computador B estar offline), mas ainda assim você voltará razoavelmente rápido se a conexão cair.

#/bin/sh
while true; do
    sleep $((60*10))
    ssh -nNT -R 2222:localhost:22 ip.of.computer.b
done

Um script como esse pode ser executado iniciado na inicialização /etc/rc.local. Sua primeira alteração no logon na máquina começará cerca de dez minutos após a inicialização do Computador A.

Caleb
fonte
1
Agradável. Então, basicamente, cada máquina remota encapsula a porta SSH local em uma porta na máquina local? Pode ser aconselhável que cada máquina encapsule apenas a conexão sob demanda. Talvez eu consiga que cada máquina abra uma conexão HTTP keep-alive e envie dados XML quando desejar que ela tente uma conexão reversa, para facilitar o gerenciamento (e não obstruir todas as minhas portas;]). Obrigado!
Naftuli Kay
@TKKocheran: Existem várias portas para você escolher ... especificamente mais do que você terá quiosques. Como manter um túnel SSH aberto é pior do que manter uma conexão http aberta?
Caleb
Eu acho que você está certo, eu poderia fazer isso, mas então eu teria que mapear portas para máquinas e lembrar qual é qual, enquanto a outra rota seria preguiçosamente instanciada, ou seja, apenas criar um túnel SSH quando solicitado.
Naftuli Kay
1
@TKKocheran: Você teria que fazer o mapeamento de qualquer maneira, caso contrário, sua instancia preguiçosa se depararia com situações em que eles tentavam se intimidar.
Caleb
1
Eu não sei se ele é aplicável, mas meu sshd configuração está agora em/etc/ssh/sshd_config
GC5