SSH-toegang via proxy
Hoe een LLM-agent veilig commando's uitvoert op externe machines via een SSH-proxy-API in plaats van rauwe SSH-sleutels.
SSH-toegang via proxy
Agenten moeten commando's uitvoeren op externe machines — een container deployen, een log lezen, een config repareren. Rauwe SSH-privésleutels aan een LLM geven is een slecht idee: sleutels belanden in contextvensters, logs en transcripties. Een SSH-proxy lost dit op: hij bezit de credentials, de agent spreekt alleen HTTP.
Het model
LLM ──HTTPS──► SSH-proxy ──SSH──► doelmachines
(bezit sleutels,
auditlog,
ratelimieten)De proxy stelt persistente sessies bloot met een eenvoudig REST-oppervlak:
| Endpoint | Doel |
|---|---|
POST /connect?target=vps1 |
een sessie openen → session_id |
POST /<sid>/exec {command, timeout} |
een commando uitvoeren (async) → exec_id |
GET /<sid>/exec/<exec_id> |
output opvragen |
| SFTP-endpoints | bestandsup-/download, ls, mkdir, rm |
Auth is een Bearer-token — hetzelfde patroon als elke andere API die je gebruikt.
Het uitvoeringspatroon
# 1. verbind een keer, hergebruik de sessie voor de hele taak
SID=$(curl -s -H "Authorization: Bearer $KEY" \
"https://ssh-proxy.example/connect?target=vps1" | jq -r .session_id)
# 2. voer een commando uit
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. vraag het resultaat op
curl -s -H "Authorization: Bearer $KEY" "https://ssh-proxy.example/$SID/exec/$EID"Gedragsregels
- Hergebruik sessies. Per commando verbinden verspilt bronnen en triggert ratelimieten. Bewaar de
session_id(bijv./tmp/vps1_sid) en geef hem een heartbeat vóór hergebruik. - Noem targets, ontdek ze niet. Targets zijn vooraf geregistreerd (
vps1,pi, …). De proxy is de enige bron van waarheid — hardcode nooit IP-adressen in agentcode. - Geef SFTP de voorkeur boven shell cat/heredoc voor bestanden. Escapen van binaire data via
execcorrumpeert payloads. Gebruik de dedicated upload/download-endpoints. - Quote je commando's. De JSON-body wordt twee keer geparsed (HTTP + shell). Wikkel externe commando's in enkele aanhalingstekens en houd ze éénregelig.
- Reken op auditing. Elke exec komt in het auditlog van de proxy — gedraag je alsof de mens alles leest (dat kan).
Wanneer exec NIET gebruiken
- Gestructureerde staat lezen die een API heeft (Docker, databases, de Synapse Mind API) — geef altijd de API de voorkeur boven CLI-output parsen.
- Langlopende interactieve processen.
execis fire-and-forget met timeout; gebruiknohup+ een statusbestand op de target. - Alles destructiefs zonder expliciete instructie. De proxy geeft je de kracht — de mens geeft je de toestemming.
Foutenherstel
| Symptoom | Oplossing |
|---|---|
| 401 bij connect | token verlopen — lees hem opnieuw uit memory/settings, nooit uit een transcript |
| sessie 404 | sessie verlopen (24h-limiet) — verbind opnieuw |
| exec-timeout | verhoog timeout of splits het commando; controleer de belasting van de target |
| gecorrumpeerde bestandsinhoud | je gebruikte exec in plaats van SFTP — schakel over naar de SFTP-endpoints |