Voltar às atualizações
New releaseAug 20, 2026

sshroute v0.2.11

Roteador SSH consciente da rede - roteia conexões para diferentes IPs/portas/chaves/hosts de salto com base na VPN ou rede ativa

Compartilhar

sshroute

CICódigoOpenSpecSegurança
CI
Release
OpenSpec Badge
Scorecard
Latest Release
codecov
Go Report Card
Go Reference
Specs
Requirements
Tasks
Open Changes
OpenSSF Scorecard
CII Best Practices
License: Apache 2.0

Roteador SSH ciente de rede. Detecta sua rede ativa ou VPN e seleciona automaticamente o host, porta, arquivo de identidade e host de salto corretos para cada conexão SSH — sem tocar no ~/.ssh/config.

Como funciona

Defina cada host lógico uma vez com um perfil default e substituições opcionais por rede. Em cada conexão, o sshroute detecta em qual rede você está (VPN, LAN do escritório, peer WireGuard, etc.) e resolve os parâmetros SSH corretos antes de passar para o /usr/bin/ssh real.

ssh myserver
  → sshroute detecta: corp-vpn está ativo
  → resolve: 10.100.0.50:2222 via bastion.corp.internal
  → exec /usr/bin/ssh -p 2222 -i ~/.ssh/corp_key -J bastion.corp.internal 10.100.0.50

Por que sshroute?

Para donos de homelab

Seu laboratório provavelmente tem pelo menos duas realidades: você está em casa na LAN, ou está fora e acessa via WireGuard ou outra VPN. O problema é que o ~/.ssh/config não sabe em qual você está — então você acaba com apelidos separados (server-lan, server-vpn), ou um host de salto que só funciona metade do tempo, ou você simplesmente memoriza IPs.

O sshroute resolve isso detectando sua rede atual antes de cada conexão. Quando a interface WireGuard está ativa e a rota do peer existe, ele conecta diretamente ao IP do túnel. Quando você está na LAN, ele usa o endereço local. Quando nenhum é alcançável, ele recai para o nome de host público. Um apelido, três realidades, zero troca manual.

Ele também intercepta SSH de forma transparente — git push, rsync, scp passam automaticamente por ele assim que você configura o modo sombra. Sem wrappers, sem funções de shell, sem pensar.

Para ambientes corporativos

Redes empresariais são piores. Você tem a internet pública, talvez uma VPN site-to-site, talvez uma VPN pessoal com split-tunnel, e dentro disso você tem diferentes hosts de salto dependendo de qual ambiente está mirando — dev, staging, produção, cada um com seu bastião e chave. Manter isso correto no ~/.ssh/config significa ou um arquivo enorme que quebra quando a infra muda, ou você escreve um script que cada pessoa da equipe mantém de forma diferente.

O sshroute permite que você defina a lógica de roteamento de forma declarativa, mantenha-a em um arquivo YAML versionado e compartilhe com a equipe. A mesma configuração funciona para todos — a rede correta é detectada automaticamente com base em quais interfaces ou rotas estão ativas em cada máquina. Chaves, portas, usuários e hosts de salto são resolvidos sem que o usuário precise pensar nisso.

Como se compara

Funcionalidade~/.ssh/configSomente WireGuardTeleport / Boundarysshroute
Detecta sua rede atual
Escolhe o melhor caminho automaticamente
Recai em caso de falha de conexão
Reconexão automática + re-roteamento ao cair⚠️ túnel faz roaming⚠️ via proxy fixo
Um comando por host, qualquer local⚠️ VPN precisa estar ativa
Tamanho da config para 10 hosts × 4 caminhos📄 ~600 linhas📄 ~600 linhas + config VPN📄 config no servidor📄 ~60 linhas
Dispositivos móveis em roaming⚠️ apelidos manuais⚠️ VPN necessária
Encadeamento automático de host de salto⚠️ -J manual➖ n/a
Funciona com scp / rsync / git / Ansible⚠️ parcial
Sem instalação no servidor nos alvos
Sem servidor de autenticação ou daemon para executar
Sem agente cliente
Código aberto, totalmente auto-hospedado⚠️ open-core

Teleport e Boundary são uma categoria diferente — eles adicionam controle de acesso, logs de auditoria e autenticação baseada em certificado sobre o roteamento. Se é isso que você precisa, use-os. O sshroute é para quando você quer a inteligência de roteamento sem a sobrecarga operacional de executar um servidor de autenticação central.

Instalação

Download do binário

Baixe a versão mais recente em GitHub Releases. Binários estão disponíveis para Linux, macOS e Android em AMD64 e ARM64.

Instalação via Go

go install github.com/thereisnotime/sshroute@latest

Android (Termux)

Baixe o pacote android_arm64 do GitHub Releases, extraia e coloque o binário em ~/.local/bin:

mkdir -p ~/.local/bin
curl -Lo "$TMPDIR/sshroute.tar.gz" \
  https://github.com/thereisnotime/sshroute/releases/latest/download/sshroute_android_arm64.tar.gz
tar -xzf "$TMPDIR/sshroute.tar.gz" -C ~/.local/bin sshroute
chmod +x ~/.local/bin/sshroute

Adicione ~/.local/bin ao seu PATH no ~/.bashrc ou ~/.profile se ainda não estiver:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Alternativamente, compile a partir do código-fonte com o Go do Termux. Como a toolchain oficial do Go não publica binários android/arm64, defina GOTOOLCHAIN=local para usar o que o Termux fornece:

GOTOOLCHAIN=local go install github.com/thereisnotime/sshroute@latest

Após instalar, defina o caminho do binário SSH, já que o Termux não tem /usr/bin/ssh:

# ~/.config/sshroute/config.yaml
ssh_binary: /data/data/com.termux/files/usr/bin/ssh

Ou via variável de ambiente: export SSHROUTE_SSH=$(which ssh)

Docker

docker run --rm -v ~/.config/sshroute:/root/.config/sshroute \
  ghcr.io/thereisnotime/sshroute network

Podman

podman run --rm -v ~/.config/sshroute:/root/.config/sshroute \
  ghcr.io/thereisnotime/sshroute network

Em sistemas com SELinux ativado (Fedora, RHEL, etc.) adicione :Z ao flag de volume:

podman run --rm -v ~/.config/sshroute:/root/.config/sshroute:Z \
  ghcr.io/thereisnotime/sshroute network

Modo sombra (substituto transparente do SSH)

Instale o sshroute como ssh antes no seu $PATH. Todas as chamadas SSH — do seu terminal, git, rsync, scp — são interceptadas automaticamente. Hosts que não estão na sua configuração passam para o /usr/bin/ssh sem alterações.

mkdir -p ~/.local/bin
ln -s $(which sshroute) ~/.local/bin/ssh

# Adicione ao ~/.bashrc ou ~/.zshrc se ainda não estiver:
export PATH="$HOME/.local/bin:$PATH"

Início rápido

# Adicione um host com um perfil padrão
sshroute add myserver --host myserver.example.com --user alice --key ~/.ssh/id_ed25519

# Adicione uma substituição específica para VPN
sshroute add myserver --network vpn --host 10.8.0.50 --port 2222 --jump bastion.vpn

# Conecte — a rede é detectada automaticamente
sshroute connect myserver

# Visualize o comando resolvido sem executá-lo
sshroute connect myserver --dry-run

# Veja qual rede está ativa no momento
sshroute network

Comandos

Flags globais

Estas flags se aplicam a todos os comandos:

FlagVariável de ambientePadrãoDescrição
--configSSHROUTE_CONFIG~/.config/sshroute/config.yamlCaminho do arquivo de configuração
-o, --outputtableFormato de saída: table, json, yaml
-v, --verboseSSHROUTE_VERBOSE=1falseLog de depuração no stderr
--dry-runfalseImprime o comando SSH resolvido sem executar

init

Cria um arquivo de configuração inicial com exemplos comentados. Falha se o arquivo já existir.

FlagPadrãoDescrição
--forcefalseSobrescreve um arquivo de configuração existente

connect <alias>

Detecta a rede ativa, resolve os parâmetros SSH para alias e executa o binário SSH real. Quaisquer argumentos extras após o alias são passados diretamente para o SSH sem alteração.

FlagPadrãoDescrição
--fallbackfalseTenta cada perfil em ordem de prioridade, repetindo o próximo apenas em caso de falha de conexão (código de saída 255)
--reconnectfalseSupervisiona a conexão e reconecta automaticamente quando ela cai, redetectando a rede ativa e re-resolvendo a rota a cada vez
--reconnect-delay2sTempo de espera entre tentativas de reconexão quando --reconnect está definido

Com --reconnect, o sshroute mantém o ssh ativo durante quedas de conexão (suspensão do laptop, handoff de WiFi, roaming entre redes). Como ele redetecta a rede a cada reconexão, ele te segue para uma rota diferente: por exemplo, dormir na LAN e acordar em um hotspot reconecta pela rota pública em vez de tentar novamente o endereço LAN agora inalcançável. Um logout limpo (código 0) ou uma falha de autenticação/comando remoto interrompe o loop; apenas quedas genuínas de conexão reconectam. O reconnect executa o ssh como subprocesso (como --fallback), então o sshroute permanece residente durante a sessão; SIGINT/SIGTERM o derruba. O estado da sessão durante o lapso é responsabilidade do seu multiplexador (tmux/zellij); combine --reconnect com -- tmux attach ou -- zellij attach -c <name> para cair direto na sua sessão:

sshroute connect myserver --reconnect --fallback -- zellij attach -c work

list

Lista todos os hosts configurados e os parâmetros SSH que seriam usados na rede atual. Suporta -o table|json|yaml.

add <alias>

Adiciona um host ou atualiza um existente. Flags omitidas mantêm seu valor atual. Execute várias vezes com diferentes valores de --network para construir substituições por rede.

FlagPadrãoDescrição
--hostNome do host ou endereço IP
--port22Porta SSH
--userUsuário SSH
--keyCaminho para o arquivo de identidade (suporta ~)
--jumpHost de salto — passado como -J para o SSH
--networkdefaultPerfil de rede no qual escrever os parâmetros

remove <alias>

Remove todos os perfis de alias da configuração.

network

Imprime o nome da rede atualmente detectada (ou default se nenhuma corresponder).

network list

Lista todas as redes configuradas com sua prioridade, regras de verificação e estado ativo atual. Suporta -o table|json|yaml.

network test <name>

Executa cada verificação para a rede name e imprime passou/falhou por regra. Útil para depurar a lógica de detecção.

config

Imprime o caminho resolvido para o arquivo de configuração.

config edit

Abre o arquivo de configuração no $EDITOR (recai para nano). Cria o arquivo e seu diretório pai se não existirem.

resolve <alias>

Imprime os parâmetros SSH que seriam usados para alias na rede atual. Útil para depuração e scripts. Use --network <name> para sobrescrever a rede detectada. Suporta -o table|json|yaml.

FlagPadrãoDescrição
--networkdetecção automáticaPerfil de rede contra o qual resolver

copy <alias> <src> <dst>

Copia arquivos de ou para um host configurado usando scp com os mesmos parâmetros resolvidos (chave, porta, salto) que connect. Use a sintaxe <alias>:<path> para caminhos remotos:

sshroute copy myserver ./local.txt myserver:/remote/path/
sshroute copy myserver myserver:/remote/file.txt ./local/

A variável de ambiente SSHROUTE_SCP substitui o binário scp usado.

version

Imprime a versão, commit git, data de compilação e informações do runtime Go.

update

Atualiza o sshroute no local para o último lançamento do GitHub. Ele baixa o arquivo para sua plataforma, verifica seu sha256 em relação ao checksums.txt e — se o cosign estiver instalado — verifica a assinatura cosign do lançamento, antes de substituir atomicamente o binário em execução.

sshroute update            # baixa, verifica e instala o último lançamento
sshroute update --check    # apenas informa se uma versão mais nova está disponível
sshroute update --force    # reinstala o último mesmo se já estiver atualizado

Se a verificação sha256 (ou cosign, quando presente) falhar, a atualização é abortada e o binário permanece intacto. Isso tem como alvo instalações do binário de lançamento; se você instalou via go install ou um gerenciador de pacotes, atualize por esses meios.

Arquivo de configuração

Localização padrão: ~/.config/sshroute/config.yaml

networks:
  corp-vpn:
    priority: 10          # menor = verificado primeiro
    checks:
      - type: interface
        match: wg0
      - type: route
        match: 10.100.0.0

  office:
    priority: 20
    checks:
      - type: ping
        host: 192.168.1.1
        timeout: 500ms

hosts:
  myserver:
    default:              # obrigatório — usado quando nenhuma rede corresponde
      host: myserver.example.com
      port: 22
      user: alice
      key: ~/.ssh/id_ed25519
      options:            # opcional — passado como flags SSH -o Key=Value
        ConnectTimeout: "10"
        ServerAliveInterval: "30"
    corp-vpn:
      host: 10.100.0.50
      port: 2222
      key: ~/.ssh/corp_key
      jump: bastion.corp.internal
      options:
        ConnectTimeout: "5"   # substitui o padrão apenas para esta rede
    office:
      host: 192.168.1.50

Todo host deve ter um perfil default. Perfis de rede só precisam especificar campos que diferem do padrão — campos não definidos herdam do default.

Campos do perfil do host

CampoTipoDescrição
hoststringNome do host ou endereço IP
portintPorta SSH (padrão: 22)
userstringUsuário SSH
keystringCaminho para o arquivo de identidade (~ é expandido)
jumpstringApelido do host de salto ou user@host
optionsmapaFlags SSH -o Key=Value arbitrários (ex.: ConnectTimeout, StrictHostKeyChecking)
commentstringDescrição mostrada em sshroute list
tagslistaTags para filtragem com sshroute list --tag

As chaves de options são mescladas de default para perfis de rede — valores de rede substituem chaves correspondentes, chaves não sobrepostas são herdadas.

Detecção de rede

As redes são avaliadas em ordem de priority (menor valor primeiro). Ordem alfabética desempata. A primeira rede cujas verificações passam é usada; se nenhuma corresponder, default se aplica.

Tipo de verificaçãoPassa quandoCampos obrigatórios
routeSub-rede/IP aparece na tabela de roteamento do kernelmatch
interfaceInterface nomeada existe e está operacionalmente ativamatch
pingO host responde ao eco ICMP dentro do tempo limitehost, timeout (opcional, padrão 2s)
execO comando shell sai com código 0command

Múltiplas verificações dentro de uma definição de rede usam lógica E — todas devem passar.

Exemplos

Arquivos de configuração prontos para uso estão em examples/:

ArquivoCaso de uso
basic.yamlHost único, recuo entre VPN e público
multi-network.yamlLAN do escritório, VPN corporativa, VPN remota, público
wireguard-backconnect.yamlPeer WireGuard que se reconecta a você
jump-hosts.yamlBastiões diferentes por rede
multi-zone-roaming.yamlHomelab multi-zona com gateway WireGuard e dispositivos móveis em roaming

Documentação

Guias aprofundados estão em docs/:

GuiaDescrição
Configuração de homelabHomelab multi-zona com WireGuard, hosts de salto, NAS, nós k3s
Roaming multi-zonaVárias LANs, gateway WireGuard, dispositivos móveis que roam entre redes
Ambiente corporativo / multi-ambienteDev/staging/prod com bastiões por ambiente e detecção de VPN
Modo sombraSubstituto transparente do SSH — git, rsync, scp, Ansible
Complemento de shellComplemento dinâmico de apelidos para bash, zsh, fish
Scripts e automaçãoUsando resolve e copy em scripts e pipelines CI

Formatos de saída

Todos os comandos de listagem suportam múltiplos formatos de saída:

sshroute list                  # table (padrão)
sshroute list -o json          # JSON — para scripts
sshroute list -o yaml          # YAML
sshroute network list -o json

Comunidade

Obtenha o software — baixe um binário pré-compilado de Releases, instale com go install github.com/thereisnotime/sshroute@latest, ou compile a partir do código-fonte.

Feedback e relatórios de bug — abra uma issue em GitHub Issues. Use o modelo de relatório de bug para comportamento inesperado e o modelo de solicitação de funcionalidade para ideias.

Contribuições — veja CONTRIBUTING.md para saber como configurar o projeto, executar testes e abrir um pull request. Vulnerabilidades de segurança devem ser relatadas em particular via GitHub Security Advisories.

Compilando a partir do código-fonte

Requer Go 1.22+ e just.

git clone [email protected]:thereisnotime/sshroute.git
cd sshroute

just build        # gera bin/sshroute
just build-all    # compilação cruzada linux/darwin × amd64/arm64
just test         # executa testes com detector de raça
just install      # go install com ldflags de versão injetadas

Categorias