Cuando Docker no es suficiente: el dilema del aislamiento real

teal LED panel

Imagina que son las 3 de la mañana y tu plataforma de CI/CD acaba de ejecutar código malicioso que ha escapado del contenedor y comprometido el host. El cliente insiste en que "estaba aislado con Docker", pero ahora tienes 40 millones de líneas de código C del kernel Linux como superficie de ataque compartida. Bienvenido al mundo real del aislamiento.

El kernel como superficie compartida

Cada vez que ejecutas código no confiable —agentes de IA generando scripts, plataformas multi-tenant ejecutando código de clientes, pipelines de RL evaluando outputs de modelos— te enfrentas a la misma pregunta fundamental: ¿cómo reduces el acceso de ese código no confiable a los ~340 syscalls que expone el kernel Linux?

Los namespaces: muros de visibilidad

Los namespaces de Linux envuelven recursos globales del sistema para que los procesos parezcan tener su propia instancia aislada. Tienes PID (árbol de procesos propio), Mount (tabla de montajes propia), Network (interfaces propias), User (mapping UID/GID), y otros cuatro tipos más.

Pero aquí viene la sorpresa: los namespaces son muros de visibilidad, no fronteras de seguridad. Previenen que un proceso vea cosas fuera de su namespace, pero no previenen que explote el kernel que implementa el namespace.

El CVE-2024-21626 de enero pasado lo demostró claramente: un file descriptor leak en runc permitía a los contenedores acceder al filesystem del host. El mount namespace estaba intacto, pero el escape ocurrió a través de un fd que runc falló en cerrar antes de transferir control al contenedor.

Foto de Adi Goldstein en Unsplash

Read more