Volver a actualizaciones
Nuevo releaseAug 20, 2026

sshroute v0.2.11

Enrutador SSH consciente de la red - enruta conexiones a diferentes IPs/puertos/claves/hosts de salto según la VPN o red activa

Compartir

sshroute

CICodeOpenSpecSecurity
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

Enrutador SSH consciente de la red. Detecta tu red activa o VPN y selecciona automáticamente el host, puerto, archivo de identidad y host de salto correctos para cada conexión SSH, sin tocar ~/.ssh/config.

Cómo funciona

Define cada host lógico una vez con un perfil default anidado y opcionales anulaciones por red. En cada conexión, sshroute detecta en qué red estás (VPN, LAN de oficina, par WireGuard, etc.) y resuelve los parámetros SSH correctos antes de pasar el control al /usr/bin/ssh real.

ssh myserver
  → sshroute detecta: corp-vpn está activa
  → resuelve: 10.100.0.50:2222 vía bastion.corp.internal
  → exec /usr/bin/ssh -p 2222 -i ~/.ssh/corp_key -J bastion.corp.internal 10.100.0.50

¿Por qué sshroute?

Para entusiastas de homelab

Tu laboratorio probablemente tiene al menos dos realidades: o estás en casa en la LAN, o estás fuera y te conectas a través de WireGuard u otra VPN. El problema es que ~/.ssh/config no sabe en cuál estás, así que terminas con alias separados (server-lan, server-vpn), o un host de salto que solo funciona la mitad del tiempo, o simplemente memorizas direcciones IP.

sshroute soluciona esto detectando tu red actual antes de cada conexión. Cuando la interfaz WireGuard está activa y la ruta del par existe, se conecta directamente a la IP del túnel. Cuando estás en la LAN, usa la dirección local. Cuando ninguna es alcanzable, recurre al nombre de host público. Un alias, tres realidades, cero cambios manuales.

También intercepta SSH de manera transparente: git push, rsync, scp — todo pasa a través de él automáticamente una vez que configuras el modo sombra. Sin envoltorios, sin funciones de shell, sin pensar.

Para entornos corporativos

Las redes empresariales son peores. Tienes la internet pública, tal vez una VPN sitio a sitio, tal vez una VPN personal con split-tunnel, y dentro de eso diferentes hosts de salto según el entorno al que apuntes — desarrollo, staging, producción, cada uno con su bastión y clave. Mantener esto en orden en ~/.ssh/config significa o un archivo enorme que se rompe cada vez que cambia la infraestructura, o escribir un script que todos en el equipo mantienen de manera diferente.

sshroute te permite definir la lógica de enrutamiento de forma declarativa, mantenerla en un archivo YAML versionado y compartirla con el equipo. La misma configuración funciona para todos: la red correcta se detecta automáticamente según qué interfaces o rutas están activas en cada máquina. Las claves, puertos, usuarios y hosts de salto se resuelven sin que el usuario tenga que pensar en ello.

Comparativa

Característica~/.ssh/configSolo WireGuardTeleport / Boundarysshroute
Detecta tu red actual
Elige la mejor ruta automáticamente
Reintenta en caso de fallo de conexión
Reconexión automática + reenrutamiento al caer⚠️ el túnel vaga⚠️ a través de proxy fijo
Un comando por host, desde cualquier ubicación⚠️ VPN debe estar activa
Tamaño de configuración para 10 hosts × 4 rutas📄 ~600 líneas📄 ~600 líneas + config VPN📄 configuración del lado servidor📄 ~60 líneas
Dispositivos móviles en itinerancia⚠️ alias manuales⚠️ VPN requerida
Encadenamiento automático de host de salto⚠️ manual -J➖ n/a
Funciona con scp / rsync / git / Ansible⚠️ parcial
Sin instalación en el servidor en los destinos
Sin servidor de autenticación ni demonio
Sin agente cliente
Código abierto, completamente autogestionado⚠️ open-core

Teleport y Boundary son una categoría diferente: añaden control de acceso, registros de auditoría y autenticación basada en certificados sobre el enrutamiento. Si eso es lo que necesitas, úsalos. sshroute es para cuando quieres la inteligencia de enrutamiento sin la sobrecarga operativa de ejecutar un servidor de autenticación central.

Instalación

Descarga del binario

Descarga la última versión desde GitHub Releases. Hay binarios disponibles para Linux, macOS y Android en AMD64 y ARM64.

Instalación con Go

go install github.com/thereisnotime/sshroute@latest

Android (Termux)

Descarga el tarball android_arm64 desde GitHub Releases, extráelo y coloca el binario en ~/.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

Añade ~/.local/bin a tu PATH en ~/.bashrc o ~/.profile si aún no está:

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

Alternativamente, compila desde el código fuente con Go de Termux. Debido a que el toolchain oficial de Go no publica binarios android/arm64, configura GOTOOLCHAIN=local para usar el que proporciona Termux:

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

Después de instalar, establece la ruta del binario SSH, ya que Termux no tiene /usr/bin/ssh:

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

O mediante una variable de entorno: 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

En sistemas con SELinux habilitado (Fedora, RHEL, etc.) añade :Z al flag de volumen:

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

Modo sombra (reemplazo transparente de SSH)

Instala sshroute como ssh antes en tu $PATH. Todas las llamadas SSH — desde tu terminal, git, rsync, scp — son interceptadas automáticamente. Los hosts que no estén en tu configuración pasan a /usr/bin/ssh sin cambios.

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

# Añade a ~/.bashrc o ~/.zshrc si aún no está:
export PATH="$HOME/.local/bin:$PATH"

Inicio rápido

# Añade un host con un perfil por defecto
sshroute add myserver --host myserver.example.com --user alice --key ~/.ssh/id_ed25519

# Añade una anulación específica para VPN
sshroute add myserver --network vpn --host 10.8.0.50 --port 2222 --jump bastion.vpn

# Conéctate — la red se detecta automáticamente
sshroute connect myserver

# Previsualiza el comando resuelto sin ejecutarlo
sshroute connect myserver --dry-run

# Ve qué red está activa actualmente
sshroute network

Comandos

Flags globales

Estos flags aplican a todos los comandos:

FlagVariable de entornoValor por defectoDescripción
--configSSHROUTE_CONFIG~/.config/sshroute/config.yamlRuta del archivo de configuración
-o, --outputtableFormato de salida: table, json, yaml
-v, --verboseSSHROUTE_VERBOSE=1falseRegistro de depuración en stderr
--dry-runfalseImprime el comando SSH resuelto sin ejecutarlo

init

Crea un archivo de configuración inicial con ejemplos comentados. Falla si el archivo ya existe.

FlagValor por defectoDescripción
--forcefalseSobrescribe un archivo de configuración existente

connect <alias>

Detecta la red activa, resuelve los parámetros SSH para alias y ejecuta el binario SSH real. Cualquier argumento extra después del alias se pasa a SSH sin cambios.

FlagValor por defectoDescripción
--fallbackfalseIntenta cada perfil en orden de prioridad, reintentando el siguiente solo si falla la conexión (código de salida 255)
--reconnectfalseSupervisa la conexión y se reconecta automáticamente cuando se cae, redetectando la red activa y recalculando la ruta cada vez
--reconnect-delay2sEspera entre intentos de reconexión cuando se usa --reconnect

Con --reconnect, sshroute mantiene ssh activo a través de caídas de conexión (suspensión del portátil, traspaso WiFi, itinerancia entre redes). Como redetecta la red en cada reconexión, te sigue a una ruta diferente: por ejemplo, dormir en la LAN y despertar en un punto de acceso público se reconecta por la ruta pública en lugar de reintentar la dirección LAN ahora inalcanzable. Un cierre de sesión limpio (código de salida 0) o un fallo de autenticación/comando remoto detienen el bucle; solo las caídas genuinas de conexión provocan reconexión. La reconexión ejecuta ssh como un subproceso (como --fallback), por lo que sshroute permanece residente durante la sesión; SIGINT/SIGTERM lo derriba. El estado de la sesión a través del parpadeo es trabajo de tu multiplexor (tmux/zellij); combina --reconnect con -- tmux attach o -- zellij attach -c <nombre> para volver directamente a tu sesión:

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

list

Lista todos los hosts configurados y los parámetros SSH que se usarían en la red actual. Soporta -o table|json|yaml.

add <alias>

Añade un host o actualiza uno existente. Los flags omitidos mantienen su valor actual. Ejecuta varias veces con diferentes valores de --network para construir anulaciones por red.

FlagValor por defectoDescripción
--hostNombre de host o dirección IP
--port22Puerto SSH
--userUsuario SSH
--keyRuta al archivo de identidad (soporta ~)
--jumpHost de salto — se pasa como -J a SSH
--networkdefaultPerfil de red en el que escribir los parámetros

remove <alias>

Elimina todos los perfiles de alias de la configuración.

network

Imprime el nombre de la red detectada actualmente (o default si ninguna coincide).

network list

Lista todas las redes configuradas con su prioridad, reglas de comprobación y estado activo actual. Soporta -o table|json|yaml.

network test <name>

Ejecuta cada comprobación de la red name e imprime aprobado/fallido por regla. Útil para depurar la lógica de detección.

config

Imprime la ruta resuelta al archivo de configuración.

config edit

Abre el archivo de configuración en $EDITOR (si no está definido, usa nano). Crea el archivo y su directorio padre si no existen.

resolve <alias>

Imprime los parámetros SSH que se usarían para alias en la red actual. Útil para depuración y scripting. Usa --network <name> para anular la red detectada. Soporta -o table|json|yaml.

FlagValor por defectoDescripción
--networkdetección automáticaPerfil de red contra el que resolver

copy <alias> <src> <dst>

Copia archivos hacia o desde un host configurado usando scp con los mismos parámetros resueltos (clave, puerto, salto) que connect. Usa la sintaxis <alias>:<ruta> para rutas remotas:

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

La variable de entorno SSHROUTE_SCP anula el binario scp utilizado.

version

Imprime la versión, el commit de Git, la fecha de compilación y la información del runtime Go.

update

Actualiza sshroute in situ a la última versión de GitHub. Descarga el archivo para tu plataforma, verifica su sha256 contra checksums.txt y — si cosign está instalado — verifica la firma cosign del lanzamiento, antes de reemplazar atómicamente el binario en ejecución.

sshroute update            # descarga, verifica e instala la última versión
sshroute update --check    # solo informa si hay una versión más reciente disponible
sshroute update --force    # reinstala la última versión incluso si ya está actualizado

Si la verificación sha256 (o cosign, cuando está presente) falla, la actualización se cancela y el binario no se modifica. Esto está pensado para instalaciones del binario de lanzamiento; si instalaste mediante go install o un gestor de paquetes, actualiza con ese método.

Archivo de configuración

Ubicación por defecto: ~/.config/sshroute/config.yaml

networks:
  corp-vpn:
    priority: 10          # lower = checked first
    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:              # required — used when no network matches
      host: myserver.example.com
      port: 22
      user: alice
      key: ~/.ssh/id_ed25519
      options:            # optional — passed as SSH -o Key=Value flags
        ConnectTimeout: "10"
        ServerAliveInterval: "30"
    corp-vpn:
      host: 10.100.0.50
      port: 2222
      key: ~/.ssh/corp_key
      jump: bastion.corp.internal
      options:
        ConnectTimeout: "5"   # overrides default for this network only
    office:
      host: 192.168.1.50

Todo host debe tener un perfil default. Los perfiles de red solo necesitan especificar los campos que difieren del valor por defecto: los campos no establecidos heredan de default.

Campos de perfil de host

CampoTipoDescripción
hoststringNombre de host o dirección IP
portintPuerto SSH (por defecto: 22)
userstringUsuario SSH
keystringRuta al archivo de identidad (se expande ~)
jumpstringAlias de host de salto o user@host
optionsmapFlags arbitrarios SSH -o Key=Value (ej. ConnectTimeout, StrictHostKeyChecking)
commentstringDescripción mostrada en sshroute list
tagslistEtiquetas para filtrar con sshroute list --tag

Las claves de options se fusionan desde default hacia los perfiles de red: los valores de red anulan las claves coincidentes, las claves no superpuestas se heredan.

Detección de red

Las redes se evalúan en orden de priority (el valor más bajo primero). El orden alfabético desempata. Se usa la primera red cuyas comprobaciones pasen todas; si ninguna coincide, se aplica default.

Tipo de comprobaciónPasa cuandoCampos requeridos
routeLa subred/IP aparece en la tabla de enrutamiento del kernelmatch
interfaceLa interfaz nombrada existe y está operativamente activamatch
pingEl host responde al eco ICMP dentro del tiempo de esperahost, timeout (opcional, por defecto 2s)
execEl comando de shell termina con código 0command

Múltiples comprobaciones dentro de una misma definición de red usan lógica AND — todas deben pasar.

Ejemplos

Archivos de configuración listos para usar en examples/:

ArchivoCaso de uso
basic.yamlHost único, respaldo VPN vs público
multi-network.yamlLAN de oficina, VPN corporativa, VPN remota, público
wireguard-backconnect.yamlPar WireGuard que se reconecta contigo
jump-hosts.yamlDiferentes bastiones por red
multi-zone-roaming.yamlHomelab multi-zona con gateway WireGuard y dispositivos móviles en itinerancia

Documentación

Guías detalladas en docs/:

GuíaDescripción
Configuración de homelabHomelab multi-zona con WireGuard, hosts de salto, NAS, nodos k3s
Itinerancia multi-zonaMúltiples LANs, gateway WireGuard, dispositivos móviles que se mueven entre redes
Entorno corporativo / multi-entornoDesarrollo/staging/producción con bastiones por entorno y detección de VPN
Modo sombraReemplazo transparente de SSH — git, rsync, scp, Ansible
Finalización de shellFinalización dinámica de alias para bash, zsh, fish
Scripting y automatizaciónUso de resolve y copy en scripts y pipelines CI

Formatos de salida

Todos los comandos de lista soportan múltiples formatos de salida:

sshroute list                  # table (por defecto)
sshroute list -o json          # JSON — para scripting
sshroute list -o yaml          # YAML
sshroute network list -o json

Comunidad

Obtén el software — descarga un binario precompilado desde Releases, instálalo con go install github.com/thereisnotime/sshroute@latest, o compila desde el código fuente.

Comentarios e informes de errores — abre un issue en GitHub Issues. Usa la plantilla de informe de errores para comportamientos inesperados y la plantilla de solicitud de características para ideas.

Contribuciones — consulta CONTRIBUTING.md para saber cómo configurar el proyecto, ejecutar pruebas y abrir un pull request. Las vulnerabilidades de seguridad deben notificarse de forma privada a través de GitHub Security Advisories.

Compilación desde el código fuente

Requiere Go 1.22+ y just.

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

just build        # outputs bin/sshroute
just build-all    # cross-compile linux/darwin × amd64/arm64
just test         # run tests with race detector
just install      # go install with version ldflags injected

Categorías