Remote-Zugriff (SSH, Tunnel und Tailnets)

Dieses Repo unterstützt “Remote über SSH”, indem ein einzelnes Gateway (der Master) auf einem dedizierten Host (Desktop/Server) läuft und sich Clients damit verbinden.

  • Für Operators (du / die macOS-App): SSH-Tunneling ist der universelle Fallback.
  • Für Nodes (iOS/Android und zukünftige Geräte): Verbinde dich mit dem Gateway-WebSocket (LAN/Tailnet oder SSH-Tunnel nach Bedarf).

Die Grundidee

  • Der Gateway-WebSocket bindet an Loopback auf dem konfigurierten Port (Standard 18789).
  • Für Remote-Nutzung leitest du diesen Loopback-Port über SSH weiter (oder nutzt ein Tailnet/VPN und brauchst weniger Tunneling).

Gängige VPN-/Tailnet-Setups (wo der Agent lebt)

Stell dir den Gateway-Host als “wo der Agent lebt” vor. Er besitzt Sessions, Auth-Profile, Channels und State. Dein Laptop/Desktop (und Nodes) verbinden sich mit diesem Host.

1) Always-On-Gateway in deinem Tailnet (VPS oder Home-Server)

Betreibe das Gateway auf einem persistenten Host und erreiche es per Tailscale oder SSH.

  • Beste UX: gateway.bind: "loopback" beibehalten und Tailscale Serve für die Control-UI nutzen.
  • Fallback: Loopback beibehalten + SSH-Tunnel von jedem Rechner, der Zugriff braucht.
  • Beispiele: exe.dev (einfache VM) oder Hetzner (Produktions-VPS).

Ideal, wenn dein Laptop häufig in den Ruhezustand geht, der Agent aber immer erreichbar sein soll.

2) Desktop zu Hause betreibt das Gateway, Laptop als Fernsteuerung

Der Laptop betreibt keinen eigenen Agent. Er verbindet sich remote:

  • Nutze den Remote over SSH-Modus der macOS-App (Einstellungen > Allgemein > “OpenClaw runs”).
  • Die App öffnet und verwaltet den Tunnel, sodass WebChat + Health-Checks “einfach funktionieren”.

Anleitung: macOS Remote-Zugriff.

3) Laptop betreibt das Gateway, Remote-Zugriff von anderen Rechnern

Behalte das Gateway lokal, aber stelle es sicher bereit:

  • SSH-Tunnel zum Laptop von anderen Rechnern, oder
  • Tailscale Serve für die Control-UI und das Gateway auf Loopback-only.

Anleitung: Tailscale und Web-Übersicht.

Befehlsfluss (was wo läuft)

Ein Gateway-Service besitzt State + Channels. Nodes sind Peripheriegeräte.

Beispielfluss (Telegram -> Node):

  • Telegram-Nachricht kommt beim Gateway an.
  • Gateway führt den Agent aus und entscheidet, ob ein Node-Tool aufgerufen werden soll.
  • Gateway ruft den Node über den Gateway-WebSocket auf (node.*-RPC).
  • Node gibt das Ergebnis zurück; Gateway antwortet zurück an Telegram.

Hinweise:

  • Nodes betreiben keinen Gateway-Service. Nur ein Gateway sollte pro Host laufen, es sei denn, du betreibst absichtlich isolierte Profile (siehe Mehrere Gateways).
  • Der “Node-Modus” der macOS-App ist lediglich ein Node-Client über den Gateway-WebSocket.

SSH-Tunnel (CLI + Tools)

Erstelle einen lokalen Tunnel zum Remote-Gateway-WS:

ssh -N -L 18789:127.0.0.1:18789 user@host

Mit dem Tunnel:

  • openclaw health und openclaw status --deep erreichen nun das Remote-Gateway über ws://127.0.0.1:18789.
  • openclaw gateway {status,health,send,agent,call} kann das Gateway auch über --url mit der weitergeleiteten URL ansprechen.

Hinweis: Ersetze 18789 durch deinen konfigurierten gateway.port (oder --port/OPENCLAW_GATEWAY_PORT). Hinweis: Wenn du --url verwendest, fällt die CLI nicht auf Konfigurations- oder Umgebungs-Credentials zurück. Gib --token oder --password explizit an. Fehlende explizite Credentials sind ein Fehler.

CLI-Remote-Standardwerte

Du kannst ein Remote-Ziel persistieren, damit CLI-Befehle es standardmäßig verwenden:

{
  gateway: {
    mode: "remote",
    remote: {
      url: "ws://127.0.0.1:18789",
      token: "your-token",
    },
  },
}

Wenn das Gateway nur auf Loopback hört, belasse die URL bei ws://127.0.0.1:18789 und öffne zuerst den SSH-Tunnel.

Credential-Vorrang

Die Gateway-Credential-Auflösung folgt einem gemeinsamen Vertrag über Call-/Probe-/Status-Pfade und Discord-Exec-Approval-Monitoring. Node-Host verwendet denselben Basisvertrag mit einer Ausnahme im Local-Modus (er ignoriert absichtlich gateway.remote.*):

  • Explizite Credentials (--token, --password oder Tool gatewayToken) gewinnen immer auf Call-Pfaden, die explizite Auth akzeptieren.
  • URL-Override-Sicherheit:
    • CLI-URL-Overrides (--url) verwenden nie implizite Config-/Env-Credentials.
    • Env-URL-Overrides (OPENCLAW_GATEWAY_URL) dürfen nur Env-Credentials verwenden (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD).
  • Local-Modus-Standards:
    • Token: OPENCLAW_GATEWAY_TOKEN -> gateway.auth.token -> gateway.remote.token (Remote-Fallback gilt nur, wenn der lokale Auth-Token-Input nicht gesetzt ist)
    • Passwort: OPENCLAW_GATEWAY_PASSWORD -> gateway.auth.password -> gateway.remote.password (Remote-Fallback gilt nur, wenn der lokale Auth-Passwort-Input nicht gesetzt ist)
  • Remote-Modus-Standards:
    • Token: gateway.remote.token -> OPENCLAW_GATEWAY_TOKEN -> gateway.auth.token
    • Passwort: OPENCLAW_GATEWAY_PASSWORD -> gateway.remote.password -> gateway.auth.password
  • Node-Host Local-Modus-Ausnahme: gateway.remote.token / gateway.remote.password werden ignoriert.
  • Remote-Probe/Status-Token-Prüfungen sind standardmäßig strikt: Sie verwenden nur gateway.remote.token (kein lokaler Token-Fallback) im Remote-Modus.
  • Legacy CLAWDBOT_GATEWAY_*-Env-Variablen werden nur von Kompatibilitäts-Call-Pfaden verwendet; Probe/Status/Auth-Auflösung nutzt ausschließlich OPENCLAW_GATEWAY_*.

Chat-UI über SSH

WebChat nutzt keinen separaten HTTP-Port mehr. Die SwiftUI-Chat-UI verbindet sich direkt mit dem Gateway-WebSocket.

  • Leite 18789 über SSH weiter (siehe oben), dann verbinde Clients mit ws://127.0.0.1:18789.
  • Auf macOS bevorzuge den “Remote over SSH”-Modus der App, der den Tunnel automatisch verwaltet.

macOS-App “Remote over SSH”

Die macOS-Menüleisten-App kann dasselbe Setup end-to-end steuern (Remote-Statusprüfungen, WebChat und Voice-Wake-Weiterleitung).

Anleitung: macOS Remote-Zugriff.

Sicherheitsregeln (Remote/VPN)

Kurzfassung: Halte das Gateway auf Loopback-only, es sei denn, du bist sicher, dass du einen Bind brauchst.

  • Loopback + SSH/Tailscale Serve ist der sicherste Standard (keine öffentliche Exposition).
  • Klartext ws:// ist standardmäßig nur für Loopback. Für vertrauenswürdige private Netzwerke setze OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 auf dem Client-Prozess als Break-Glass.
  • Nicht-Loopback-Bindungen (lan/tailnet/custom, oder auto wenn Loopback nicht verfügbar ist) müssen Auth-Tokens/-Passwörter verwenden.
  • gateway.remote.token / .password sind Client-Credential-Quellen. Sie konfigurieren nicht allein die Server-Auth.
  • Lokale Call-Pfade können gateway.remote.* nur als Fallback verwenden, wenn gateway.auth.* nicht gesetzt ist.
  • Wenn gateway.auth.token / gateway.auth.password explizit per SecretRef konfiguriert und nicht aufgelöst ist, schlägt die Auflösung fehl (kein Remote-Fallback-Masking).
  • gateway.remote.tlsFingerprint pinnt das Remote-TLS-Zertifikat bei Verwendung von wss://.
  • Tailscale Serve kann Control-UI-/WebSocket-Traffic über Identity-Header authentifizieren, wenn gateway.auth.allowTailscale: true; HTTP-API-Endpunkte erfordern weiterhin Token-/Passwort-Auth. Dieser tokenlose Flow setzt voraus, dass der Gateway-Host vertrauenswürdig ist. Setze ihn auf false, wenn du überall Tokens/Passwörter erzwingen willst.
  • Behandle Browser-Kontrolle wie Operator-Zugriff: Tailnet-only + bewusstes Node-Pairing.

Vertiefung: Sicherheit.