# Acceso SSH vía proxy Los agentes necesitan ejecutar comandos en máquinas remotas — desplegar un contenedor, leer un log, arreglar una configuración. Entregar claves privadas SSH crudas a un LLM es una mala idea: las claves acaban en ventanas de contexto, logs y transcripciones. Un proxy SSH lo resuelve: él posee las credenciales, el agente solo habla HTTP. ## El modelo ``` LLM ──HTTPS──► Proxy SSH ──SSH──► máquinas objetivo (posee las claves, log de auditoría, límites de tasa) ``` El proxy expone sesiones persistentes con una superficie REST sencilla: | Endpoint | Propósito | |---|---| | `POST /connect?target=vps1` | abrir una sesión → `session_id` | | `POST //exec` `{command, timeout}` | ejecutar un comando (async) → `exec_id` | | `GET //exec/` | consultar la salida | | Endpoints SFTP | subida/descarga de archivos, `ls`, `mkdir`, `rm` | La autenticación es un token Bearer — el mismo patrón que todas las demás APIs que usas. ## El patrón de ejecución ```bash # 1. conecta una vez, reutiliza la sesión para toda la tarea SID=$(curl -s -H "Authorization: Bearer $KEY" \ "https://ssh-proxy.example/connect?target=vps1" | jq -r .session_id) # 2. ejecuta un comando 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. consulta el resultado curl -s -H "Authorization: Bearer $KEY" "https://ssh-proxy.example/$SID/exec/$EID" ``` ## Reglas de uso 1. **Reutiliza sesiones.** Conectar por comando desperdicia recursos y dispara límites de tasa. Guarda el `session_id` (p. ej. `/tmp/vps1_sid`) y hazle heartbeat antes de reutilizarlo. 2. **Nombra los targets, no los descubras.** Los targets están pre-registrados (`vps1`, `pi`, …). El proxy es la única fuente de verdad — nunca hardcodees IPs en código de agente. 3. **Prefiere SFTP a cat/heredoc de shell para archivos.** Escapar datos binarios a través de `exec` corrompe los payloads. Usa los endpoints dedicados de subida/descarga. 4. **Cita tus comandos.** El cuerpo JSON se parsea dos veces (HTTP + shell). Envuelve los comandos remotos en comillas simples y mantenlos en una sola línea. 5. **Asume auditoría.** Cada exec queda en el log de auditoría del proxy — compórtate como si el humano leyera todo (puede hacerlo). ## Cuándo NO usar exec - Leer estado estructurado que tiene una API (Docker, bases de datos, la Mind API de Synapse) — siempre prefiere la API a parsear salida de CLI. - Procesos interactivos de larga duración. `exec` es fire-and-forget con timeout; usa `nohup` + un archivo de estado en el objetivo. - Cualquier cosa destructiva sin instrucción explícita. El proxy te da el poder — el humano te da el permiso. ## Recuperación de errores | Síntoma | Solución | |---|---| | 401 al conectar | token expirado — relee de memoria/settings, nunca de una transcripción | | sesión 404 | sesión expirada (tope 24h) — reconecta | | timeout de exec | sube `timeout` o divide el comando; revisa la carga del objetivo | | contenido de archivo corrupto | usaste `exec` en vez de SFTP — cambia a los endpoints SFTP |