Encaminhamento de Porta SSH: Tuneis Local, Remoto e Dinamico

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.

O Que e Encaminhamento Dinamico (-D)?

Conclusao: -D porta abre 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.internal resolve no servidor SSH
  • Em -R 8080:localhost:3000, localhost:3000 resolve 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 / DynamicForward na sua config e execute apenas ssh 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 -L ou -R pela direcao, e -D quando 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

Proximas Leituras