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.
1. Como usuário root, crie o arquivo ssh-tunnel.sh em /usr/local/bin. Ele deverá conter o seguinte:
#!/bin/sh
# Remove o arquivo known_hosts para que o SSH não pare informando
# que a identificação do host mudou (isso acontecerá se você apontar
# o hostname no DNS para uma máquina diferente)
if [ -f /home/tunnel/.ssh/known_hosts ]; then
rm /home/tunnel/.ssh/known_hosts
fi
# Comando responsável por estabelecer o túnel SSH reverso
COMMAND="ssh -Cp 26 -o StrictHostKeyChecking=no -nNT -R $1:localhost:22 tunnel@$2"
# Comando para verificar se o túnel já se encontra estabelecido
CHECK_TUNNEL=`ps ax | grep "$COMMAND" | grep -v grep`
# Verifica se o túnel está criado. Se não estiver, executa comando para criá-lo
if [ -z "$CHECK_TUNNEL" ] ; then
$COMMAND
fi
Repare que em COMMAND utilizei a porta 26 porque minhas máquinas cliente costumam estar com a porta 22 bloqueada pela operadora de banda larga. Adapte essa porta para aquela que você utiliza para acessar o SSH em sua máquina cliente. A opção "C" pode ser colocada para habilitar a compressão do ssh, útil caso o link de internet seja lento.
A chave -nNT diz para o ssh não aceitar entrada de stdin, não executar comandos remotos e não alocar um terminal. Fazemos isso porque queremos apenas estabelecer o túnel para permitir conexões pela outra ponta, e não estabelecer uma sessão interativa com a máquina cliente.
A chave -R informa ao cliente para mapear a porta especificada (argumento $1 do script) para a porta 22 do servidor, conforme já explicado na seção "teórica". Se seu servidor também estiver em um link com portas bloqueadas, pode ser preciso rodar o daemon do SSH em outra porta, caso em que será necessário alterar também essa porta. O hostname a ser utilizado na conexão corresponde ao informado no argumento $2 do script.
2. Crie um usuário responsável por estabelecer o túnel SSH reverso e gere para ele uma chave ssh *sem passphrase* (isso é muito importante para que a coisa funcione de forma automática):
# adduser tunnel
# su tunnel
$ ssh-keygen -t dsa
3. Ainda logado como usuário tunnel, crie uma "cron job" para o servidor tentar conexão ao cliente de 1 em 1 minuto:
crontab -e
Na tela que se abrirá no editor "vi" (suponho que você saiba como utilizá-lo), entre com a seguinte linha:
[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.