O SSH tunneling no Linux cria canais criptografados que encaminham tráfego de rede entre máquinas, permitindo acessar serviços protegidos por firewalls, criptografar protocolos normalmente desprotegidos e criar caminhos seguros em redes não confiáveis. Seja para acessar um banco de dados em uma rede privada, expor um servidor de desenvolvimento local para um colega ou rotear o tráfego do navegador por um ponto de saída confiável, o port forwarding SSH resolve todos esses casos com ferramentas já instaladas em qualquer sistema Linux. Este guia cobre os três tipos de encaminhamento com configurações testadas em ambientes de produção.

Pré-requisitos

  • Duas máquinas Linux com acesso SSH (ou um cliente Linux e qualquer servidor SSH)
  • OpenSSH client instalado localmente (ssh -V para verificar)
  • OpenSSH server em execução na máquina remota (sshd)
  • Conhecimento básico de portas TCP e redes cliente-servidor
  • Autenticação por chave SSH configurada (recomendado — veja o artigo relacionado)

Entendendo os Tipos de Túnel SSH

O SSH suporta três modos distintos de encaminhamento, cada um adequado a um caso de uso diferente:

TipoFlagDireçãoCaso de Uso
Encaminhamento local-LMáquina local → destino remotoAcessar banco de dados remoto, painel web ou serviço
Encaminhamento remoto-RServidor remoto → máquina localExpor servidor de desenvolvimento local, permitir acesso remoto a serviços locais
Encaminhamento dinâmico-DProxy SOCKS local → qualquer destino via remotoNavegação segura, roteamento de todo o tráfego pelo SSH

Os três criptografam o tráfego de ponta a ponta entre o cliente e o servidor SSH. O tráfego entre o servidor SSH e o destino final não é criptografado pelo SSH — ele percorre a rede local do servidor.

Encaminhamento de Porta Local (-L)

O encaminhamento local é o tipo mais comum. Ele vincula uma porta na sua máquina local e envia o tráfego pelo túnel SSH até um destino específico acessível a partir do servidor remoto.

Sintaxe

ssh -L [bind_address:]local_port:destination:dest_port user@ssh_server

Exemplo: Acessar um Banco de Dados Remoto

Você tem um banco de dados PostgreSQL em db.internal na porta 5432, acessível apenas a partir do servidor de aplicação app.example.com. Seu laptop não consegue alcançar db.internal diretamente.

# Encaminhar porta local 5432 para db.internal:5432 através de app.example.com
ssh -L 5432:db.internal:5432 admin@app.example.com

Agora conecte ao banco de dados localmente:

psql -h localhost -p 5432 -U myuser mydb

O caminho do tráfego: laptop:5432 → túnel SSH → app.example.com → db.internal:5432

Exemplo: Acessar uma Interface Web Remota

Um painel de monitoramento está em http://monitor.internal:3000 atrás de um firewall:

# Encaminhar porta local 8080 para o painel remoto
ssh -L 8080:monitor.internal:3000 admin@jumpbox.example.com

# Abrir no navegador
# http://localhost:8080

Túnel em Segundo Plano (Sem Shell)

Use -f -N para executar o túnel em segundo plano sem abrir um shell remoto:

# -f = executar em background após autenticação
# -N = sem comando remoto (somente túnel)
ssh -f -N -L 8080:monitor.internal:3000 admin@jumpbox.example.com

Para encerrar um túnel em segundo plano, encontre e finalize o processo:

ps aux | grep 'ssh -f -N -L'
kill <PID>

Vincular a Todas as Interfaces

Por padrão, -L vincula apenas ao localhost. Para permitir que outras máquinas na sua rede usem o túnel:

# Vincular a todas as interfaces (0.0.0.0)
ssh -L 0.0.0.0:8080:monitor.internal:3000 admin@jumpbox.example.com

# Ou vincular a uma interface específica
ssh -L 192.168.1.100:8080:monitor.internal:3000 admin@jumpbox.example.com

Aviso de segurança: Vincular a 0.0.0.0 expõe o túnel para toda a sua rede local. Faça isso apenas em redes confiáveis.

Encaminhamento de Porta Remoto (-R)

O encaminhamento remoto funciona na direção oposta — ele vincula uma porta no servidor remoto e encaminha o tráfego de volta para a sua máquina local.

Sintaxe

ssh -R [bind_address:]remote_port:destination:dest_port user@ssh_server

Exemplo: Expor um Servidor de Desenvolvimento Local

Você está desenvolvendo uma aplicação web em localhost:3000 e quer que um colega no servidor remoto possa acessá-la:

# Vincular porta 9000 no servidor remoto, encaminhando para sua porta local 3000
ssh -R 9000:localhost:3000 admin@remote.example.com

Agora qualquer pessoa em remote.example.com pode acessar seu servidor de desenvolvimento local em http://localhost:9000.

Exemplo: Fornecer Acesso Remoto a um Serviço Local

Sua máquina no escritório executa um serviço na porta 8443 e você quer acessá-la de casa por meio de um servidor na nuvem:

# A partir da máquina do escritório:
ssh -R 8443:localhost:8443 user@cloud-server.example.com

De casa, conecte-se ao servidor na nuvem via SSH e acesse localhost:8443.

Permitindo Conexões Externas

Por padrão, as portas de encaminhamento remoto vinculam ao localhost no servidor remoto. Para permitir acesso externo, o servidor SSH deve ter GatewayPorts habilitado:

# No servidor SSH, edite /etc/ssh/sshd_config:
GatewayPorts yes        # Permite vinculação a todas as interfaces
# ou
GatewayPorts clientspecified  # Deixa o cliente escolher o endereço de vinculação

Em seguida, reinicie o sshd e especifique o endereço de vinculação:

ssh -R 0.0.0.0:9000:localhost:3000 admin@remote.example.com

Encaminhamento Dinâmico (-D) — Proxy SOCKS

O encaminhamento dinâmico cria um proxy SOCKS5 local. Qualquer aplicação configurada para usar esse proxy roteará todo o seu tráfego pelo túnel SSH, com o servidor remoto atuando como ponto de saída.

Sintaxe

ssh -D [bind_address:]port user@ssh_server

Exemplo: Navegação Web Segura

Você está em uma rede Wi-Fi não confiável e quer rotear todo o tráfego do navegador pelo seu servidor doméstico:

# Criar um proxy SOCKS5 na porta local 1080
ssh -D 1080 -f -N user@home-server.example.com

Em seguida, configure seu navegador:

  • Firefox: Configurações → Configurações de Rede → Proxy manual → Host SOCKS: localhost, Porta: 1080, SOCKS v5. Marque “Usar DNS via proxy SOCKS5”.
  • Chrome (linha de comando): google-chrome --proxy-server="socks5://localhost:1080"
  • Em todo o sistema (variável de ambiente): export ALL_PROXY=socks5://localhost:1080

Exemplo: Rotear Ferramentas de Linha de Comando pelo Proxy

# Usar com curl
curl --proxy socks5h://localhost:1080 https://ifconfig.me

# Usar com git
git -c http.proxy=socks5h://localhost:1080 clone https://github.com/user/repo.git

# O 'h' em socks5h significa que a resolução DNS ocorre no lado remoto

Importante: Use socks5h:// (com o h) para resolver o DNS pelo proxy. O socks5:// simples resolve o DNS localmente, o que vaza suas consultas DNS na rede local.

Tornando Túneis Persistentes com autossh

Túneis SSH morrem quando a conexão cai (interrupção de rede, suspensão do laptop, reinicialização do servidor). O autossh monitora a conexão e reconecta automaticamente.

Instalação

# Debian / Ubuntu
sudo apt install autossh

# RHEL / Fedora
sudo dnf install autossh

# Arch Linux
sudo pacman -S autossh

Uso

# Encaminhamento local persistente com autossh
autossh -M 0 -f -N -L 5432:db.internal:5432 admin@jumpbox.example.com

# Proxy SOCKS persistente
autossh -M 0 -f -N -D 1080 user@home-server.example.com

# Encaminhamento remoto persistente
autossh -M 0 -f -N -R 9000:localhost:3000 admin@remote.example.com

A flag -M 0 desativa a porta de monitoramento interna do autossh e usa o mecanismo de keepalive do próprio SSH (mais confiável e simples). Combine-a com keepalives SSH na sua configuração.

Executar como Serviço systemd

Para túneis que devem sobreviver a reinicializações, crie uma unit systemd:

# /etc/systemd/system/ssh-tunnel-db.service
[Unit]
Description=SSH Tunnel to Database
After=network-online.target
Wants=network-online.target

[Service]
User=tunneluser
ExecStart=/usr/bin/autossh -M 0 -N -L 5432:db.internal:5432 admin@jumpbox.example.com
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now ssh-tunnel-db.service
sudo systemctl status ssh-tunnel-db.service

SSH Config para Túneis Reutilizáveis

Em vez de digitar comandos longos, defina os túneis em ~/.ssh/config:

Host db-tunnel
    HostName jumpbox.example.com
    User admin
    LocalForward 5432 db.internal:5432
    ServerAliveInterval 60
    ServerAliveCountMax 3
    IdentityFile ~/.ssh/id_ed25519

Host socks-proxy
    HostName home-server.example.com
    User myuser
    DynamicForward 1080
    ServerAliveInterval 60
    ServerAliveCountMax 3
    IdentityFile ~/.ssh/id_ed25519

Host expose-dev
    HostName remote.example.com
    User admin
    RemoteForward 9000 localhost:3000
    ServerAliveInterval 60
    ServerAliveCountMax 3

Agora use-os pelo nome:

ssh -f -N db-tunnel
ssh -f -N socks-proxy
ssh -f -N expose-dev

Comparando SSH Tunneling com Alternativas

RecursoSSH TunnelingWireGuard VPNCloudflare Tunnelngrok
CriptografiaSim (SSH)Sim (WireGuard)Sim (TLS)Sim (TLS)
Requer software no servidorsshd (ubíquo)Módulo kernel WireGuardDaemon cloudflaredAgente ngrok
Encaminhamento por portaSimNão (rede completa)SimSim
Proxy SOCKSSim (-D)NãoNãoNão
Overhead de desempenhoModerado (TCP-sobre-TCP)Baixo (UDP, kernel-space)BaixoBaixo
Reconexão persistenteCom autosshEmbutidoEmbutidoEmbutido
CustoGratuitoGratuitoPlano gratuito disponívelPlano gratuito disponível
Ideal paraTúneis rápidos ad-hoc, acesso a portas específicasAcesso de rede completo ou site-to-siteExpor serviços à internetDemos rápidos, webhooks

Use SSH tunneling quando precisar acessar rapidamente uma ou duas portas específicas e já tiver acesso SSH — sem necessidade de software adicional. Migre para WireGuard quando precisar de acesso completo à rede ou alta taxa de transferência. Use Cloudflare Tunnels ou ngrok quando precisar expor serviços a usuários externos com URLs públicas.

Solução de Problemas

Túnel conecta mas o tráfego não flui

# Verificar se o túnel está ouvindo
ss -tlnp | grep <local_port>

# Verificar se o destino é acessível a partir do servidor SSH
ssh admin@jumpbox.example.com "nc -zv db.internal 5432"

Se ss mostrar a porta ouvindo mas as conexões travarem, o serviço de destino pode estar rejeitando conexões do IP do servidor SSH. Verifique as regras de firewall no host de destino.

”bind: Address already in use"

# Encontrar o que está usando a porta
sudo ss -tlnp | grep <port>

# Encerrar o túnel antigo ou escolher uma porta local diferente
ssh -L 15432:db.internal:5432 admin@jumpbox.example.com

"channel 3: open failed: administratively prohibited”

O servidor SSH desabilitou o encaminhamento TCP. O administrador do servidor precisa definir em /etc/ssh/sshd_config:

AllowTcpForwarding yes
# ou apenas para encaminhamento local:
AllowTcpForwarding local

Túnel desconecta após período de inatividade

Adicione keepalives ao seu ~/.ssh/config:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

Isso envia um keepalive a cada 60 segundos e desconecta após 3 respostas perdidas (3 minutos). Impede que dispositivos NAT e firewalls com estado encerrem a conexão TCP ociosa.

Porta de encaminhamento remoto não acessível externamente

Verifique se GatewayPorts está habilitado no servidor SSH:

grep GatewayPorts /etc/ssh/sshd_config

Se estiver como no ou ausente, as portas de encaminhamento remoto vinculam apenas ao 127.0.0.1 no servidor.

Considerações de Segurança

  • Restringir encaminhamento no authorized_keys: Limite o que uma chave específica pode fazer:

    no-agent-forwarding,no-X11-forwarding,permitopen="db.internal:5432" ssh-ed25519 AAAA...

    Essa chave só pode criar túneis para db.internal:5432.

  • Desabilitar encaminhamento para usuários específicos: Em /etc/ssh/sshd_config:

    Match User restricteduser
        AllowTcpForwarding no
  • Desempenho TCP-sobre-TCP: Os túneis SSH sofrem com o problema de TCP-sobre-TCP — as pilhas TCP interna e externa lidam com retransmissões de forma independente, o que pode causar backoff exponencial em conexões com perda de pacotes. Para tráfego de alta taxa de transferência ou sensível à latência, use WireGuard.

  • Auditar o uso de túneis: Monitore os túneis ativos em seus servidores:

    # Mostrar todos os port forwards SSH em uso
    sudo ss -tlnp | grep sshd
    # Mostrar sessões SSH conectadas com encaminhamento
    sudo lsof -i -n | grep ssh | grep LISTEN

Resumo

  • Encaminhamento local (-L) traz serviços remotos para sua máquina local — o caso de uso mais comum para acessar bancos de dados, painéis e APIs atrás de firewalls
  • Encaminhamento remoto (-R) expõe serviços locais em um servidor remoto — útil para compartilhar ambientes de desenvolvimento e fornecer acesso externo a ferramentas internas
  • Encaminhamento dinâmico (-D) cria um proxy SOCKS5 — roteia o tráfego de qualquer aplicação pelo túnel SSH para navegação segura em redes não confiáveis
  • Use autossh para túneis persistentes que sobrevivem a interrupções de rede, e serviços systemd para túneis que devem sobreviver a reinicializações
  • Arquivos de configuração SSH (~/.ssh/config) eliminam flags repetitivas na linha de comando e tornam os túneis reutilizáveis com nomes simples
  • Adicione keepalives (ServerAliveInterval 60) para impedir que firewalls encerrem conexões de túnel ociosas

Artigos Relacionados