CreaRack-SL

Terminal SSH: como se conecta el navegador al Local Agent en localhost:5050 y como se establece la sesion SSH via WebSocket ws/terminal? Protocolo crearack:// y persistencia de sesiones.

Conceptoactiveverificado Fri Jul 03#terminal#local-agent#ssh

Pregunta

Terminal SSH: ¿cómo se conecta el navegador al Local Agent en localhost:5050 y cómo se establece la sesión SSH vía WebSocket ws/terminal? Protocolo crearack:// y persistencia de sesiones.

Respuesta corta

El navegador no habla SSH directamente. Abre un WebSocket contra el Local Agent en 127.0.0.1:5050, y es el Agente —que corre dentro de la LAN del cliente— quien abre la sesión SSH real contra el dispositivo. El Agente actúa de puente cifrado: transporta tus teclas al dispositivo y la salida de vuelta al navegador.

El flujo paso a paso

  1. Detección + auth local: el frontend confirma que el Agente está vivo (fetch a /info) y obtiene el token local del SaaS para autorizar la API local (ver la página de credenciales del Local Agent).
  2. Apertura del WebSocket: ws://127.0.0.1:5050/ws/terminal/{client_id}. Con el Agente vinculado a un SaaS, el primer mensaje debe ser {"action":"auth","token":<token_local>} (la UI lo recibe del SaaS por postMessage SET_AUTH_TOKEN). Sin token válido → el Agente cierra con código 4401 (terminal/agent/routes/terminal.py:255-263).
  3. Conexión SSH: {"action":"connect", "device_id"|"profile_id": ...}. El Agente resuelve las credenciales server-side con su JWT (R3) — fetch_device_credentials / fetch_profile_credentials (terminal.py:315-330) — abre asyncssh con host-key TOFU y responde "Tunnel Established!". El navegador nunca ve la contraseña.
  4. Interacción: cada tecla viaja como {"action":"data", ...} al PTY del dispositivo; la salida vuelve por el mismo WebSocket como {"type":"output"}.

Persistencia de sesiones (reattach)

Al navegar entre páginas el WebSocket se cae, pero la sesión SSH sobrevive. El Agente conserva el puente en memoria (ACTIVE_BRIDGES) y solo pone bridge.websocket = None (log: “Client decoupled (SSH session persists)”, terminal.py:342). Al reconectar con el mismo client_id, si el SSH sigue vivo, el Agente reproduce el output_buffer (te devuelve lo que salió mientras no mirabas) y responde "Tunnel Established!" (terminal.py:265-278). Si el SSH murió mientras estabas desconectado, limpia el puente obsoleto y abre uno nuevo.

El protocolo crearack://

Sí existe (el draft anterior decía que no; es incorrecto). El instalador registra crearack como protocolo URL de Windows en el registro: HKCU\SOFTWARE\Classes\crearack con comando "CreaRackAgent.exe" "%1" (_register_protocol_handler, terminal/agent/core/installer.py:217). Así, un enlace crearack://… desde el navegador lanza o enfoca el Agente local (deep-link), sin depender de que el usuario lo abra a mano.

Seguridad del canal

  • La API local exige Authorization: Bearer <token_local> salvo rutas de bootstrap; el WS de la consola valida el token en el primer mensaje (close 4401). Cierra el DNS-rebinding/CSRF (Raíz 3 de la Auditoría Suprema).
  • Las credenciales del dispositivo nunca las teclea ni relé el navegador: el Agente las obtiene server-side por device_id/profile_id (R3). Cifradas en reposo (Fernet en el SaaS, DPAPI en el Agente).
  • Host-key TOFU (network/host_keys.py): graba la clave del dispositivo en la 1ª conexión y rechaza si cambia (detección de MITM).

Véase también

  • [[concept—general—como-obtiene-el-local-agent-sus-credenciales-de-vi]]
  • [[concept—general—como-detecta-el-frontend-si-el-local-agent-esta-co]]