Como funciona o encapsulamento SSH reverso?


350

Pelo que entendi, os firewalls (assumindo as configurações padrão) negam todo o tráfego recebido que não possui tráfego de saída correspondente anterior.

Com base no Reversão de uma conexão ssh e no SSH Tunneling Made Easy , o tunelamento SSH reverso pode ser usado para contornar as restrições de firewall.

Eu gostaria de executar comandos shell em uma máquina remota. A máquina remota possui seu próprio firewall e está atrás de um firewall adicional (roteador). Possui um endereço IP como 192.168.1.126 (ou algo semelhante). Não estou atrás de um firewall e sei o endereço IP da máquina remota visto na Internet (não o endereço 192.168.1.126). Além disso, eu posso pedir a alguém para executar ssh (something)como root na máquina remota em primeiro lugar.

Alguém poderia me explicar, passo a passo, como o encapsulamento SSH reverso funciona para contornar os firewalls (firewalls de máquinas locais e remotas e o firewall adicional entre eles)?

Qual é o papel dos interruptores ( -R, -f, -L, -N)?


Respostas:


403

Adoro explicar esse tipo de coisa através da visualização. :-)

Pense em suas conexões SSH como tubos. Tubos grandes. Normalmente, você acessará esses tubos para executar um shell em um computador remoto. O shell é executado em um terminal virtual (tty). Mas você já conhece essa parte.

Pense no seu túnel como um tubo dentro de um tubo. Você ainda tem a grande conexão SSH, mas a opção -L ou -R permite configurar um tubo menor dentro dela.

Todo tubo tem um começo e um fim. O tubo grande, sua conexão SSH, começou com seu cliente SSH e termina no servidor SSH ao qual você se conectou. Todos os tubos menores têm os mesmos pontos finais, exceto que o papel de "início" ou "fim" é determinado por você ter usado -Lou -R(respectivamente) para criá-los.

(Você não disse, mas vou assumir que a máquina "remota" que você mencionou, a que está atrás do firewall, pode acessar a Internet usando o Network Address Translation (NAT). Isso é meio importante, então corrija essa suposição se for falsa.)

Ao criar um túnel, você especifica um endereço e uma porta na qual ela responderá e um endereço e porta na qual será entregue. A -Lopção informa ao túnel para responder no lado local do túnel (o host executando o seu cliente). A -Ropção informa ao túnel para responder no lado remoto (o servidor SSH).

direções do túnel ssh

Portanto ... Para poder fazer o SSH da Internet em uma máquina atrás de um firewall, é necessário que a máquina em questão abra uma conexão SSH com o mundo externo e inclua um -Rtúnel cujo ponto de "entrada" é o lado "remoto" do a conexão dele.

Dos dois modelos mostrados acima, você deseja o modelo à direita.

No host com firewall:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

Isso diz ao seu cliente para estabelecer um túnel com um -Rponto de entrada emote. Qualquer coisa anexada à porta 22222 na extremidade do túnel alcançará "porta localhost 22", onde "localhost" é da perspectiva do ponto de saída do túnel (ou seja, seu cliente ssh).

As outras opções são:

  • -f diz ao ssh para fazer o segundo plano após a autenticação, para que você não precise ficar rodando algo no servidor remoto para que o túnel permaneça ativo.
  • -Ndiz que você deseja uma conexão SSH, mas na verdade não deseja executar nenhum comando remoto. Se tudo o que você está criando é um túnel, a inclusão dessa opção economiza recursos.
  • -T desabilita a alocação de pseudo-tty, o que é apropriado porque você não está tentando criar um shell interativo.

Haverá um desafio de senha, a menos que você tenha configurado chaves DSA ou RSA para um login sem senha.

Observe que é altamente recomendável que você use uma conta descartável (não o seu próprio login) que você configurou apenas para esse túnel / cliente / servidor.

Agora, a partir do seu shell no yourpublichost , estabeleça uma conexão com o host com firewall através do túnel:

ssh -p 22222 username@localhost

Você terá um desafio importante do host, pois provavelmente nunca o atingiu antes. Em seguida, você terá um desafio de senha para a usernameconta (a menos que tenha configurado as chaves para o login sem senha).

Se você estiver acessando esse host regularmente, também poderá simplificar o acesso adicionando algumas linhas ao seu ~/.ssh/configarquivo:

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Ajuste remotehostnamee remoteusernamese adapte. O remoteusernamecampo deve corresponder ao seu nome de usuário no servidor remoto, mas remotehostnamepode ser qualquer nome de host que combina com você, não precisa corresponder a nada resolvível.

(Para expor o ponto de extremidade reverso em um IP de host não local , confira esta postagem )


2
e quanto ao ssh -D. Por favor, explique usando o mesmo método.
BigSack

6
Os proxies do SOCKS não são iguais aos túneis. Se você tiver alguma dúvida sobre como usá-los, faça -o .
ghoti

12
Estou tendo um momento muito difícil de seguir esta explicação devido ao pouco uso de termos: servidor, cliente, máquina local, máquina remota, host, seupublichost, localhost, remotehostname. Com todos esses termos indefinidos e indefinidos, pode-se presumir que alguém precisaria de 8 computadores para configurá-lo. Afirmo isso porque em todos os outros aspectos parece uma explicação muito boa. Reduza e defina os termos.
Rucent88

4
@ Rucent88, não tenho certeza de qual redução seria possível. Um cliente estabelece uma conexão com um servidor. Essa terminologia comum em todo o mundo das redes. Máquinas locais e remotas parecem bastante evidentes. Se você estiver confuso sobre o SSH ou a terminologia geral do unix depois de ler a documentação, tenho certeza de que não terá problemas em encontrar pessoas aqui muito dispostas a responder a quaisquer perguntas que possa ter.
ghoti 18/09/2015

9
@hothot É realmente confuso, porque as máquinas locais e remotas são relativas. Quando estou sentado no local de trabalho, meu computador doméstico é o controle remoto, quando estou em casa, o computador no local de trabalho é remoto. Servidor e cliente também são confusos quando se fala em encapsulamento. Por exemplo, se eu me conectar a casa do trabalho com ssh -R. Eu me conecto ao meu trabalho no computador doméstico conectando o host local. Portanto, da perspectiva dos soquetes, o servidor é o próprio computador doméstico. Mas logicamente eu me conectei ao meu computador de trabalho. Isso é confuso.
Calmarius

357

Eu desenhei alguns esboços

A máquina onde o comando ssh tunnel é digitado é chamado »seu host« .

túnel ssh a partir do local


túnel ssh a partir do controle remoto

Introdução

  1. local: -L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHostsignifica: conectar com ssh ae connectToHostencaminhar todas as tentativas de conexão para o local sourcePort a porta onPortna máquina chamada forwardToHost, que pode ser acessada a partir da connectToHostmáquina.

  2. controlo remoto: -R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHostsignifica: conectar com ssh connectToHoste encaminhar todas as tentativas de conexão para o controle remoto sourcePort na porta onPortda máquina chamada forwardToHost, que pode ser acessada a partir da sua máquina local.

Opções adicionais

  • -f diz ao ssh para fazer o segundo plano após a autenticação, para que você não precise ficar rodando algo no servidor remoto para que o túnel permaneça ativo.
  • -Ndiz que você deseja uma conexão SSH, mas na verdade não deseja executar nenhum comando remoto. Se tudo o que você está criando é um túnel, a inclusão dessa opção economiza recursos.
  • -T desabilita a alocação de pseudo-tty, o que é apropriado porque você não está tentando criar um shell interativo.

Seu exemplo

A terceira imagem representa esse túnel. Mas o computador azul chamado "seu host" representa o computador em que alguém inicia o túnel ssh, neste caso a máquina com firewall.

Portanto, peça a alguém para iniciar uma conexão de túnel ssh com sua máquina. O comando deve basicamente parecer

ssh -R 12345:localhost:22 YOURIP

Agora o túnel está aberto. Agora você pode conectar via ssh à máquina com firewall através do túnel com o comando

ssh -p 12345 localhost

que se conectará ao seu localhost(sua máquina) na porta 12345, mas a porta 12345será encaminhada pelo túnel para a porta 22 do host local do computador com firewall (ou seja, o próprio computador com firewall).


9
Ótima resposta! Usará isso em uma apresentação.
Isaiah Turner

4
Obrigado. De nada. Se você deseja imagens vetoriais (svg ou pdf), escreva-me uma mensagem.
Erik

1
@erik, como você desenhou essas imagens?
Pacerier

31
oh cara, eu gostaria que as páginas de manual pudessem ter explicações como essa! obrigado!
precisa saber é o seguinte

30
Você sabe o que ? Eu nem precisei ler a explicação do texto. Ótimo trabalho !
Deppfx

21

O tunelamento ssh funciona usando a conexão ssh já estabelecida para enviar tráfego adicional.

Quando você se conecta a um servidor remoto, normalmente possui apenas 1 canal para a interação normal do usuário (ou 3 canais se considerar STDIN / STDOUT / STDERR separado). A qualquer momento, o processo ssh local ou remoto pode abrir canais adicionais na conexão existente. Esses canais enviam / recebem o tráfego do túnel. Ao enviar ou receber qualquer tráfego, o processo ssh simplesmente diz "esse tráfego é para o canal foobar".

Essencialmente funciona assim:

  1. Você diz ao ssh para começar a escutar na porta XXXX e que qualquer tráfego recebido deve ser encapsulado em túnel e, em seguida, defina como AAAA na porta ZZZZ.
  2. O ssh local começa a escutar na porta XXXX (geralmente ativada 127.0.0.1, mas pode ser alterada).
  3. Alguns aplicativos abrem uma conexão com a porta XXXX na máquina local.
  4. O ssh local abre um canal para o ssh remoto e diz "qualquer tráfego nesse canal vai para AAAA: ZZZZ
  5. O ssh remoto se conecta a YYYY: ZZZZ e envia de volta a mensagem "OK, o canal está aberto"
  6. Agora, qualquer tráfego enviado ao longo da conexão para a porta XXXX na máquina local é proxy por ssh para YYYY: ZZZZ.

Esse processo é exatamente o mesmo para os encapsulamentos para frente e para trás (apenas troque as palavras 'local' e 'remoto' no procedimento acima). Qualquer um dos lados pode iniciar o túnel. Nem precisa ser quando você inicia o ssh. Você pode abrir túneis enquanto o ssh já estiver em execução (consulte ESCAPE CHARACTERS, especificamente ~C).

Para o papel de -R, -f, -L, e -N, você realmente deve apenas consultar a página homem, que lhe dá a melhor explicação possível. Mas eu vou mencionar -Re -L.
-Rdiz ao ssh remoto para escutar as conexões e que o ssh local deve se conectar ao destino real. -Ldiz ao ssh local para escutar as conexões e que o ssh remoto deve se conectar ao destino real.

Observe que esta é uma descrição muito grosseira, mas deve fornecer informações suficientes para saber o que está acontecendo


16

Isso é explicado no manual SSH, especialmente as diferenças entre -L(local) e -R(remoto).


-L

-L [bind_address:]port:host:hostport

Especifica que a porta especificada no host local (cliente) deve ser encaminhada para o host e a porta especificados no lado remoto .

Isso funciona alocando um soquete para escutar a porta no lado local, opcionalmente vinculada ao endereço bind_ad especificado.

Sempre que é feita uma ligação a esta porta, a ligação é encaminhado através de um canal seguro, e é estabelecida uma ligação de hostporta hostporta partir do computador remoto .

O exemplo a seguir encapsula uma sessão de IRC da máquina cliente 127.0.0.1( localhost) usando a porta 1234 para o servidor remoto server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Nota: A -fopção backgrounds ssh e o comando remoto sleep 10são especificados para permitir uma quantidade de tempo para iniciar o serviço a ser tunelizado.

Exemplo:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Depois de conectar, aguarde um pouco (você não receberá um prompt de shell)

    Não execute um comando remoto.

  • -L 22000A ligação terá origem na porta 22000 do seu, pessoal L máquina ocal

  • localhost:11000- remote.server.comgarantirá que a outra extremidade do túnel seja a localhostporta11000

ssh -N -L 22000: 192.168.1.2: 11000 remote.server.com

Fonte: Um guia ilustrado, tutorial, instruções, sobre encapsulamento ssh .


-R

-R [bind_address:]port:host:hostport

Especifica que a porta especificada no host remoto (servidor) deve ser encaminhada para o host e a porta especificados no lado local .

Isso funciona alocando um soquete para escutar portno lado remoto e, sempre que uma conexão é feita a essa porta, a conexão é encaminhada pelo canal seguro e uma conexão é feita na hostporta hostportda máquina local .

Exemplo:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Depois de conectar, aguarde um pouco (você não receberá um prompt de shell)

    Não execute um comando remoto.

  • -R22000 A conexão terá origem na porta 22000 do computador emote R (neste caso, remote.server.com)

  • localhost:11000seu computador pessoal local garantirá que a outra extremidade do túnel seja a localhostporta11000

ssh -N -R 22000: localhost: 11000 remote.server.com

Fonte: Um guia ilustrado, tutorial, instruções, sobre encapsulamento ssh .


6
o ouvido e a boca deixam claro quem está falando e quem está ouvindo!
Thufir

1
Eu amo suas ilustrações!
Mcantsin
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.