# KiraDesktop Sistema de escritorios virtuales remotos (X11 + XFCE) pensado para **captura de streams con protección DRM (Widevine L3) reproducidos en Firefox**. Cada instancia levanta un escritorio Linux headless, expone acceso VNC para control/depuración y ofrece una API REST que produce un stream de vídeo+audio en formato MPEG-TS (vía `ffmpeg`) listo para consumir con cualquier reproductor/pipeline aguas abajo. La idea general: como el contenido DRM no se puede volcar "en crudo" (el decodificador protege los frames), se renderiza en una sesión X11 real dentro de Firefox y se captura la salida de pantalla (X11 grab) + audio (PulseAudio null-sink), re-codificando con `ffmpeg` a H.264/AAC en MPEG-TS. El resultado es funcionalmente equivalente a "grabar la pantalla" del escritorio remoto. ## Arquitectura: variante CPU vs variante GPU ### Variante CPU (`cpu/`) - Contenedores LXC (Proxmox `pct`), clonados: `kiradesktop-cpu-1` ... `kiradesktop-cpu-12`. Son **12 instancias idénticas** en el cluster, cada una con **1 escritorio** por contenedor. - Servidor VNC: `Xtigervnc` (framebuffer virtual, no requiere GPU). - Captura: `ffmpeg` con `-f x11grab` + encoder software `libx264` (preset `superfast`, escalado a 1280x720 para aliviar la carga de CPU aunque el VNC se sirve en 1080p). - Cada contenedor corre un único proceso (`kiradesktop-cpu.py`) que gestiona ese único escritorio (`/desktop/0/...`). - Incluye `kiradesktop.py`, una versión anterior/backup del mismo script. Ver sección "Diferencias" más abajo. ### Variante GPU (`gpu/`) - Una VM KVM (`kirastream-gpu1`, Proxmox VM id 211) con GPU NVIDIA pasada por passthrough/vGPU. - Servidor VNC: `x11vnc` sobre sesiones `Xorg` reales con el driver NVIDIA (permite aceleración GLX/VDPAU y decodificación por hardware NVDEC/VA-API dentro de Firefox: `LIBVA_DRIVER_NAME=nvidia`, `MOZ_X11_EGL=1`). - Captura: `ffmpeg` con `-f x11grab` + encoder por hardware `h264_nvenc`. - Un único proceso (`kiradesktop-gpu.py`) gestiona **hasta 6 escritorios en paralelo** (`/desktop/{0..5}/...`), cada uno con su propio display (`:1`-`:6`), puerto VNC (`5901`-`5906`) y PulseAudio aislado. ## API REST (puerto 8900 en ambas variantes) | Método | Ruta | Descripción | |--------|-----------------------------------------|---------------------------------------| | GET | `/health` | Estado de escritorio(s) | | POST | `/desktop/{id}/start` | Arranca el escritorio `id` | | POST | `/desktop/{id}/stop` | Detiene el escritorio `id` | | GET | `/desktop/{id}/stream` | Stream MPEG-TS (multi-cliente) | | GET | `/sync/firefox/export[/{slot}]` | Exporta el perfil de Firefox (.tar.gz)| | POST | `/sync/firefox/import` | Importa un perfil de Firefox | En la variante CPU `{id}` es siempre `0` (un solo escritorio por contenedor). En la variante GPU `{id}` va de `0` a `5` (hasta 6 escritorios por VM). ## Puertos - **8900/tcp** — API REST (FastAPI + uvicorn, `0.0.0.0:8900`). - **5901/tcp** (y consecutivos `5902`-`5906` en GPU) — VNC directo al framebuffer X11 de cada escritorio. ## Despliegue (systemd) Cada instancia corre como servicio systemd (`kiradesktop.service` en CPU, `kiradesktop-gpu.service` en GPU) con `Restart=always` y toda la configuración por variables de entorno — así el mismo `.py` sirve para las 12 instancias CPU clonadas y para la VM GPU, cambiando solo el entorno: - `MY_IP` — IP pública/interna que se anuncia en las respuestas de la API (`vnc_addr`, `stream_url`). **Debe fijarse por instancia** al clonar el contenedor/VM (es lo único que realmente cambia entre clones CPU). - `RESOLUTION`, `FRAMERATE`, `VIDEO_BITRATE`, `AUDIO_BITRATE` — parámetros de codificación. - `VNC_PORT` / `BASE_VNC_PORT` — puerto(s) VNC. - `WM_CMD` — gestor de ventanas a lanzar (`startxfce4` por defecto). - Variante GPU además: `NUM_DESKTOPS` (6), `BASE_DISPLAY`, `NVENC_PRESET`, `XORG_CONFIG` (ruta al `xorg.conf` con el driver NVIDIA). Instalación típica en cada nodo: ```bash cp kiradesktop-cpu.py /opt/kiradesktop-cpu.py # o kiradesktop-gpu.py cp kiradesktop.service /etc/systemd/system/ # o kiradesktop-gpu.service systemctl daemon-reload systemctl enable --now kiradesktop.service # o kiradesktop-gpu.service ``` ## Diferencias entre `kiradesktop.py` y `kiradesktop-cpu.py` `cpu/kiradesktop.py` es una **versión previa/backup** del script CPU actual (`cpu/kiradesktop-cpu.py`), tal como se encontró en `/opt` del contenedor. Se incluye igual por trazabilidad histórica, pero **el que está desplegado y en uso (referenciado por el `.service`) es `kiradesktop-cpu.py`**. La diferencia real entre ambos archivos es mínima: - Se eliminó un comentario explicativo sobre el escalado a 720p. - Se cambió el preset del encoder `libx264` de `ultrafast` a `superfast` (mejor relación calidad/CPU a cambio de un poco más de carga). El resto del código (gestión de PulseAudio, Xtigervnc, ffmpeg, API FastAPI, export/import de perfil de Firefox) es idéntico. ## Nota de seguridad (importante para un despliegue real) Los servidores VNC de ambas variantes se levantan **sin contraseña** (`Xtigervnc -SecurityTypes None` en CPU, `x11vnc -nopw` en GPU) y la API REST no implementa autenticación. Esto asume que el servicio corre en una red interna/confiable (o detrás de un firewall/VPN/reverse-proxy que añada auth). **No exponer el puerto 8900 ni los puertos VNC directamente a Internet** sin añadir una capa de autenticación (por ejemplo, un proxy con Basic Auth o un túnel VPN) delante de ambos servicios. No se encontraron contraseñas, tokens ni claves de API hardcodeadas en el código (se auditó con `grep -iE "password|secret|token|key"` antes de subir el repo). ## Requisitos - Python 3 con `fastapi`, `uvicorn`. - `ffmpeg` (con soporte `libx264` en CPU, o `h264_nvenc`/driver NVIDIA en GPU). - `pulseaudio`, `dbus-launch`, XFCE (`startxfce4`) o el WM que se configure. - CPU: `Xtigervnc`. GPU: `Xorg` + driver propietario NVIDIA + `x11vnc`.