Seguridad del servidor de OpenCode: cómo ejecutar opencode serve y opencode web de forma segura
opencode serve expone una API HTTP que puede leer archivos y ejecutar comandos de shell. Cómo mantenerlo en localhost, poner contraseña, añadir TLS y acceder en remoto.
- CLI
- 0.2.17
- Ref de preview
- a2c45c8
En resumen
opencode serve y opencode web ejecutan un servidor HTTP cuya API puede leer archivos, ejecutar comandos de shell, cambiar la configuración y definir credenciales de proveedores. Trata el acceso a él como acceso de shell a la máquina.
Una configuración segura, por orden de importancia:
- Mantén el hostname por defecto,
127.0.0.1. Usa0.0.0.0o--mdnssolo en una red que controles. - Define
OPENCODE_SERVER_PASSWORDsiempre que el servidor sea accesible desde algo que no sea tu propia máquina. La documentación de OpenCode dice que sin ella el servidor no tiene protección. - Pon TLS delante si el tráfico cruza una red. La autenticación básica sobre HTTP sin cifrar envía la contraseña de forma que cualquiera en el camino puede leerla.
- Accede a través de una red privada o un túnel, como SSH o Tailscale, en lugar de un puerto público.
- Mantén
--corsacotado. Añade solo orígenes que gestiones tú.
El problema
El diseño cliente-servidor de OpenCode es uno de sus puntos fuertes. La TUI habla con un servidor local, así que también puedes manejarlo desde un navegador, un plugin del IDE, un script u otro ordenador. La documentación muestra cómo hacerlo con una sola opción:
opencode web --port 4096 --hostname 0.0.0.0Esa línea está bien en un portátil en casa. En la red de una cafetería, la LAN de una oficina compartida o una máquina virtual en la nube con el grupo de seguridad abierto, publica la API de control de un agente de programación para cualquiera que llegue al puerto. La solución son unos pocos ajustes, y es fácil saltárselos cuando lo único que quieres es conectar el móvil.
Qué expone el servidor de OpenCode
Según la documentación del servidor de OpenCode, consultada el 26 de octubre de 2026, la API incluye:
| Endpoint | Qué hace |
|---|---|
POST /session/:id/shell | Ejecuta un comando de shell |
POST /session/:id/message | Envía un prompt al agente |
GET /file/content?path= | Lee un archivo |
GET /find?pattern= | Busca en el contenido de los archivos |
PATCH /config | Actualiza la configuración |
PUT /auth/:id | Define credenciales de proveedores |
POST /mcp | Añade un servidor MCP |
POST /session/:id/permissions/:permissionID | Responde a una solicitud de permiso |
GET /doc | La especificación OpenAPI 3.1 |
Quien pueda llamar a estos endpoints puede hacer lo mismo que tú en una terminal de esa máquina, y responder por ti a los prompts de permisos del agente. Ese es el modelo de amenaza de todo lo que sigue.
Los valores por defecto del servidor de OpenCode
Según la documentación del servidor:
| Opción | Por defecto | Notas |
|---|---|---|
--port | 4096 | |
--hostname | 127.0.0.1 | Solo loopback |
--mdns | false | Al activarlo, el hostname pasa a 0.0.0.0 y anuncia opencode.local |
--cors | ninguno | Orígenes de navegador adicionales permitidos |
Los valores por defecto son seguros por sí solos. Ejecutar opencode sin argumentos inicia la TUI y un servidor en un puerto y hostname aleatorios, que la TUI usa como backend. El riesgo aparece al cambiar el hostname o activar mDNS.
Paso 1: mantén OpenCode en localhost salvo que necesites más
Si el único cliente está en la misma máquina, no pases --hostname:
opencode serveComprueba qué está escuchando:
# Linux
ss -ltnp | grep 4096
# macOS
lsof -nP -iTCP:4096 -sTCP:LISTENLo que quieres ver es 127.0.0.1:4096, no 0.0.0.0:4096 ni *:4096.
Paso 2: pon una contraseña al servidor de OpenCode
El servidor admite autenticación HTTP básica mediante variables de entorno. Se aplica tanto a opencode serve como a opencode web:
export OPENCODE_SERVER_PASSWORD="$(openssl rand -base64 32)"
opencode serveEl usuario por defecto es opencode. Define OPENCODE_SERVER_USERNAME para cambiarlo. La documentación web incluye una advertencia: si OPENCODE_SERVER_PASSWORD no está definida, el servidor no tiene protección, algo que describe como aceptable en uso local pero que conviene definir para el acceso por red.
Para conectar una TUI a un servidor protegido con contraseña:
opencode attach http://10.20.30.40:4096 --password "$OPENCODE_SERVER_PASSWORD"--password toma por defecto OPENCODE_SERVER_PASSWORD, así que si la variable está definida en esa shell puedes omitir la opción.
No dejes la contraseña en el historial de la shell ni en dotfiles de repositorios compartidos. Sirve un gestor de contraseñas o un archivo que solo tú puedas leer y que se cargue al arrancar.
Paso 3: añade TLS delante del servidor de OpenCode
La autenticación básica envía las credenciales con cada petición, codificadas pero sin cifrar. Sobre HTTP sin cifrar en una red de la que no te fías del todo, equivale a no tener contraseña. Opciones:
-
Un proxy inverso como Caddy o nginx, que termina HTTPS y reenvía a
127.0.0.1:4096. El servidor de OpenCode se queda en loopback. -
Un túnel SSH, que cifra la conexión sin abrir puertos nuevos:
ssh -N -L 4096:127.0.0.1:4096 you@serverDespués apunta el cliente a
http://127.0.0.1:4096en tu propia máquina. -
Una red privada como Tailscale o WireGuard, que cifra el tráfico entre tus dispositivos. Úsala igualmente con contraseña, porque cualquier otro equipo de esa red puede llegar al puerto.
Cloudflare Tunnel vs Tailscale Funnel vs ngrok compara las opciones de túnel. Ten cuidado con todo lo que publique el puerto en internet. Una URL pública con autenticación básica es una shell protegida solo por contraseña.
Paso 4: limita quién puede llegar al puerto de OpenCode
- En una máquina virtual en la nube, no abras el 4096 en el grupo de seguridad. Accede por SSH o por una red privada.
- En un servidor doméstico, no lo incluyas en la redirección de puertos del router.
- Con mDNS, recuerda que
--mdnsescucha en0.0.0.0. Es cómodo en una red doméstica y poco adecuado para una Wi-Fi compartida. - Con un cortafuegos en el equipo, permite el puerto solo desde las direcciones que lo necesiten.
Paso 5: mantén CORS acotado
--cors añade orígenes de navegador que pueden llamar al servidor. Cada origen que añades es un sitio web cuyos scripts pueden hablar con tu agente desde un navegador que llegue a él. Añade solo frontends que gestiones tú, con el origen exacto:
opencode serve --cors https://app.example.comPaso 6: reduce el alcance de un error en la máquina
Aun con un buen control de acceso, el servidor se ejecuta con tu usuario. Algunos hábitos limitan lo que puede hacer un error:
- En un servidor compartido, ejecuta OpenCode con un usuario aparte, con acceso a los repositorios que necesita y sin credenciales de producción.
- Mantén estrictas las reglas de permisos para los comandos de shell. Un cliente remoto que responde "permitir" sigue siendo tú permitiéndolo.
- Detén el servidor cuando termines. Un
opencode serveen marcha durante semanas es una exposición permanente.
Acceder a OpenCode desde el móvil sin abrir un puerto
El motivo habitual para escuchar en 0.0.0.0 es usar OpenCode desde otro dispositivo. Eso también se puede hacer sin que el servidor de OpenCode escuche en nada más que loopback.
Si quieres manejar OpenCode desde el móvil sin exponer su servidor, Happier es una app de código abierto para ejecutar y orquestar Claude Code, Codex, OpenCode y otros agentes entre dispositivos, desde el móvil, el escritorio o la web.
Cómo trata el servidor de OpenCode que gestiona:
- Solo loopback. Happier inicia su servidor de OpenCode gestionado con
--hostname=127.0.0.1y un puerto local libre, y solo reutiliza un servidor gestionado cuya dirección sea loopback. - Una contraseña por cada servidor gestionado. Si defines
OPENCODE_PASSWORDuOPENCODE_SERVER_PASSWORD, Happier usa la tuya. Si no, genera una para ese servidor y la guarda en un archivo de estado legible solo por el propietario en~/.happier/opencode/managed-servers/. - La contraseña no sale de tu máquina. La documentación de Happier dice que se pasa al servidor mediante el entorno, nunca se escribe en los registros del servidor de OpenCode de Happier y nunca se envía a un endpoint remoto.
- El acceso remoto pasa por Happier, no por el puerto de OpenCode. La app del móvil, de escritorio o web habla con el daemon de Happier en tu ordenador a través del relay. El contenido de las sesiones va cifrado de extremo a extremo por defecto. Los metadatos como los ids de sesión y las marcas de tiempo no. También puedes autoalojar el relay.
Los prompts de permisos de OpenCode llegan al móvil y los respondes allí. happier attach <session-id> vuelve a abrir la TUI de OpenCode de la sesión en la misma máquina. La configuración está en Cómo usar Happier desde el móvil. Happier está en GitHub, puedes descargarlo aquí y hay un Discord.
Solución de problemas
Todas las peticiones devuelven 401
El cliente no envía la contraseña que espera el servidor. Comprueba que el OPENCODE_SERVER_PASSWORD del cliente coincide con el del servidor, y que el usuario coincide si cambiaste OPENCODE_SERVER_USERNAME. Algunas versiones recientes de OpenCode leen otro nombre de variable, así que compara opencode --version con la documentación de tu versión.
El servidor es accesible desde otras máquinas y no debería
Comprueba la dirección de escucha con ss -ltnp o lsof. Si pone 0.0.0.0 o *, busca --hostname 0.0.0.0 o --mdns en el comando o en un archivo de servicio.
El navegador bloquea las peticiones de un frontend propio
Añade el origen exacto del frontend con --cors. No uses un comodín.
opencode attach no conecta por SSH
Comprueba que el túnel está activo y apunta a 127.0.0.1:4096 en el lado remoto. Conéctate a http://127.0.0.1:4096 en local, no a la IP remota.
Preguntas frecuentes
¿opencode serve es seguro por defecto?
Escucha en 127.0.0.1, así que otras máquinas no pueden llegar a él. Cualquier proceso de la misma máquina sí puede. Sin OPENCODE_SERVER_PASSWORD no hay autenticación.
¿opencode web usa la misma contraseña?
Sí. La documentación de OpenCode dice que OPENCODE_SERVER_PASSWORD se aplica tanto a opencode serve como a opencode web.
¿Se puede exponer OpenCode a internet?
Se puede, pero la API ejecuta comandos de shell. Si no te queda otra, usa TLS, una contraseña robusta e idealmente una capa de acceso delante, como una VPN o un proxy con verificación de identidad.
¿El endpoint de la especificación OpenAPI es un riesgo?
/doc describe la API. No da acceso por sí mismo, pero facilita explorar la superficie. Está detrás de la misma contraseña que el resto.
Guías relacionadas
- Expón tu panel de forma segura
- Cómo acceder a Happier desde el móvil con Tailscale
- Cómo autoalojar el relay de Happier
- Cómo bifurcar sesiones de Codex y OpenCode (desde su UI/TUI o desde el móvil)
- Cómo ejecutar Claude Code, Codex y OpenCode en un servidor de casa y revisar el progreso desde el navegador del móvil