Zurück zu den Updates
New releaseAug 20, 2026

sshroute v0.2.11

Netzwerkbewusster SSH-Router - leitet Verbindungen zu verschiedenen IPs/Ports/Keys/Sprunghosts basierend auf dem aktiven VPN oder Netzwerk um.

Teilen

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

Netzwerkbewusster SSH-Router. Erkennt Ihr aktives Netzwerk oder VPN und wählt automatisch den richtigen Host, Port, Identity File und Jump-Host für jede SSH-Verbindung aus – ohne ~/.ssh/config anfassen zu müssen.

So funktioniert es

Definieren Sie jeden logischen Host einmal mit einem default-Profil und optionalen netzwerkspezifischen Überschreibungen. Bei jeder Verbindung erkennt sshroute, in welchem Netzwerk Sie sich befinden (VPN, Büro-LAN, WireGuard-Peer usw.) und löst die korrekten SSH-Parameter auf, bevor es an das echte /usr/bin/ssh übergibt.

ssh myserver
  → sshroute erkennt: corp-vpn ist aktiv
  → löst auf: 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

Warum sshroute?

Für Homelab-Betreiber

Ihr Labor hat wahrscheinlich mindestens zwei Realitäten: Entweder Sie sitzen zu Hause im LAN oder Sie sind unterwegs und kommen über WireGuard oder ein anderes VPN herein. Das Problem: ~/.ssh/config weiß nicht, in welchem Sie sich befinden – also landen Sie bei separaten Aliasen (server-lan, server-vpn), einem Jump-Host, der nur halb funktioniert, oder Sie merken sich einfach IPs.

sshroute löst dies, indem es vor jeder Verbindung Ihr aktuelles Netzwerk erkennt. Wenn das WireGuard-Interface aktiv ist und die Peer-Route existiert, verbindet es direkt zur Tunnel-IP. Wenn Sie im LAN sind, verwendet es die lokale Adresse. Wenn keines erreichbar ist, fällt es auf den öffentlichen Hostnamen zurück. Ein Alias, drei Realitäten, null manuelles Umschalten.

Außerdem fängt sshroute SSH transparent ab – git push, rsync, scp werden automatisch darüber geleitet, sobald Sie den Schattenmodus eingerichtet haben. Keine Wrapper, keine Shell-Funktionen, kein Nachdenken.

Für Unternehmensumgebungen

Unternehmensnetzwerke sind noch schlimmer. Sie haben das öffentliche Internet, vielleicht ein Site-to-Site-VPN, vielleicht ein persönliches VPN mit Split-Tunnel, und darin verschiedene Jump-Hosts, je nachdem, welche Umgebung Sie anvisieren – Dev, Staging, Prod, jede mit eigener Bastion und eigenem Schlüssel. Das in ~/.ssh/config gerade zu halten bedeutet entweder eine riesige Konfiguration, die bei jeder Infrastrukturänderung kaputt geht, oder ein Skript, das jedes Teammitglied anders pflegt.

sshroute ermöglicht es Ihnen, die Routinglogik deklarativ zu definieren, in einer versionierten YAML-Datei zu speichern und im Team zu teilen. Die gleiche Konfiguration funktioniert für alle – das richtige Netzwerk wird automatisch erkannt, basierend darauf, welche Interfaces oder Routen auf jedem Rechner aktiv sind. Schlüssel, Ports, Benutzer und Jump-Hosts werden aufgelöst, ohne dass der Benutzer darüber nachdenken muss.

Vergleich

Funktion~/.ssh/configNur WireGuardTeleport / Boundarysshroute
Erkennt Ihr aktuelles Netzwerk
Wählt automatisch den besten Pfad
Fallback bei Verbindungsfehler
Automatische Wiederverbindung + Neurouting bei Trennung⚠️ Tunnel roamt⚠️ via festem Proxy
Ein Befehl pro Host, von überall⚠️ VPN muss aktiv sein
Konfigurationsgröße für 10 Hosts × 4 Pfade📄 ~600 Zeilen📄 ~600 Zeilen + VPN-Konfig📄 Server-seitige Konfig📄 ~60 Zeilen
Mobile Geräte im Roaming⚠️ manuelle Aliase⚠️ VPN erforderlich
Automatisches Chaining von Jump-Hosts⚠️ manuelles -J➖ n/a
Funktioniert mit scp / rsync / git / Ansible⚠️ teilweise
Keine Server-Installation auf Zielen
Kein Authentifizierungsserver oder Daemon erforderlich
Kein Client-Agent
Open Source, vollständig selbst gehostet⚠️ Open-Core

Teleport und Boundary sind eine andere Kategorie – sie fügen Zugriffskontrolle, Audit-Logs und zertifikatsbasierte Authentifizierung zum Routing hinzu. Wenn Sie das brauchen, nutzen Sie sie. sshroute ist für diejenigen, die die Routing-Intelligenz wollen, ohne den Betriebsaufwand eines zentralen Auth-Servers.

Installation

Binär-Download

Laden Sie die neueste Veröffentlichung von GitHub Releases herunter. Binärdateien sind für Linux, macOS und Android auf AMD64 und ARM64 verfügbar.

Go install

go install github.com/thereisnotime/sshroute@latest

Android (Termux)

Laden Sie das android_arm64-Tarball von GitHub Releases herunter, extrahieren Sie es und legen Sie die Binärdatei in ~/.local/bin ab:

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

Fügen Sie ~/.local/bin zu Ihrem PATH in ~/.bashrc oder ~/.profile hinzu, falls noch nicht geschehen:

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

Alternativ können Sie mit Termux' Go aus dem Quellcode kompilieren. Da die offizielle Go-Toolchain keine android/arm64-Binärdateien veröffentlicht, setzen Sie GOTOOLCHAIN=local, um die von Termux mitgelieferte Version zu verwenden:

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

Setzen Sie nach der Installation den SSH-Binärpfad, da Termux kein /usr/bin/ssh hat:

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

Oder per Umgebungsvariable: 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

Auf Systemen mit SELinux (Fedora, RHEL usw.) fügen Sie dem Volume-Flag :Z hinzu:

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

Schattenmodus (transparenter SSH-Ersatz)

Installieren Sie sshroute als ssh weiter vorne in Ihrem $PATH. Alle SSH-Aufrufe – vom Terminal, von git, rsync, scp – werden automatisch abgefangen. Hosts, die nicht in Ihrer Konfiguration stehen, werden unverändert an /usr/bin/ssh durchgereicht.

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

# In ~/.bashrc oder ~/.zshrc hinzufügen, falls nicht vorhanden:
export PATH="$HOME/.local/bin:$PATH"

Schnellstart

# Einen Host mit einem Standardprofil hinzufügen
sshroute add myserver --host myserver.example.com --user alice --key ~/.ssh/id_ed25519

# Eine VPN-spezifische Überschreibung hinzufügen
sshroute add myserver --network vpn --host 10.8.0.50 --port 2222 --jump bastion.vpn

# Verbinden – Netzwerk wird automatisch erkannt
sshroute connect myserver

# Den aufgelösten Befehl anzeigen, ohne ihn auszuführen
sshroute connect myserver --dry-run

# Sehen, welches Netzwerk gerade aktiv ist
sshroute network

Befehle

Globale Flags

Diese Flags gelten für jeden Befehl:

FlagUmgebungsvariableStandardBeschreibung
--configSSHROUTE_CONFIG~/.config/sshroute/config.yamlPfad zur Konfigurationsdatei
-o, --outputtableAusgabeformat: table, json, yaml
-v, --verboseSSHROUTE_VERBOSE=1falseDebug-Ausgabe nach stderr
--dry-runfalseAufgelösten SSH-Befehl ausgeben, ohne ihn auszuführen

init

Erstellt eine Startkonfigurationsdatei mit kommentierten Beispielen. Schlägt fehl, wenn die Datei bereits existiert.

FlagStandardBeschreibung
--forcefalseVorhandene Konfigurationsdatei überschreiben

connect <alias>

Erkennt das aktive Netzwerk, löst die SSH-Parameter für alias auf und führt die echte SSH-Binärdatei aus. Zusätzliche Argumente nach dem Alias werden unverändert an SSH durchgereicht.

FlagStandardBeschreibung
--fallbackfalseJedes Profil in der Prioritätsreihenfolge versuchen und nur bei einem Verbindungsfehler (Exit 255) zum nächsten wechseln
--reconnectfalseVerbindung überwachen und bei Trennung automatisch wieder verbinden, dabei das aktive Netzwerk neu erkennen und die Route jedes Mal neu auflösen
--reconnect-delay2sWartezeit zwischen Wiederverbindungsversuchen, wenn --reconnect gesetzt ist

Mit --reconnect hält sshroute die SSH-Verbindung über abgebrochene Verbindungen hinweg aufrecht (Laptop-Schlaf, WLAN-Handover, Roaming zwischen Netzwerken). Da es bei jeder Wiederverbindung das Netzwerk neu erkennt, folgt es Ihnen auf eine andere Route: Werden Sie z. B. im LAN schlafen und an einem Hotspot aufwachen, wird über die öffentliche Route neu verbunden, anstatt die jetzt unerreichbare LAN-Adresse erneut zu versuchen. Ein sauberer Logout (Exit 0) oder ein Fehler bei Authentifizierung/Remote-Befehl stoppt die Schleife; nur echte Verbindungsabbrüche lösen eine Wiederverbindung aus. Der Wiederverbindungsmodus startet ssh als Unterprozess (wie --fallback), sodass sshroute für die Sitzung resident bleibt; SIGINT/SIGTERM beendet es. Der Sitzungszustand über den Aussetzer hinweg ist Aufgabe Ihres Multiplexers (tmux/zellij); kombinieren Sie --reconnect mit -- tmux attach oder -- zellij attach -c <name>, um direkt in Ihre Sitzung zurückzukehren:

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

list

Listet alle konfigurierten Hosts und die SSH-Parameter auf, die im aktuellen Netzwerk verwendet würden. Unterstützt -o table|json|yaml.

add <alias>

Fügt einen Host hinzu oder aktualisiert einen vorhandenen. Ausgelassene Flags behalten ihren aktuellen Wert. Führen Sie den Befehl mehrmals mit verschiedenen --network-Werten aus, um netzwerkspezifische Überschreibungen zu erstellen.

FlagStandardBeschreibung
--hostHostname oder IP-Adresse
--port22SSH-Port
--userSSH-Benutzername
--keyPfad zur Identity-Datei (unterstützt ~)
--jumpJump-Host – wird als -J an SSH übergeben
--networkdefaultNetzwerkprofil, in das die Parameter geschrieben werden

remove <alias>

Entfernt alle Profile für alias aus der Konfiguration.

network

Gibt den Namen des aktuell erkannten Netzwerks aus (oder default, wenn keins passt).

network list

Listet alle konfigurierten Netzwerke mit ihrer Priorität, Prüfregeln und aktuellem Aktivitätsstatus auf. Unterstützt -o table|json|yaml.

network test <name>

Führt jede Prüfung für das Netzwerk name aus und gibt bestanden/nicht bestanden pro Regel aus. Nützlich zum Debuggen der Erkennungslogik.

config

Gibt den aufgelösten Pfad zur Konfigurationsdatei aus.

config edit

Öffnet die Konfigurationsdatei in $EDITOR (fällt auf nano zurück). Erstellt die Datei und das übergeordnete Verzeichnis, falls sie nicht existieren.

resolve <alias>

Gibt die SSH-Parameter aus, die für alias im aktuellen Netzwerk verwendet würden. Nützlich zum Debuggen und für Skripte. Verwenden Sie --network <name>, um das erkannte Netzwerk zu überschreiben. Unterstützt -o table|json|yaml.

FlagStandardBeschreibung
--networkautomatische ErkennungNetzwerkprofil, gegen das aufgelöst werden soll

copy <alias> <src> <dst>

Kopiert Dateien zu oder von einem konfigurierten Host mit scp unter Verwendung derselben aufgelösten Parameter (Schlüssel, Port, Jump) wie connect. Verwenden Sie die Syntax <alias>:<pfad> für entfernte Pfade:

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

Die Umgebungsvariable SSHROUTE_SCP überschreibt die verwendete scp-Binärdatei.

version

Gibt Version, Git-Commit, Build-Datum und Go-Laufzeitinformationen aus.

update

Aktualisiert sshroute direkt auf die neueste GitHub-Version. Es lädt das Archiv für Ihre Plattform herunter, überprüft dessen sha256 gegen checksums.txt und – falls cosign installiert ist – die Cosign-Signatur der Version, bevor es die laufende Binärdatei atomar ersetzt.

sshroute update            # neueste Version herunterladen, verifizieren und installieren
sshroute update --check    # nur melden, ob eine neuere Version verfügbar ist
sshroute update --force    # neueste Version auch neu installieren, wenn bereits aktuell

Wenn die sha256-Prüfung (oder Cosign, falls vorhanden) fehlschlägt, wird das Update abgebrochen und die Binärdatei bleibt unberührt. Dieses Ziel sind Installationen der Release-Binärdatei; wenn Sie über go install oder einen Paketmanager installiert haben, aktualisieren Sie damit.

Konfigurationsdatei

Standardpfad: ~/.config/sshroute/config.yaml

networks:
  corp-vpn:
    priority: 10          # niedriger = zuerst geprüft
    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:              # erforderlich – wird verwendet, wenn kein Netzwerk passt
      host: myserver.example.com
      port: 22
      user: alice
      key: ~/.ssh/id_ed25519
      options:            # optional – als SSH -o Key=Value Flags übergeben
        ConnectTimeout: "10"
        ServerAliveInterval: "30"
    corp-vpn:
      host: 10.100.0.50
      port: 2222
      key: ~/.ssh/corp_key
      jump: bastion.corp.internal
      options:
        ConnectTimeout: "5"   # überschreibt den Standard nur für dieses Netzwerk
    office:
      host: 192.168.1.50

Jeder Host muss ein default-Profil haben. Netzwerkprofile müssen nur die Felder angeben, die vom Standard abweichen – nicht gesetzte Felder erben vom default.

Felder des Host-Profils

FeldTypBeschreibung
hoststringHostname oder IP-Adresse
portintSSH-Port (Standard: 22)
userstringSSH-Benutzer
keystringPfad zur Identity-Datei (~ wird expandiert)
jumpstringJump-Host-Alias oder user@host
optionsmapBeliebige SSH -o Key=Value Flags (z.B. ConnectTimeout, StrictHostKeyChecking)
commentstringBeschreibung, die in sshroute list angezeigt wird
tagslistTags zum Filtern mit sshroute list --tag

Die options-Schlüssel werden vom default-Profil in die Netzwerkprofile gemergt – Netzwerkeinträge überschreiben übereinstimmende Schlüssel, nicht überlappende Schlüssel werden vererbt.

Netzwerkerkennung

Netzwerke werden in der Reihenfolge der priority ausgewertet (niedrigster Wert zuerst). Alphabetische Reihenfolge entscheidet bei Gleichstand. Das erste Netzwerk, dessen Prüfungen alle bestehen, wird verwendet; wenn keins passt, gilt default.

PrüftypBesteht, wennErforderliche Felder
routeSubnetz/IP in der Kernel-Routing-Tabelle erscheintmatch
interfaceBenanntes Interface existiert und ist betriebsbereitmatch
pingHost innerhalb des Timeouts auf ICMP-Echo antwortethost, timeout (optional, Standard 2s)
execShell-Befehl mit Exit-Code 0 beendetcommand

Mehrere Prüfungen innerhalb einer Netzwerkdefinition verwenden UND-Logik – alle müssen bestehen.

Beispiele

Gebrauchsfertige Konfigurationsdateien befinden sich in examples/:

DateiAnwendungsfall
basic.yamlEinzelner Host, VPN vs. öffentlicher Fallback
multi-network.yamlBüro-LAN, Firmen-VPN, Remote-VPN, öffentlich
wireguard-backconnect.yamlWireGuard-Peer, der sich zu Ihnen zurückverbindet
jump-hosts.yamlVerschiedene Bastionen pro Netzwerk
multi-zone-roaming.yamlMulti-Zonen-Homelab mit WireGuard-Gateway und mobilen Geräten im Roaming

Dokumentation

Ausführliche Anleitungen finden Sie in docs/:

AnleitungBeschreibung
Homelab-EinrichtungMulti-Zonen-Homelab mit WireGuard, Jump-Hosts, NAS, k3s-Knoten
Multi-Zonen-RoamingMehrere LANs, WireGuard-Gateway, mobile Geräte, die zwischen Netzwerken roamieren
Unternehmen / Multi-UmgebungDev/Staging/Prod mit umgebungsspezifischen Bastionen und VPN-Erkennung
SchattenmodusTransparenter SSH-Ersatz – git, rsync, scp, Ansible
Shell-VervollständigungDynamische Alias-Vervollständigung für bash, zsh, fish
Skripterstellung und AutomatisierungVerwendung von resolve und copy in Skripten und CI-Pipelines

Ausgabeformate

Alle List-Befehle unterstützen mehrere Ausgabeformate:

sshroute list                  # Tabelle (Standard)
sshroute list -o json          # JSON – für Skripte
sshroute list -o yaml          # YAML
sshroute network list -o json

Community

Software herunterladen – Laden Sie eine vorkompilierte Binärdatei von Releases herunter, installieren Sie mit go install github.com/thereisnotime/sshroute@latest oder bauen Sie aus dem Quellcode.

Feedback und Fehlerberichte – Öffnen Sie ein Issue auf GitHub Issues. Verwenden Sie die Bug-Report-Vorlage für unerwartetes Verhalten und die Feature-Request-Vorlage für Ideen.

Mitwirken – Siehe CONTRIBUTING.md für die Einrichtung des Projekts, das Ausführen von Tests und das Öffnen eines Pull Requests. Sicherheitslücken sollten privat über GitHub Security Advisories gemeldet werden.

Aus dem Quellcode bauen

Erfordert Go 1.22+ und just.

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

just build        # Ausgabe: bin/sshroute
just build-all    # Cross-Kompilierung linux/darwin × amd64/arm64
just test         # Tests mit Race-Detector ausführen
just install      # go install mit eingefügten Versions-ldflags

Kategorien