Encaminhamento de Porta SSH: Tuneis Local, Remoto e Dinamico
O Que Voce Vai Aprender
- A diferenca entre encaminhamento
-L(local),-R(remoto) e-D(dinamico) - Como acessar um banco de dados atras de um bastion, expor um app local e executar um proxy SOCKS
- Como solucionar problemas quando um tunel "nao conecta"
Resumo Rapido
- Acessar um servico remoto da sua maquina ->
-L(encaminhamento local) - Expor um servico local para um host remoto ->
-R(encaminhamento remoto) - Enviar todo o trafego de um app pelo SSH ->
-D(dinamico / SOCKS)
Premissas
- SO: Ubuntu (cliente / servidor OpenSSH)
- Voce ja consegue fazer login via SSH
- Os numeros de porta sao exemplos; adapte para sua configuracao
O Que e Encaminhamento de Porta SSH?
Conclusao: Ele cria tuneis para conexoes TCP arbitrarias dentro da sessao SSH criptografada, permitindo acessar portas que voce nao consegue alcancar diretamente, desde que consiga fazer SSH.
Servicos atras de um firewall ou dentro de uma rede privada nao podem ser alcancados diretamente de fora. Mas se voce conseguir fazer SSH, pode transportar outra conexao TCP dentro dessa sessao SSH. Isso e encaminhamento de porta (tunelamento).
Existem tres tipos. Eles diferem apenas na direcao e em qual lado escuta; a ideia e a mesma.
| Tipo | Opcao | Escuta em | Caso de uso |
|---|---|---|---|
| Local | -L |
Seu lado | Usar um servico remoto da sua maquina |
| Remoto | -R |
Remoto | Expor um servico local para o remoto |
| Dinamico | -D |
Seu lado | Enviar todo o trafego de um app pelo tunel |
Como Usar Encaminhamento Local (-L)?
Conclusao: O formato e
-L portaLocal:hostDestino:portaDestino. Conexoes na sua porta local sao encaminhadas ao destino visto pelo servidor SSH. Acessar um BD atraves de um bastion e o caso classico.
Formato basico
$ ssh -L 8080:localhost:80 user@server
Agora uma conexao 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 e resolvido do ponto de vista do servidor SSH. localhost significa o proprio servidor; outro nome significa um host que o servidor consegue alcancar.
Exemplo: acessar um BD atraves de um bastion
O banco de dados (db.internal:5432) esta atras de um bastion e nao e alcancavel diretamente da sua maquina.
$ 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 tunel (-N / -f)
Se voce nao precisa de um shell de login e quer apenas o tunel, adicione -N; para colocar em segundo plano, adicione -f.
$ ssh -fN -L 15432:db.internal:5432 user@bastion
-N: nao executar um comando remoto (somente encaminhamento)-f: ir para segundo plano apos autenticacao
Um tunel em segundo plano continua rodando. Pare-o quando terminar.
$ ps aux | grep "ssh -fN" $ kill <PID>
Como Usar Encaminhamento Remoto (-R)?
Conclusao: O formato e
-R portaRemota:hostDestino:portaDestino. O lado remoto escuta e encaminha para um destino visto pela sua maquina. Compartilhar temporariamente um servidor de desenvolvimento local e o uso comum.
Essa e a direcao reversa. Uma conexao na porta remota alcanca o destino visto pela sua maquina (a que esta executando ssh).
Formato basico
$ ssh -R 8080:localhost:3000 user@server
Uma conexao ao localhost:8080 no server e encaminhada ao seu localhost:3000. Seu servidor de desenvolvimento local (porta 3000) se torna alcancavel a partir do servidor.
O detalhe para acesso publico: GatewayPorts
Por padrao, -R escuta apenas no loopback remoto (127.0.0.1). O proprio servidor consegue alcanca-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 apos alterar: sudo systemctl reload ssh.
GatewayPorts yes expoe seu servico local para redes externas. Limite o escopo, autenticacao e duracao, e reverta tanto o tunel quanto a configuracao assim que terminar.
O Que e Encaminhamento Dinamico (-D)?
Conclusao:
-D portaabre um proxy SOCKS local. Em vez de um tunel por destino, o trafego de um app sai pelo servidor SSH.
-L e "uma porta, um destino", mas -D nao fixa um destino. Ele cria um proxy SOCKS localmente; qualquer app apontado para ele envia trafego pelo servidor SSH.
$ ssh -D 1080 user@server
Agora localhost:1080 e 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 alcancar hosts que somente o DNS do servidor SSH consegue resolver. O simples --socks5 resolve localmente.
Por Que Meu Tunel Nao Conecta?
Conclusao: A maioria das falhas e por conflito de porta, mal-entendido sobre onde o nome de destino e resolvido, ou configuracoes de exposicao 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) ja esta em uso. Use outra porta ou encontre o processo que a esta ocupando.
$ ss -tlnp | grep :8080
channel ... open failed: connect failed
O tunel esta ativo, mas o servidor SSH nao consegue alcancar o destino. Verifique o host de destino, porta e alcancabilidade a partir do servidor.
$ ssh user@server $ nc -vz db.internal 5432
-R funciona mas hosts externos nao conseguem conectar
Geralmente e o GatewayPorts mencionado acima. Mesmo -R 0.0.0.0:8080:... nao vai ajudar se a configuracao do servidor ainda estiver em no.
Confusao 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 maquina
Quando "resolve localmente mas nao conecta", voce provavelmente confundiu o lado de resolucao.
Como Salvar Tuneis no ~/.ssh/config?
Conclusao: Em vez de opcoes 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 dai, basta nomear o host.
$ ssh -fN db-tunnel
Para mais sobre o arquivo de configuracao, veja Dicas de SSH config.
Resumo e Modelos Seguros
Conclusao: Escolha
-Lou-Rpela direcao, e-Dquando o destino nao e fixo. Nao deixe tuneis 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