Encaminhamento de Porta SSH: Túneis Local, Remoto e Dinâmico
O Que Você Vai Aprender
- A diferença entre encaminhamento
-L(local),-R(remoto) e-D(dinâmico) - Como acessar um banco de dados atrás de um bastion, expor um app local e executar um proxy SOCKS
- Como solucionar problemas quando um túnel "não conecta"
Resumo Rápido
- Acessar um serviço remoto da sua máquina ->
-L(encaminhamento local) - Expor um serviço local para um host remoto ->
-R(encaminhamento remoto) - Enviar todo o tráfego de um app pelo SSH ->
-D(dinâmico / SOCKS)
Premissas
- SO: Ubuntu (cliente / servidor OpenSSH)
- Você já consegue fazer login via SSH
- Os números de porta são exemplos; adapte para sua configuração
O Que é Encaminhamento de Porta SSH?
Conclusão: Ele cria túneis para conexões TCP arbitrárias dentro da sessão SSH criptografada, permitindo acessar portas que você não consegue alcançar diretamente, desde que consiga fazer SSH.
Serviços atrás de um firewall ou dentro de uma rede privada não podem ser alcançados diretamente de fora. Mas se você conseguir fazer SSH, pode transportar outra conexão TCP dentro dessa sessão SSH. Isso é encaminhamento de porta (tunelamento).
Existem três tipos. Eles diferem apenas na direção e em qual lado escuta; a ideia é a mesma.
| Tipo | Opção | Escuta em | Caso de uso |
|---|---|---|---|
| Local | -L |
Seu lado | Usar um serviço remoto da sua máquina |
| Remoto | -R |
Remoto | Expor um serviço local para o remoto |
| Dinâmico | -D |
Seu lado | Enviar todo o tráfego de um app pelo túnel |
Como Usar Encaminhamento Local (-L)?
Conclusão: O formato é
-L portaLocal:hostDestino:portaDestino. Conexões na sua porta local são encaminhadas ao destino visto pelo servidor SSH. Acessar um BD através de um bastion é o caso clássico.
Formato básico
$ ssh -L 8080:localhost:80 user@server
Agora uma conexão ao seu localhost:8080 alcanca localhost:80 visto pelo server. Abra http://localhost:8080 no navegador e funciona como se estivesse acessando a porta 80 do servidor.
O hostDestino é resolvido do ponto de vista do servidor SSH. localhost significa o próprio servidor; outro nome significa um host que o servidor consegue alcançar.
Exemplo: acessar um BD através de um bastion
O banco de dados (db.internal:5432) está atrás de um bastion e não é alcançável diretamente da sua máquina.
$ ssh -L 15432:db.internal:5432 user@bastion
Em outro terminal, trate sua porta local 15432 como se fosse o BD real.
$ psql -h localhost -p 15432 -U dbuser appdb
Somente túnel (-N / -f)
Se você não precisa de um shell de login e quer apenas o túnel, adicione -N; para colocar em segundo plano, adicione -f.
$ ssh -fN -L 15432:db.internal:5432 user@bastion
-N: não executar um comando remoto (somente encaminhamento)-f: ir para segundo plano após autenticação
Um túnel em segundo plano continua rodando. Pare-o quando terminar.
$ ps aux | grep "ssh -fN" $ kill <PID>
Como Usar Encaminhamento Remoto (-R)?
Conclusão: O formato é
-R portaRemota:hostDestino:portaDestino. O lado remoto escuta e encaminha para um destino visto pela sua máquina. Compartilhar temporariamente um servidor de desenvolvimento local é o uso comum.
Essa é a direção reversa. Uma conexão na porta remota alcanca o destino visto pela sua máquina (a que está executando ssh).
Formato básico
$ ssh -R 8080:localhost:3000 user@server
Uma conexão ao localhost:8080 no server é encaminhada ao seu localhost:3000. Seu servidor de desenvolvimento local (porta 3000) se torna alcançável a partir do servidor.
O detalhe para acesso público: GatewayPorts
Por padrão, -R escuta apenas no loopback remoto (127.0.0.1). O próprio servidor consegue alcançá-lo, mas nada fora do servidor consegue. Para escutar em todas as interfaces, o /etc/ssh/sshd_config do servidor precisa de:
GatewayPorts yes
Recarregue após alterar: sudo systemctl reload ssh.
GatewayPorts yes expõe seu serviço local para redes externas. Limite o escopo, autenticação e duração, e reverta tanto o túnel quanto a configuração assim que terminar.
O Que é Encaminhamento Dinâmico (-D)?
Conclusão:
-D portaabre um proxy SOCKS local. Em vez de um túnel por destino, o tráfego de um app sai pelo servidor SSH.
-L é "uma porta, um destino", mas -D não fixa um destino. Ele cria um proxy SOCKS localmente; qualquer app apontado para ele envia tráfego pelo servidor SSH.
$ ssh -D 1080 user@server
Agora localhost:1080 é um proxy SOCKS5. Aponte seu navegador ou curl para ele.
$ curl --socks5-hostname localhost:1080 https://example.com
--socks5-hostname resolve nomes no lado do proxy. Use-o para alcançar hosts que somente o DNS do servidor SSH consegue resolver. O simples --socks5 resolve localmente.
Por Que Meu Túnel Não Conecta?
Conclusão: A maioria das falhas é por conflito de porta, mal-entendido sobre onde o nome de destino é resolvido, ou configurações de exposição remota ausentes. O texto do erro aponta qual.
bind: Address already in use
A porta de escuta no seu lado (ou no remoto, para -R) já está em uso. Use outra porta ou encontre o processo que a está ocupando.
$ ss -tlnp | grep :8080
channel ... open failed: connect failed
O túnel está ativo, mas o servidor SSH não consegue alcançar o destino. Verifique o host de destino, porta e alcançabilidade a partir do servidor.
$ ssh user@server $ nc -vz db.internal 5432
-R funciona mas hosts externos não conseguem conectar
Geralmente é o GatewayPorts mencionado acima. Mesmo -R 0.0.0.0:8080:... não vai ajudar se a configuração do servidor ainda estiver em no.
Confusão comum: qual lado resolve o nome de destino?
- Em
-L 15432:db.internal:5432,db.internalresolve no servidor SSH - Em
-R 8080:localhost:3000,localhost:3000resolve na sua máquina
Quando "resolve localmente mas não conecta", você provavelmente confundiu o lado de resolução.
Como Salvar Túneis no ~/.ssh/config?
Conclusão: Em vez de opções longas toda vez, coloque
LocalForward/RemoteForward/DynamicForwardna sua config e execute apenasssh host.
Host db-tunnel
HostName bastion.example.com
User user
LocalForward 15432 db.internal:5432
Host socks
HostName server.example.com
User user
DynamicForward 1080
A partir daí, basta nomear o host.
$ ssh -fN db-tunnel
Para mais sobre o arquivo de configuração, veja Dicas de SSH config.
Resumo e Modelos Seguros
Conclusão: Escolha
-Lou-Rpela direção, e-Dquando o destino não é fixo. Não deixe túneis abertos; pare-os quando terminar.
Modelos para copiar e colar
# Encaminhamento local (BD remoto para sua maquina) ssh -fN -L 15432:db.internal:5432 user@bastion # Encaminhamento remoto (seu servidor dev para um host remoto) ssh -R 8080:localhost:3000 user@server # Encaminhamento dinamico (proxy SOCKS) ssh -D 1080 user@server