termal.in

← Blog

Túneis SSH reversos (ssh -R): exponha uma porta local por um servidor remoto

· Termalin Team sshport-forwardingtunnelingtutorial

Você tem algo rodando no seu notebook — um servidor de desenvolvimento, uma API, uma máquina em casa atrás de NAT — e algo do outro lado da internet precisa alcançá-lo. Sem IP público, sem acesso ao roteador, sem tempo para montar uma VPN. Essa é a função do túnel SSH reverso, o ssh -R: ele faz surgir uma porta em um servidor que você consegue alcançar e, discretamente, encaminha de volta para a sua máquina tudo o que chega nela.

É a flag que as pessoas acham invertida, então vamos acertar o modelo mental primeiro e depois percorrer os casos reais.

O modelo mental: o -L, espelhado

Todo túnel SSH abre uma porta de escuta em uma máquina e envia o que chega a algum lugar alcançável a partir da outra máquina. No encaminhamento local (-L), a porta abre na sua máquina e o tráfego sai pelo lado do servidor. Um túnel reverso é exatamente a imagem espelhada:

Com o -R, a porta de escuta abre no servidor remoto, e as conexões a ela saem do seu lado.

É esse o truque inteiro. A máquina que não consegue aceitar conexões de entrada faz, em vez disso, uma conexão SSH de saída — e recebe conexões de volta por ela. Se os dois ainda se confundem, o retrato completo da família está em encaminhamento de portas SSH, explicado.

A sintaxe, lida da esquerda para a direita

ssh -R [bind_address:]remote_port:localhost:local_port user@server

Leia assim: no servidor, escute em remote_port; encaminhe tudo o que chegar para localhost:local_port — resolvido a partir da minha máquina. Então:

ssh -R 8080:localhost:3000 deploy@vps.example.com

abre a porta 8080 no VPS, e toda conexão a ela cai na porta 3000 do seu notebook. O destino não precisa ser o próprio notebook — -R 8080:192.168.1.50:80 encaminha para outra máquina na sua LAN, usando o seu notebook como saída.

Uma flag que vale conhecer: -R 0:localhost:3000 deixa o servidor escolher qualquer porta livre e imprime Allocated port 43022 for remote forward para você saber qual foi.

Três coisas que as pessoas realmente constroem com isso

Mostrar um servidor de desenvolvimento local para um cliente. O seu trabalho em andamento roda em localhost:3000. Em vez de fazer o deploy em algum lugar só para uma demonstração:

ssh -N -R 8080:localhost:3000 deploy@demo.example.com

Qualquer um que alcance demo.example.com:8080 agora está vendo o app no seu notebook, ao vivo. (O -N pula o shell remoto — você só quer o túnel. Se qualquer um ou só o próprio servidor pode conectar depende do GatewayPorts — próxima seção.)

Alcançar uma máquina doméstica atrás de NAT. A sua máquina de casa não consegue aceitar conexões, mas consegue fazê-las. Faça com que ela mantenha um túnel de saída até um pequeno VPS:

# on the home machine
ssh -N -R 2222:localhost:22 tunnel@vps.example.com

Agora a porta 2222 do VPS é a porta SSH da máquina de casa, e de qualquer lugar:

ssh -J vps.example.com -p 2222 you@localhost

salta pelo VPS direto para a máquina atrás de NAT. Essa é a clássica resposta self-hosted para como fazer SSH no seu servidor doméstico.

Entregar webhooks no seu notebook. Um provedor de pagamentos ou um host de Git precisa fazer POST no seu handler em desenvolvimento. Faça um túnel do endpoint alcançável deles de volta até você:

ssh -N -R 9000:localhost:9000 deploy@vps.example.com

Aponte o webhook para o VPS. Se você mantiver o túnel vinculado ao loopback do servidor (o padrão), coloque o nginx ou qualquer proxy reverso no VPS na frente de 127.0.0.1:9000 — você ganha terminação TLS de graça e nunca expõe a porta bruta do túnel.

GatewayPorts: por que ninguém mais alcança o seu túnel

A surpresa número um: o túnel funciona quando você o testa a partir do servidor (o curl localhost:8080 dá certo), mas ninguém de fora consegue conectar. Isso é proposital — por padrão, o sshd vincula as portas encaminhadas remotamente apenas a 127.0.0.1, não importa qual endereço de bind você tenha pedido.

Para abrir um túnel para o mundo, o /etc/ssh/sshd_config do servidor precisa de:

GatewayPorts clientspecified

depois reinicie o sshd e peça o bind explicitamente: ssh -R 0.0.0.0:8080:localhost:3000 .... (O GatewayPorts yes vincula todo encaminhamento remoto a todas as interfaces, o que costuma ser mais amplo do que você quer.) Essa é uma decisão do lado do servidor que você não pode sobrepor pelo cliente — um padrão de segurança deliberado, já que um túnel reverso é um furo aberto de dentro, e tudo o que ele expõe fica, na prática, voltado para a internet. Trate-o assim.

Duas opções relacionadas no lado do servidor podem te pegar: AllowTcpForwarding no desativa os túneis por completo, e PermitListen pode restringir quais portas o -R pode reivindicar.

Mantendo o túnel vivo

Um túnel reverso é uma única conexão TCP, e conexões TCP ociosas morrem. Para qualquer coisa mais longa que uma demonstração:

ssh -N -R 2222:localhost:22 \
    -o ServerAliveInterval=30 \
    -o ExitOnForwardFailure=yes \
    tunnel@vps.example.com
  • ServerAliveInterval 30 mantém o tráfego fluindo para que entradas de NAT e timeouts de ociosidade não derrubem a conexão.
  • ExitOnForwardFailure yes faz o ssh falhar ruidosamente se a porta remota não puder ser vinculada, em vez de conectar assim mesmo e não encaminhar nada.
  • autossh envolve o comando e reinicia o túnel sempre que ele cai — a ferramenta padrão para túneis que devem sobreviver a reinicializações e redes instáveis, normalmente executado como autossh -M 0 -N -R ... sob uma unidade do systemd.

E quando um túnel conquista um lugar permanente, mova-o para o ~/.ssh/config com uma linha RemoteForward, para que ele acompanhe a entrada do host — estrutura explicada no guia do ssh_config (em inglês):

Host homelink
    HostName vps.example.com
    User tunnel
    RemoteForward 2222 localhost:22
    ServerAliveInterval 30
    ExitOnForwardFailure yes

-L vs -R vs -D num relance

FlagPorta abre emTráfego sai emTarefa típica
-Lsua máquinalado do servidortrazer um banco/painel remoto para o localhost
-Ro servidorseu ladoexpor serviço local; alcançar uma máquina atrás de NAT
-Dsua máquinalado do servidor, qualquer destinoproxy SOCKS para dentro de uma rede

Quando o túnel reverso é a ferramenta errada

Um túnel reverso é uma ótima resposta temporária: demonstrações, depuração de webhooks, resgatar uma máquina atrás de NAT. É uma resposta permanente ruim. Se aquilo que você expõe precisa ficar de pé por meses, atender usuários reais ou sobreviver ao seu notebook dormindo — isso é ingresso de tráfego, e ingresso merece infraestrutura de verdade: um proxy reverso num servidor, uma VPN ou rede overlay, um deploy de verdade. O charme do túnel é ser um comando só, sem pegada permanente; no momento em que você está escrevendo monitoramento para ele, já passou do ponto.

Resolvendo as falhas de sempre

  • Warning: remote port forwarding failed for listen port 8080 — a porta está ocupada no servidor. Muitas vezes o culpado é o seu próprio túnel anterior: o processo sshd antigo segura a porta até a conexão morta expirar. Os keepalives evitam o zumbi; -R 0:... contorna a colisão; o ExitOnForwardFailure transforma o aviso em um erro que você não deixa passar.
  • Funciona a partir do servidor, recusado de fora — a porta de escuta está no loopback do servidor. É o padrão do GatewayPorts fazendo o seu trabalho; configure-o ou coloque um proxy reverso na frente da porta.
  • O túnel conecta, mas o serviço não responde — verifique a metade local: há de fato algo escutando na porta local que você indicou? -R 8080:localhost:3000 sem nada na sua :3000 resulta em connection refused para todo visitante.
  • A própria conexão SSH não se estabelece — esse é outro problema, com a sua própria lista de verificação: connection refused e timed out, decodificados.

Quando os túneis viram mobília

O túnel reverso que você roda uma vez, você digita. O que carrega o seu home lab, a sua máquina de demonstração e o seu endpoint de webhook é um estado que você reconstrói toda manhã, depois de cada vez que o notebook dorme — e do qual perde o rastro até quinta-feira. O gerenciador de túneis salvos do Termalin mantém os encaminhamentos locais, remotos e dinâmicos presos ao host a que pertencem: inicie-os com um clique, veja num relance quais estão ativos e deixe que se restabeleçam junto com a conexão, em vez de redigitá-los a partir do histórico do shell. A lista de hosts — com chaves, hosts de salto, keepalives e túneis — sincroniza entre as suas máquinas, criptografada de ponta a ponta. E quando uma máquina fica atrás de NAT para valer, o Connector dela, só de saída, substitui por completo o túnel reverso feito à mão — sem porta de entrada e sem unidade autossh para vigiar. A linha de comando ensina o que o -R significa; um cliente evita que os túneis dos quais você depende fiquem reféns da sua memória.


O Termalin é um cliente SSH gratuito e multiplataforma, com túneis integrados, SFTP e um gerenciador de chaves — baixe o Termalin, ou veja como ele cuida das suas chaves com segurança.

Experimente em um host.

Termalin é um cliente SSH rápido para você — e para seus agentes.

Plano gratuito · 14 dias de Pro grátis · preços