Die Challenge

Um mich in mein Heimnetzwerk zu verbinden nutze ich eine SSH Verbindung mit einigen offenen Tunnels. Mein Proxy Server ist per SSH Verfügbar und einige Services die ich gerne nicht öffentlich verfügbar haben möchte, erreiche ich per SSH.

Nachdem meine Firma VPN-Verbindungen blockiert, muss ich eben den SSH-Weg wählen…

Mein Setup bisher

Bisher habe ich den SSH Tunnel manuell aufgesetzt, das bedeutet: Jedes Mal wenn ich den Computer gestartet habe, habe ich ein Terminal geöffnet und ssh ssh-proxy ausgeführt. Das war bereits so wenig Arbeit wie möglich; alles weitere war dann in ~/.ssh/config definiert, so dass ich die Tunnels und Remote IPs nicht mehr definieren musste.

Diese Konfiguration schaut, in einer getrimmten Version, wie folgt aus:

Host ssh-proxy
    HostName ssh-proxy.tech-tales.blog
    User proxy_user

    # Time Tracking
    LocalForward 8001 time-tracking.tech-tales.blog:8001
    # Proxmox Management UI
    LocalForward 8006 proxmox-server.tech-tales.blog:8006

Das neue Setup

Ich habe gelesen dass ich den letzten manuellen Schritt ja doch auch automatisieren könnte - und diese Idee gefällt mir. Also habe ich die Datei /etc/systemd/system/proxy-server.service erzeugt, mit dem folgenden Inhalt:

[Unit]
Description=SSH Tunnels
After=network.target

[Service]

ExecStart=/usr/bin/ssh ssh-proxy

User=chris
Group=chris

RestartSec=5
Restart=always

[Install]
WantedBy=multi-user.target

Was passiert hier: Wenn das Service startet, führe ich ssh ssh-proxy aus. Das mache ich als User (und Gruppe) chris; mein eigener Username am System. Dadurch wird meine Konfigurationsdatei und meine SSH Keys (und Zertitifkate) genutzt.

Falls das Service scheitert, soll es einfach neustarten (Restart=always), nach einer Wartezeit von $5$ Sekunden.

Ich habe hierfür meine Konfiguration auch ein bisschen aktualisiert:

Host ssh-proxy
    HostName ssh-proxy.tech-tales.blog
    User proxy_user

    SessionType none

    ServerAliveInterval 30
    ServerAliveCountMax 2

    ExitOnForwardFailure yes

    # Time Tracking
    LocalForward 8001 time-tracking.tech-tales.blog:8001
    # Proxmox Management UI
    LocalForward 8006 proxmox-server.tech-tales.blog:8006
    # ... and some more forwards

Die folgenden Änderungen habe ich vorgenommen:

  • Ich habe SessionType none hinzugefügt. Dadurch wird kein Befehl am Remote Server ausgeführt; was nicht notwendig ist, da ich ja nur Ports weiterleiten möchte.
  • Neu ist auch ServerAliveInterval 30. Nach 30 Sekunden Inaktivität gibt es einen Heartbeat zwischen Server und Client, und die Verbindung wird gestoppt (und dann automatisch neu gestartet) falls dieser Heartbeat scheitert.
  • Ich habe ServerAliveCountMax 2 hinzugefügt. Das bedeutet, dass die Verbindung bereits nach zwei gescheiterten Heartbeats neu startet; der voreingestellte Wert scheint hier 3 zu sein.
    • Die letzten beiden ServerAlive Konfigurationen definieren, wann eine Verbindung als kaputt gilt: Nach $30 \cdot 2 = 60$ Sekunden stirbt der Prozess. Da ich einen Neustart des Prozesses definiert habe, wird dieser Neustart nach einer Minute (und fünf Sekunden Verspätung) durchgeführt.
  • ExitOnForwardFailure yes bedeutet dass wenn ich den Port Forward nicht durchführen kann, scheitert die Verbindung. Dadurch werden mehrere Verbindungen verhindert.

Am Ende muss ich nur noch einmalig sudo systemctl enable --now proxy-server.service ausführen, und bin fertig!