SSH-Zugriff über einen Proxy
Wie ein LLM-Agent sicher über eine SSH-Proxy-API auf Remote-Maschinen arbeitet statt mit rohen SSH-Keys.
SSH-Zugriff über einen Proxy
Agents müssen Befehle auf Remote-Maschinen ausführen — einen Container deployen, ein Log lesen, eine Config reparieren. Rohe SSH-Private-Keys an ein LLM zu übergeben ist eine schlechte Idee: Keys landen in Kontextfenstern, Logs und Transkripten. Ein SSH-Proxy löst das: er besitzt die Zugangsdaten, der Agent spricht nur HTTP.
Das Modell
LLM ──HTTPS──► SSH-Proxy ──SSH──► Ziel-Maschinen
(besitzt Keys,
Audit-Log,
Rate-Limits)Der Proxy stellt persistente Sessions mit einer einfachen REST-Oberfläche bereit:
| Endpoint | Zweck |
|---|---|
POST /connect?target=vps1 |
Session öffnen → session_id |
POST /<sid>/exec {command, timeout} |
Befehl ausführen (async) → exec_id |
GET /<sid>/exec/<exec_id> |
auf Ausgabe pollen |
| SFTP-Endpoints | Datei-Up-/Download, ls, mkdir, rm |
Die Auth ist ein Bearer-Token — dasselbe Muster wie bei jeder anderen API, die du nutzt.
Das Ausführungsmuster
# 1. Einmal verbinden, die Session für die ganze Task wiederverwenden
SID=$(curl -s -H "Authorization: Bearer $KEY" \
"https://ssh-proxy.example/connect?target=vps1" | jq -r .session_id)
# 2. Befehl ausführen
EID=$(curl -s -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-X POST "https://ssh-proxy.example/$SID/exec" \
-d '{"command": "docker ps --format \"{{.Names}}\"", "timeout": 120}' | jq -r .exec_id)
# 3. Ergebnis abholen
curl -s -H "Authorization: Bearer $KEY" "https://ssh-proxy.example/$SID/exec/$EID"Spielregeln
- Sessions wiederverwenden. Eine Verbindung pro Befehl verschwendet
Ressourcen und rattert gegen Rate-Limits. Speichere die
session_id(z.B./tmp/vps1_sid) und mache vorher einen Heartbeat. - Targets benennen statt sie zu suchen. Targets sind vorregistriert
(
vps1,pi, …). Der Proxy ist die einzige Wahrheitsquelle — nie IPs in Agent-Code hardcoden. - Für Dateien SFTP statt shell-cat/heredoc. Binärdaten über
execzu schicken korrumpiert die Nutzdaten. Nutze die dedizierten Upload-/Download- Endpoints. - Befehle sauber quoten. Der JSON-Body wird zweimal geparst (HTTP + Shell). Umschließe Remote-Befehle mit einfachen Anführungszeichen und halte sie einzeilig.
- Von Auditing ausgehen. Jeder exec landet im Audit-Log des Proxies — verhalte dich so, als würde der Mensch alles lesen (er kann).
Wann exec NICHT nutzen
- Strukturierten Zustand lesen, der eine API hat (Docker, Datenbanken, die Synapse-Mind-API) — immer die API vor CLI-Output-Parsing bevorzugen.
- Lange laufende interaktive Prozesse.
execist fire-and-forget mit Timeout; nutzenohup+ Statusdatei auf dem Ziel. - Alles Destruktive ohne explizite Anweisung. Der Proxy gibt dir die Macht — der Mensch gibt dir die Erlaubnis.
Fehlerbehandlung
| Symptom | Lösung |
|---|---|
| 401 beim Verbinden | Token abgelaufen — neu aus Memory/Settings lesen, nie aus einem Transkript |
| Session 404 | Session abgelaufen (24h Cap) — neu verbinden |
| exec-Timeout | timeout erhöhen oder Befehl splitten; Last auf dem Ziel prüfen |
| Verstümmelte Dateiinhalte | du hast exec statt SFTP genutzt — auf die SFTP-Endpoints wechseln |