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 -Vpara 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:
| Tipo | Flag | Direção | Caso de Uso |
|---|---|---|---|
| Encaminhamento local | -L | Máquina local → destino remoto | Acessar banco de dados remoto, painel web ou serviço |
| Encaminhamento remoto | -R | Servidor remoto → máquina local | Expor servidor de desenvolvimento local, permitir acesso remoto a serviços locais |
| Encaminhamento dinâmico | -D | Proxy SOCKS local → qualquer destino via remoto | Navegaçã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
| Recurso | SSH Tunneling | WireGuard VPN | Cloudflare Tunnel | ngrok |
|---|---|---|---|---|
| Criptografia | Sim (SSH) | Sim (WireGuard) | Sim (TLS) | Sim (TLS) |
| Requer software no servidor | sshd (ubíquo) | Módulo kernel WireGuard | Daemon cloudflared | Agente ngrok |
| Encaminhamento por porta | Sim | Não (rede completa) | Sim | Sim |
| Proxy SOCKS | Sim (-D) | Não | Não | Não |
| Overhead de desempenho | Moderado (TCP-sobre-TCP) | Baixo (UDP, kernel-space) | Baixo | Baixo |
| Reconexão persistente | Com autossh | Embutido | Embutido | Embutido |
| Custo | Gratuito | Gratuito | Plano gratuito disponível | Plano gratuito disponível |
| Ideal para | Túneis rápidos ad-hoc, acesso a portas específicas | Acesso de rede completo ou site-to-site | Expor serviços à internet | Demos 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
autosshpara 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