Com esse artigo pretendo mostrar uma maneira prática de acessar computadores protegidos por uma firewall ou NAT. Isso é muito útil nos casos em que não é possível - ou não se tem o controle para - efetuar um direcionamento de portas para a máquina desejada. É apresentado ainda um script que, utilizando DNS dinâmico, permite estabelecer essa conexão de qualquer lugar.
Não seria ótimo se, ao precisarmos acessar um computador distante, pudéssemos simplesmente iniciar o ssh e voilá... cairmos dentro de nosso amado shell remoto? Infelizmente o mundo não é perfeito e, não raras vezes, nos deparamos com NATs e firewalls que impedem nosso acesso direto.
Quando se tem gerência sobre o roteador ou firewall em questão a solução pode ser até simples: basta direcionar uma porta específica no lado WAN (geralmente a internet) para a máquina desejada na LAN. Quando isso não é possível surge a questão... o que fazer para acessar o tal computador?
Numa série de telecentros que instalamos no interior do Maranhão (Projeto Jovem Cidadão) essa pergunta não queria calar, pois em algumas cidades não existia outro meio de acesso que não fosse via satélite, tirando totalmente de nosso controle direcionar portas para os servidores de thin client que precisávamos gerenciar remotamente.
Entendendo a teoria da solução
Após uma boa pesquisa, deparei-me com essa maravilha chamada SSH reverso. Nessa modalidade, quem inicia a conexão SSH não é a sua máquina (cliente) e sim a máquina que desejamos acessar (servidor). É justamente por isso que se consegue bypassar NAT e a maioria das firewalls, pois é bastante comum se bloquear nelas as conexões de entrada, mas não as de saída.
Uma vez estabelecida a conexão para nossa máquina, podemos iniciar o SSH para uma porta local específica e então "cair" na máquina que desejamos gerenciar através do túnel que havia sido criado pela primeira conexão. Na prática isso funciona assim:
1. No servidor, estabeleça a conexão SSH reversa para o cliente:
ssh -R 9000:localhost:22 usuario@cliente
Esse comando faz com que as conexões à porta 9000 no cliente sejam direcionadas à porta 22 do localhost (servidor), desde que o usuário "usuario" exista e tenha acesso SSH liberado no computador denominado "cliente".
2. No cliente, estabeleça a conexão SSH direta para a porta aberta pelo túnel:
ssh -p 9000 usuario@localhost
Esse comando estabelecerá a conexão SSH à porta local 9000 (no cliente), direcionando todos os seus comandos para a porta 22 do servidor pelo túnel estabelecido anteriormente. Neste caso o usuário "usuario" tem que existir no servidor e possuir nele acesso SSH liberado.
Note que "usuario" não precisa ser o mesmo no servidor e no cliente, utilizei o mesmo nome porque é um exemplo genérico. Da mesma forma a porta utilizada não precisa ser a 9000, mas qualquer porta que não esteja sendo utilizada no computador cliente.
[1] Comentário enviado por andre.vmatos em 21/11/2008 - 16:50h
Hhmmm. Muito boa a dica. Suponho que vc deve ter aprendido isso no artigo do GdH. Se sim, acredito que seria justo colocar os creditos. De qualquer forma, muito bom e muito completo mesmo seu artigo. Parabéns.
[5] Comentário enviado por chffelix em 21/11/2008 - 19:14h
Inicialmente, gostaria de agradecer o incentivo de todos. É um imenso prazer poder contribuir para essa comunidade maravilhosa, na qual a troca de conhecimento é feita de forma tão natural e visando o bem comum.
Gostaria apenas de responder o questionamento do nosso colega andre.vmatos, sobre os supostos créditos "devidos" ao GdH. Vocês devem ter reparado que coloquei três referências ao final do meu artigo. Pois bem, a primeira delas foi a principal, que eu realmente usei como base para minha solução em 2006, quando enfrentamos esse problema na prática. Reparem inclusive que meu script se parece com o dele, guardando minhas adaptações específicas. As referências seguintes servem apenas como outras fontes que os interessados podem pesquisar para comparar e realmente entender o que está sendo feito. Em nenhum momento sequer soube da existência desse artigo do GdH, tendo-o visto pela primeira vez agora com esse comentário.
Resumindo, não vou adicionar o crédito pois realmente não é devido. Apesar de desconfiar que o comentário não teve essa intenção, achei bastante deselegante a suposição, pois lança dúvidas sobre um trabalho autêntico e que comecei a escrever desde outubro de 2007, quando então se tinha muito menos material sobre o assunto.
Bom, é isso aí. Espero que a informação seja útil e obrigado a todos novamente pela atenção e incentivo.
[8] Comentário enviado por wagner_guitar em 22/11/2008 - 11:05h
Desculpe a minha ignorancia mais na parte do comando >>
$ ssh -R 9000:localhost:22 usuario@cliente
o usuario (usuario@) é o nome do host ou o ip ,e sobre o cliente tenho a mesma duvida...
tipo tenho um host cujo nome do usuario seja Brasil@... , e o ip dele seja 200.200.200.200 onde ficaria o Brasil e onde ficaria o 200.200.200.200 no comando $ ssh -R 9000:localhost:22 usuario@cliente
?????
Desde ja agradeco....
[9] Comentário enviado por chffelix em 22/11/2008 - 12:11h
Olá Wagner, sem problema, estamos aqui pra aprender mesmo :)
Nesse comando que você está em dúvida, "usuario" é o nome do usuário existente na máquina cliente (aquela em que você vai estar logado), sendo este responsável apenas por "atender" o pedido de criação do tunel. Já "cliente" seria o hostname ou IP do cliente, novamente, da máquina onde você está. Esse comando aí deve ser executado no servidor, que é a máquina remota que você deseja acessar. Por isso tem todo esse esquema para esse comando ser executado automaticamente, pois você não vai estar lá pra fazer isso, certo?
Para adaptar o negócio ao seu exemplo, você deve considerar outra máquina. Por exemplo.. você está logado na máquina 200.200.200.200, mas você quer acessar a 100.100.100.100. Então, nessa última você rodaria:
ssh -R 9000:localhost:22 brasil@200.200.200.200
Uma vez estabelecida a conexão (a pessoa em 100.100.100.100 teria que saber a senha de brasil ou ter sua chave pública cadastrada para ele), você pode então se conectar ao servidor. Digamos que o usuário que você deseja acessar em 100.100.100.100 seja wagner. Assim, estando em 200.200.200.200, você deverá executar esse comando:
ssh -p9000 wagner@localhost
Pronto! Você vai cair no shell de 100.100.100.100, com usuário wagner.
[10] Comentário enviado por wagner_guitar em 22/11/2008 - 13:59h
Nao muito,desculpe
tipo tanto "usuario" quanto "cliente" vao ser da maquina remota??
mas eu nao tenho acesso nenhum a maquina remota.
o meu problema é o seguinte : sou cliente de uma rede wireless ( radio),gostaria de acessar o roteador da minha rede para abrir algumas portas, é que gostaria de baixar uns torrents, mas acho q as portas estao fechadas, ai so consigo baixar a 1.,3kbps no maximo. Mas nao sei o login do roteador . Gostaria de resolver isso , se vc souber como eu posso fazer isso gostaria q me ajudasse...
[11] Comentário enviado por chffelix em 22/11/2008 - 17:03h
Wagner, o que descrevi no artigo é apenas para o caso de querer acessar uma máquina remota que está numa rede sem acesso de fora pra dentro. Se você quer apenas se logar no roteador da sua rede e você não tem acesso a ele esse procedimento infelizmente não vai lhe ajudar. Para fazer o que você quer, vai ter que conseguir a senha do roteador e fazer um direcionamento de portas nele mesmo, do lado WAN para o IP da sua máquina no lado LAN.