Configuración de una Máquina Remota para Programación con Agentes de IA
Configura Claude Code en un servidor remoto con Tailscale, tmux, mosh y systemd, con SSH por claves, secretos y acceso privado seguro.
El stack mínimo para ejecutar Claude Code en una máquina remota consiste en un VPS Linux o una máquina siempre encendida, Tailscale para una malla WireGuard privada que no requiere reenvío de puertos ni DNS dinámico, tmux para sesiones de terminal persistentes que sobreviven a las desconexiones, y mosh o SSH como capa de conexión — todo gratuito, todo componible y todo más duradero que las herramientas envolventes del momento. Esta guía recorre ese stack de principio a fin para el caso más común que los tutoriales existentes omiten: un agente de programación en un VPS en la nube o una máquina de repuesto, reforzado y controlado remotamente desde un portátil o un teléfono.
El problema que vale la pena resolver es la persistencia. Cuando ejecutas un agente de programación localmente y cierras el portátil, la sesión muere. Una máquina remota mantiene el agente activo durante las desconexiones, te da control y un costo predecible frente a una plataforma gestionada, y te permite dirigir el trabajo desde cualquier lugar. El inconveniente — poco documentado en todas partes — es que una máquina que ejecuta un agente con acceso a la shell y claves de API es una superficie de ataque seria, por lo que esta guía prioriza la seguridad en lugar de añadirla al final.
Puntos Clave
- Existen dos objetivos distintos que los lectores confunden habitualmente: ejecutar un agente CLI como Claude Code en una sesión persistente a la que conectarse y desconectarse (el patrón tmux), y alojar un agente como un servicio HTTP siempre activo (el patrón systemd) — cada uno requiere una configuración diferente y una postura de seguridad diferente.
- Tailscale construye una malla cifrada con WireGuard entre tus dispositivos; tu máquina remota obtiene una dirección
100.x.x.xestable accesible desde cualquier dispositivo autenticado sin abrir puertos en el firewall ni configurar DNS dinámico. - Una máquina remota que ejecuta un agente de programación tiene acceso a la shell, claves de API y credenciales de repositorio — vincular el puerto del agente a
0.0.0.0en un VPS público, aunque sea brevemente para una prueba de humo, pone los tres en riesgo. - Nunca pongas claves de API en la línea
Environment=de un archivo de unidad systemd; usaEnvironmentFile=para mantenerlas fuera de la salida desystemctl show, y recurre aLoadCredential=para una protección real de secretos. - Claude Code ahora incluye Control Remoto nativo y Sesiones Remotas en la nube, pero ambos son de sesión única y están vinculados a un proceso activo; el stack DIY es lo que necesitas para configuraciones siempre activas, sin interfaz o con múltiples proyectos.
Por Qué una Máquina Remota, y DIY vs. las Alternativas
Una máquina remota es la mejor opción cuando necesitas un agente de programación que sobreviva a las desconexiones, funcione de forma desatendida y sea accesible desde cualquier dispositivo — sin pagar la tarifa por usuario de una plataforma ni aceptar sus limitaciones de sandbox. El precio es operativo: tú eres responsable de la seguridad, el tiempo de actividad y los parches. Para los desarrolladores ya familiarizados con SSH y Git, ese precio suele valer la pena.
Antes de construir nada, decide cuál de estos tres enfoques se adapta mejor a tu caso. El panorama cambió a principios de 2026, y el planteamiento anterior de “necesitas tmux y SSH para usar Claude Code remotamente” ya es incompleto.
| Enfoque | Qué es | Ideal para | Limitaciones |
|---|---|---|---|
| Control Remoto Nativo / Sesiones Remotas | Las funciones remotas integradas de Claude Code — control HTTPS de solo salida desde el teléfono o el navegador, más sesiones en la nube alojadas por Anthropic | Control de sesión única sin infraestructura | Sesión única; vinculado a un proceso activo; funciona bajo las condiciones de terceros |
| Máquina remota DIY | Tu VPS o máquina de repuesto ejecutando el agente bajo tmux o systemd | Trabajo siempre activo, sin interfaz y con múltiples proyectos que controlas de principio a fin | Tú eres responsable de la seguridad y el tiempo de actividad |
| Plataformas de agentes gestionadas | Productos alojados que orquestan agentes en paralelo | Equipos que quieren herramientas de fusión refinadas sin operaciones | Dependencia del proveedor; costo recurrente |
Anthropic lanzó el Control Remoto nativo como vista previa de investigación y las Sesiones Remotas en la nube a principios de 2026 (CLI v2.1.x a mediados de 2026). El Control Remoto utiliza HTTPS de solo salida — sin puertos de entrada — para permitirte dirigir una sesión desde tu teléfono. Es genuinamente útil, pero es de sesión única y muere con el terminal que lo inició. Claude Code en sí se ejecuta como una herramienta CLI sin un daemon en segundo plano para sesiones interactivas; la solicitud de función abierta para un modo daemon sin interfaz confirma que cerrar el terminal termina la sesión. Para configuraciones siempre activas, sin interfaz o con múltiples proyectos, se construye sobre primitivos duraderos y se añaden herramientas de conveniencia encima.
La categoría de plataformas gestionadas existe y está bien financiada, pero para un desarrollador que ya vive en SSH y Git, una máquina autoalojada ofrece más control a menor costo. Esta guía cubre el camino DIY.
Los Dos Patrones: tmux vs. systemd
Existen dos objetivos distintos que los lectores confunden habitualmente, y requieren configuraciones diferentes. Ejecutar un agente CLI de programación como Claude Code en una sesión a la que conectarse y desconectarse es el patrón tmux. Alojar un agente como un servicio HTTP siempre activo accesible mediante API es el patrón systemd. Elegir el incorrecto es el error estructural más común en las configuraciones de agentes remotos.
| tmux (interactivo) | systemd (servicio) | |
|---|---|---|
| Caso de uso | Agentes CLI que diriges en tiempo real | Agentes HTTP que funcionan de forma desatendida |
| Reinicio tras fallo | Reconexión manual | Restart=always |
| Registros | Historial de la sesión | journalctl -u <servicio> |
| Secretos | Variables de entorno de shell o .env importado | EnvironmentFile= / LoadCredential= |
| Acceso móvil | mosh + tmux attach | curl / navegador mediante proxy inverso |
Usa tmux cuando quieras observar y dirigir el agente — escribir prompts, aprobar acciones, leer la salida. Usa systemd cuando el agente sea un servicio que acepta solicitudes y funciona sin un humano conectado. La mayoría de las personas que ejecutan Claude Code de forma interactiva quieren tmux. La mayoría de las personas que exponen un agente detrás de una API quieren systemd. Algunas configuraciones usan ambos.
Ejecutar Claude Code Remotamente: El Stack Gratuito Canónico
El stack gratuito canónico para ejecutar Claude Code remotamente es una máquina Linux, Tailscale para la capa de red privada, OpenSSH más mosh para la conexión, y tmux para las sesiones persistentes. Esta sección es la secuencia de configuración lista para copiar y pegar. Ejecuta el refuerzo de seguridad de la siguiente sección antes de tratar la máquina como producción.
Discover how at OpenReplay.com.
Instalar Tailscale
Tailscale construye una malla cifrada con WireGuard entre tus dispositivos: una vez instalado, tu máquina remota obtiene una dirección 100.x.x.x estable accesible desde cualquier dispositivo autenticado sin abrir puertos en el firewall, configurar DNS dinámico ni tocar tu router. El protocolo subyacente de Tailscale es WireGuard, y el plan Personal gratuito cubre hasta 6 usuarios con dispositivos ilimitados de propiedad del usuario según la revisión de precios de abril de 2026 — verifica los límites actuales antes de depender de ellos.
Instálalo en la máquina remota siguiendo la documentación oficial de instalación:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
El comando tailscale up imprime una URL de autenticación. Ábrela, inicia sesión y la máquina se une a tu tailnet. Ejecuta tailscale ip -4 para obtener su dirección 100.x.x.x. Instala Tailscale en tu portátil y teléfono de la misma manera, autentícalos en la misma cuenta, y los tres dispositivos podrán comunicarse directamente entre sí.
Una advertencia que rompe las configuraciones silenciosamente — algo que nos ocurrió a nosotros mismos: no habilites el servidor SSH integrado de Tailscale con tailscale up --ssh si planeas usar mosh. Tailscale SSH ejecuta su propio servidor SSH, no OpenSSH, y mosh necesita ejecutar mosh-server sobre OpenSSH real y analizar su salida para iniciar una sesión — algo que Tailscale SSH no soporta. Mantén OpenSSH instalado y en ejecución junto a Tailscale para que mosh pueda conectarse.
Configurar SSH y mosh
SSH te da la shell; mosh la mantiene utilizable sobre conexiones móviles inestables al sobrevivir a cambios de IP y roaming. mosh requiere que un puerto UDP en el rango 60000–61000 sea accesible, según la documentación de mosh. En una malla Tailscale, ese rango ya es accesible entre dispositivos autenticados, por lo que no se necesita configuración del router.
Instala mosh tanto en el servidor como en tu cliente:
sudo apt update && sudo apt install -y mosh tmux
Conéctate desde tu portátil usando la dirección de Tailscale:
mosh youruser@100.x.x.x
Si mosh no logra conectarse, recurre a ssh youruser@100.x.x.x para confirmar que la máquina es accesible, luego verifica que OpenSSH (no Tailscale SSH) esté respondiendo.
Crear Sesiones tmux Persistentes
tmux es lo que mantiene el agente activo después de desconectarte. Inicia una sesión, ejecuta Claude Code dentro de ella, desconéctate, y el agente sigue trabajando; reconéctate más tarde desde cualquier dispositivo para verificar o dirigirlo.
Nombra las sesiones tmux según el proyecto, no según la herramienta. Usa tmux new-session -s myproject en lugar de tmux new-session -s claude — cuando estés ejecutando tres agentes en tres repositorios, tmux ls necesita decirte qué sesión es cuál:
tmux new-session -s myproject
# dentro de la sesión:
cd ~/code/myproject
claude
# desconéctate con Ctrl-b y luego d
El indicador -s nombra la sesión. Reconéctate desde cualquier lugar con tmux attach -t myproject, o lista todo lo que está en ejecución con tmux ls. Ese ciclo de desconexión y reconexión es el bucle completo del agente remoto interactivo: cierra el portátil, reconéctate desde el teléfono mediante mosh, lee lo que hizo el agente, dale la siguiente instrucción.
La Línea Base de Seguridad
Una máquina remota que ejecuta un agente de programación es un objetivo de ataque de alto valor: tiene acceso a la shell, claves de API y, con frecuencia, credenciales de repositorio. Vincular el puerto del agente a 0.0.0.0 en un VPS público, aunque sea brevemente para una prueba de humo, pone los tres en riesgo. Refuerza la máquina antes de confiarle cualquier cosa. Esta sección no es opcional.
Solo Claves SSH
Deshabilita la autenticación por contraseña para que la única forma de acceder sea con una clave que tú poseas. Edita /etc/ssh/sshd_config y establece:
PasswordAuthentication no
PermitRootLogin no
La directiva PasswordAuthentication no deshabilita el inicio de sesión por contraseña, y PermitRootLogin no bloquea el SSH directo como root — ambas documentadas en el manual de sshd_config. Un error común es editar el archivo incorrecto; estas directivas pertenecen a /etc/ssh/sshd_config, no a una configuración de cliente. Aplícalas con sudo systemctl restart ssh. Confirma que tu clave funciona en una sesión separada antes de cerrar la que tienes, para que un error tipográfico no te deje sin acceso.
Mantén la Malla Privada como Privada
La malla de Tailscale ya está autenticada, pero puedes restringir qué dispositivos acceden a qué puertos usando ACLs de Tailscale. Una política ACL restringe el tráfico entre dispositivos etiquetados — por ejemplo, permitiendo que solo tu portátil y teléfono lleguen a la máquina del agente, y nada más en la tailnet. Para una configuración de un solo usuario, el “permitir todo dentro de tu tailnet” predeterminado es razonable; añade ACLs cuando otras personas o dispositivos no confiables compartan la red.
Nunca Vincules el Agente a 0.0.0.0
Cuando hagas pruebas de humo de un servicio vinculado localmente, usa curl http://127.0.0.1:9000/health desde el propio servidor en lugar de vincular temporalmente a 0.0.0.0. En un VPS sin una regla de firewall que bloquee el puerto 9000, ese cambio de una línea expone tu agente a la internet pública durante todo el tiempo que el proceso esté en ejecución. Vincula a 127.0.0.1 y accede al servicio a través de Tailscale o un proxy inverso — nunca directamente.
Mantén los Secretos Fuera del Archivo de Unidad
Nunca pongas claves de API en la línea Environment= de un archivo de unidad systemd — aparecen en la salida de systemctl show. Usa EnvironmentFile=/etc/myagent/secrets.env para mantener los valores fuera del archivo de unidad y de systemctl show, según la documentación de systemd.exec. Restringe los permisos del archivo:
sudo mkdir -p /etc/myagent
sudo chmod 640 /etc/myagent/secrets.env
sudo chown root:myagent /etc/myagent/secrets.env
Sé preciso sobre lo que esto te proporciona: EnvironmentFile= mantiene los secretos fuera del archivo de unidad y de systemctl show, pero una vez cargados, los valores siguen siendo legibles en el entorno del proceso en ejecución y a través de D-Bus. Para una protección real de secretos, usa LoadCredential= de systemd, documentado en la guía de credenciales de systemd, que pasa las credenciales a través de un directorio restringido en lugar del entorno del proceso.
Mantener Activo un Agente de Servicio: La Unidad systemd
Para un agente que funciona como un servicio HTTP siempre activo en lugar de una sesión interactiva, usa una unidad systemd vinculada a 127.0.0.1 con Restart=always. Este es el patrón systemd: el servicio se inicia al arrancar, se reinicia tras un fallo, registra en el journal y nunca toca directamente un puerto público. EnvironmentFile= es una directiva central de systemd de larga trayectoria, disponible en todas las versiones actuales de systemd, según la documentación de systemd.exec.
Crea /etc/systemd/system/my-agent.service:
[Unit]
Description=My Agent Service
After=network.target
[Service]
User=myagent
Group=myagent
WorkingDirectory=/home/myagent/app
EnvironmentFile=/etc/myagent/secrets.env
ExecStart=/home/myagent/app/venv/bin/uvicorn main:app --host 127.0.0.1 --port 9000
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Cada directiva cumple su función. After=network.target espera a que la red esté disponible. Ejecutar con un User/Group dedicado limita el radio de impacto si el agente se ve comprometido. EnvironmentFile= carga los secretos desde el archivo con permisos restringidos. ExecStart ejecuta el servidor directamente desde el entorno virtual del proyecto — sin scripts intermediarios — vinculado a 127.0.0.1 para que el puerto nunca sea accesible públicamente. Restart=always con RestartSec=5 reinicia el servicio cinco segundos después de cualquier fallo.
Habilítalo e inícialo:
sudo systemctl daemon-reload
sudo systemctl enable --now my-agent
sudo systemctl status my-agent
Para exponer el servicio de forma segura, coloca un proxy inverso delante del puerto vinculado a localhost. Un proxy_pass de nginx a 127.0.0.1 mantiene el upstream inaccesible directamente desde el exterior mientras termina TLS en el borde:
server {
listen 443 ssl;
server_name agent.example.com;
ssl_certificate /etc/letsencrypt/live/agent.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/agent.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Aprovisiona el certificado con Certbot, que automatiza la emisión y renovación de Let’s Encrypt. Para una configuración de un solo usuario, a menudo no necesitas un nombre de host público en absoluto — acceder al servicio a través de Tailscale en 100.x.x.x:9000 desde dispositivos autenticados evita por completo la exposición pública.
Acceder a la Máquina desde el Móvil
Accedes a un agente remoto desde un teléfono de la misma manera que desde un portátil — a través de Tailscale, con un cliente de terminal o un terminal en el navegador delante de él. El panorama de herramientas en este ámbito está evolucionando rápidamente a mediados de 2026; trátalo como mejoras opcionales, no como infraestructura crítica.
Las opciones duraderas son un cliente SSH móvil (varios soportan conexiones persistentes y autenticación basada en claves) más tmux, o mosh para conexiones que sobreviven a cambios de red. Sobre eso se sitúan las herramientas de terminal en el navegador. ttyd expone un terminal a través de la web. vibetunnel (con licencia MIT, principalmente para Mac con una compilación npm multiplataforma para Linux) hace de proxy de un terminal en el navegador y fue construido para monitorear agentes Claude Code, con acceso remoto a través de Tailscale. Si ejecutas cualquier terminal en el navegador, mantenlo vinculado a localhost y accede a él a través de Tailscale — exponer un terminal web públicamente es el mismo error de 0.0.0.0 en una forma diferente.
El Control Remoto nativo de Claude Code cubre el caso ligero: HTTPS de solo salida, control desde un teléfono, sin puertos de entrada. Es la forma más rápida de interactuar con una sesión activa única. El stack DIY sigue siendo lo que usas cuando el trabajo supera la vida de cualquier terminal.
El Flujo de Trabajo Diario
El ciclo de redespliegue diario en una máquina remota son tres comandos: obtener el código, reiniciar el servicio y seguir los registros. Para un agente gestionado con systemd, es:
cd ~/app && git pull origin main
source venv/bin/activate && pip install -r requirements.txt
sudo systemctl restart my-agent
journalctl -u my-agent -f
git pull obtiene el código más reciente, la instalación de dependencias recoge los nuevos requisitos, systemctl restart reinicia el servicio, y journalctl -u my-agent -f sigue los registros del servicio en tiempo real para que puedas confirmar un inicio limpio — journalctl lee el journal de systemd, documentado en freedesktop.org. Para un agente tmux interactivo, el ciclo es aún más simple: reconéctate con tmux attach -t myproject, ejecuta git pull y deja que el agente continúe.
Conclusión
Construye sobre los primitivos que sobreviven a las herramientas del momento: SSH y Tailscale para la red, tmux para las sesiones que diriges, systemd para los servicios que funcionan de forma desatendida, y una línea base de seguridad que mantiene el puerto del agente fuera de la internet pública. Elige el patrón tmux o el patrón systemd de forma deliberada según si estás dirigiendo un agente o alojando uno, refuerza la máquina antes de confiarle claves de API, y luego añade el Control Remoto nativo o un terminal en el navegador como conveniencia. Comienza con una máquina Linux nueva y el comando de instalación de Tailscale mencionado anteriormente — el resto se puede componer a partir de ahí.
Preguntas Frecuentes
¿Por qué mi agente sigue muriendo cuando me desconecto de SSH?
Una sesión SSH simple vincula el proceso del agente a tu terminal, por lo que cerrar la conexión envía una señal de cuelgue que lo termina. Ejecuta el agente dentro de una sesión tmux en su lugar: iníciala con tmux new-session -s myproject, lanza el agente y luego desconéctate con Ctrl-b seguido de d. El proceso sigue ejecutándose en el servidor, y puedes reconectarte más tarde desde cualquier dispositivo con tmux attach -t myproject.
¿Cuándo debería usar el Control Remoto nativo de Claude Code en lugar de una configuración DIY con tmux y SSH?
Usa el Control Remoto nativo cuando solo necesites dirigir una sesión activa única desde tu teléfono o navegador sin infraestructura, ya que utiliza HTTPS de solo salida y no abre puertos de entrada. Es de sesión única y muere con el terminal que lo inició, por lo que para trabajo siempre activo, sin interfaz o con múltiples proyectos que deba sobrevivir a las desconexiones, construye el stack DIY con SSH, Tailscale, tmux y systemd.
¿Funciona mosh sobre una red Tailscale?
Sí, mosh funciona sobre una malla Tailscale porque el rango de puertos UDP 60000 a 61000 que requiere ya es accesible entre dispositivos autenticados, por lo que no se necesita configuración del router. El único caso de fallo es habilitar el servidor SSH propio de Tailscale con tailscale up --ssh, lo que reemplaza OpenSSH; mosh debe ejecutar mosh-server sobre OpenSSH real para iniciar la sesión, así que mantén OpenSSH instalado y en ejecución junto a Tailscale.
¿Cuál es la diferencia entre usar EnvironmentFile y LoadCredential para secretos en systemd?
EnvironmentFile carga valores desde un archivo externo para que no aparezcan en el archivo de unidad ni en la salida de systemctl show, pero los valores siguen siendo legibles en el entorno del proceso en ejecución y a través de D-Bus. LoadCredential es más seguro porque pasa los secretos a través de un directorio restringido en lugar del entorno del proceso, manteniéndolos fuera del alcance del entorno del proceso en ejecución. Usa EnvironmentFile para configuración y LoadCredential para secretos genuinos.