termal.in

← Blog

Encaminhamento de portas SSH, explicado: túneis locais, remotos e dinâmicos

· Termalin Team sshport-forwardingtunnelingtutorial

O encaminhamento de portas SSH é um daqueles recursos que as pessoas copiam do Stack Overflow, fazem funcionar uma vez e nunca entendem direito — então, na próxima vez em que precisam dele, voltam a adivinhar qual usar entre -L, -R e -D. As três flags não são difíceis; só têm nomes ruins. Aqui está o único modelo mental que as torna óbvias, um exemplo de cada uma e as flags e armadilhas que decidem se o túnel sobrevive à tarde.

A única pergunta que escolhe a flag

Todo túnel SSH abre uma porta de escuta em uma máquina e, discretamente, envia tudo o que chega nela para algum lugar alcançável a partir da outra máquina. Então a única pergunta é: qual lado abre a porta à qual você conecta?

  • -L (local) — a porta abre na sua máquina. Você conecta localmente; o tráfego sai pelo lado do servidor.
  • -R (remoto) — a porta abre no servidor. Alguém conecta lá; o tráfego sai pelo seu lado.
  • -D (dinâmico) — a porta abre na sua máquina, mas é um proxy SOCKS: o destino é decidido por conexão, não fixado de antemão.

Todo o resto é detalhe. Mantenha “qual lado abre a porta” na cabeça e você nunca mais vai pegar a flag errada.

Encaminhamento local (-L) — trazer um serviço remoto para o localhost

O mais comum. Um banco de dados, um painel interno, uma interface de métricas — algo vinculado a 127.0.0.1 no servidor, ou em uma máquina que só o servidor alcança. Você o quer no seu notebook como se fosse local.

ssh -L 5432:localhost:5432 deploy@db.example.com

Leia da esquerda para a direita: abra 5432 na minha máquina e encaminhe tudo o que chega para localhost:5432 como visto a partir do servidor. Agora psql -h 127.0.0.1 no seu notebook conversa com o Postgres do servidor (em inglês) — pela conexão SSH criptografada, sem expor o banco de dados à rede.

O host do meio é resolvido no lado do servidor, e é isso que torna o recurso poderoso:

# reach a database that only the bastion can see
ssh -L 5432:10.0.0.9:5432 deploy@bastion.example.com

Aqui 10.0.0.9 é um endereço privado que o seu notebook não consegue rotear — mas o bastion consegue. O túnel faz a ponte.

Encaminhamento remoto (-R) — expor a sua máquina ao lado do servidor

A imagem espelhada, e a que as pessoas acham invertida (ela tem o próprio mergulho — túneis SSH reversos). A porta abre no servidor; as conexões a ela voltam a sair na sua ponta. Dois usos clássicos:

# let the server (or its network) reach a dev server running on your laptop
ssh -R 8080:localhost:3000 deploy@app.example.com

Agora tudo que bate em localhost:8080 no servidor é encaminhado para localhost:3000 no seu notebook — útil para mostrar a um colega que está na máquina o seu trabalho em andamento, ou deixar um serviço remoto chamar de volta algo que só você está rodando.

Esse também é o truque para alcançar uma máquina presa atrás de NAT, sem acesso de entrada: faça com que ela abra um túnel reverso de saída até um servidor que você controla, e você conecta pelo servidor. A máquina que não consegue aceitar conexões faz a de saída, em vez disso.

Uma ressalva: por padrão o servidor vincula a porta encaminhada a localhost, então só o próprio servidor pode usá-la. Para deixar outras máquinas da rede do servidor a alcançarem, o sshd_config do servidor precisa de GatewayPorts yes (ou clientspecified) — uma configuração do lado do servidor, não algo que você possa forçar pelo cliente.

Encaminhamento dinâmico (-D) — um proxy SOCKS em uma flag

O -L encaminha para um único destino fixo. O -D abre, em vez disso, um proxy SOCKS, então o destino é escolhido por requisição:

ssh -D 1080 deploy@jump.example.com

Aponte o seu navegador (ou curl --socks5 127.0.0.1:1080) para 127.0.0.1:1080 e toda requisição é roteada a partir do servidor. É o jeito rápido de navegar por uma rede interna, testar como um serviço aparece a partir do IP de um datacenter, ou alcançar um punhado de hosts internos sem um -L para cada um.

As flags que o tornam utilizável

Um comando de túnel pelado também abre um shell que você não quer e morre no momento em que você o fecha. Na prática:

ssh -N -L 5432:localhost:5432 deploy@db.example.com
  • -N — não rode um comando remoto. Você só quer o túnel, não um shell.
  • -f — joga o processo para segundo plano depois de conectar (use com o -N).
  • -o ExitOnForwardFailure=yes — se a porta não puder ser vinculada (já em uso, permissão negada), falhe ruidosamente em vez de conectar assim mesmo e, em silêncio, não encaminhar nada.
  • Keepalives — um túnel de longa duração morre com os timeouts de ociosidade sem o ServerAliveInterval 30. Acrescente-o ou o túnel cai no momento em que você para de usá-lo.

Torne-o permanente no ssh_config

Tudo o que você passaria com -L/-R/-D tem uma diretiva de configuração, então um host salvo carrega os próprios túneis:

Host db-tunnel
    HostName db.example.com
    User deploy
    LocalForward 5432 localhost:5432
    ServerAliveInterval 30
    RequestTTY no

Agora ssh -N db-tunnel traz o banco de dados para 127.0.0.1:5432 sem flags para lembrar. RemoteForward e DynamicForward funcionam da mesma forma. (Mais sobre o próprio arquivo de configuração no guia do ~/.ssh/config (em inglês).)

Três armadilhas

  • O endereço de bind importa. -L 5432:... escuta apenas em 127.0.0.1. Para deixar outros dispositivos da sua LAN usarem o túnel, prefixe um endereço de bind: -L 0.0.0.0:5432:... — e entenda que você acabou de expô-lo à sua rede local.
  • “Address already in use” significa que a porta local está ocupada (muitas vezes um túnel anterior que não encerrou). Escolha outra porta local ou mate o antigo; o ExitOnForwardFailure transforma a falha silenciosa em um erro que você de fato vai notar.
  • O host do meio é resolvido do lado de lá. localhost em -L a:localhost:b significa o localhost do servidor, não o seu. Inverter isso é o erro mais comum de encaminhamento de portas.

Quando o túnel não vincula

Se o comando falha com bind: Address already in use ou bind: Permission denied, a porta de escuta nunca abriu — percorra a lista curta. Já em uso: algo segura a porta, muitas vezes o túnel esquecido de ontem — o ss -tlnp nomeia o processo, depois escolha outra porta ou mate o antigo. Permissão negada localmente normalmente significa uma porta privilegiada: qualquer coisa abaixo de 1024 precisa de root, então escute na 8443 em vez da 443. Na ponta remota (-R), o servidor tem veto: AllowTcpForwarding no no sshd_config bloqueia o encaminhamento por completo, e sem o GatewayPorts a porta de escuta remota vincula só a localhost, qualquer que seja o endereço de bind que você pediu. E em hosts endurecidos da família RHEL, o SELinux pode negar o bind ao sshd mesmo quando a configuração permite — confira o log de auditoria antes de culpar o seu comando.

Quando fazer malabarismo com túneis à mão cansa

O encaminhamento é uma ótima primitiva, e todo desenvolvedor deveria saber as três flags de cor. A fricção aparece depois: você mantém um rascunho de comandos ssh -N -L ... (em inglês), você os roda de novo depois de cada vez que o notebook dorme, você esquece qual porta local mapeia para qual serviço e não consegue dizer num relance se um túnel sequer continua de pé.

É aí que um cliente com um gerenciador de túneis de verdade ajuda. O Termalin mantém os encaminhamentos locais, remotos e dinâmicos presos ao host como configuração salva — inicie-os com um clique, veja quais estão ativos e deixe que se restabeleçam junto com a conexão, em vez de redigitar o comando. A mesma lista de hosts (com suas chaves, hosts de salto e keepalives) sincroniza entre as suas máquinas, criptografada de ponta a ponta, e cada servidor é verificado na primeira conexão. A linha de comando ensina como os túneis funcionam; um cliente evita que você os reconstrua à mão toda manhã.

De qualquer forma, o modelo é o truque inteiro: decida qual lado abre a porta, e o resto da flag se escreve sozinho.


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