Blog

Una lista de verificación práctica de seguridad de aislamiento para Docker en alojamiento multiinquilino

Asegure su alojamiento Docker multiinquilino con esta lista de verificación práctica que cubre usuarios no root, capacidades, seccomp, espacios de nombres de usuario, límites de recursos y sistemas de archivos de solo lectura.

Resumen

El alojamiento Docker multiinquilino requiere un aislamiento sólido para prevenir escapes de contenedores. Este artículo proporciona una lista de verificación práctica de seguridad que cubre seis áreas clave: ejecutar como no root, eliminar capacidades, aplicar perfiles de seccomp, habilitar la reasignación de espacios de nombres de usuario, establecer límites de recursos y usar sistemas de archivos raíz de solo lectura. Cada paso incluye un ejemplo de configuración concreto para Docker Compose. También aprenderá sobre errores comunes como problemas de compatibilidad del kernel con espacios de nombres de usuario y compensaciones de rendimiento al aplicar seccomp. Siguiendo esta lista de verificación, puede reducir significativamente la superficie de ataque sin agregar complejidad innecesaria. El artículo concluye con una configuración base recomendada para entornos de producción multiinquilino.

Si ejecuta un entorno Docker multiinquilino, el espectro de un ataque de escape de contenedores le quita el sueño. Un solo exploit del kernel puede salir de un contenedor y dar a un atacante acceso sin restricciones al host y a los datos de todos los demás inquilinos. Aunque Docker proporciona potentes primitivas de aislamiento —namespaces, cgroups y capacidades—, la mala configuración deja brechas. Este artículo presenta una lista de verificación de seguridad paso a paso que puede aplicar hoy. Cada paso incluye un fragmento funcional de Docker Compose y advertencias clave. Al final, tendrá una base endurecida que equilibra seguridad y rendimiento.

1. Ejecutar Contenedores como un Usuario No Root

Los contenedores se ejecutan por defecto como root dentro del contenedor. Si un atacante obtiene root en el contenedor, tiene una ventaja inicial para escapar. Siempre defina un usuario no root en su Dockerfile.

FROM alpine:3.18
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

En Compose, también puede establecer el usuario directamente:

services:
  app:
    image: myapp
    user: "1000:1000"

Advertencia: Algunas aplicaciones requieren root para operaciones legítimas (por ejemplo, enlazar a puertos por debajo de 1024). Use CAP_NET_BIND_SERVICE en lugar de ejecutar todo el contenedor como root. Para una visión más profunda de los fundamentos del aislamiento, consulte nuestra guía sobre logrando un verdadero aislamiento multiinquilino en Docker.

2. Eliminar Todas las Capacidades y Añadir Solo las Necesarias

Las capacidades de Linux otorgan privilegios detallados a los contenedores. Por defecto, Docker concede un conjunto de capacidades. Elimine todo y conceda solo las requeridas.

services:
  app:
    image: myapp
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # si es necesario

Advertencia: Capacidades como SYS_ADMIN o NET_RAW rara vez son necesarias. Audite su aplicación para determinar el conjunto mínimo. Eliminar todas las capacidades bloquea muchos vectores de escape.

3. Aplicar un Perfil de Seccomp

Seccomp (modo de computación segura) filtra las llamadas al sistema disponibles para un contenedor. Docker incluye un perfil de seccomp predeterminado que bloquea llamadas al sistema peligrosas como clone con ciertas banderas. Puede personalizarlo aún más.

services:
  app:
    image: myapp
    security_opt:
      - seccomp=/path/to/custom-profile.json

Un perfil endurecido podría bloquear unshare, ptrace y mount. Comience con el perfil predeterminado de Docker y restrinja más. Advertencia: Los perfiles demasiado estrictos pueden romper aplicaciones. Pruebe a fondo en un entorno de pruebas. Para más información sobre defensas contra escapes de contenedores, lea defendiendo contra escapes de contenedores.

4. Habilitar la Reasignación de Espacios de Nombres de Usuario

Los espacios de nombres de usuario mapean el usuario root del contenedor a un usuario del host sin privilegios. Esto significa que incluso si un atacante obtiene root dentro del contenedor, no tiene privilegios especiales en el host.

Habilítelo en el demonio de Docker editando /etc/docker/daemon.json:

{
  "userns-remap": "default"
}

Luego reinicie Docker. Advertencia: La reasignación de espacios de nombres de usuario tiene dos inconvenientes: rompe los montajes de volúmenes cuando no se configura cuidadosamente (los archivos son propiedad del usuario reasignado) y es incompatible con algunos controladores de almacenamiento como overlay2 en kernels antiguos. Pruebe a fondo.

5. Establecer Límites de Recursos con Cgroups

Los límites de recursos evitan que un contenedor comprometido lance un ataque de denegación de servicio contra el host. Use cgroups para limitar CPU, memoria y E/S de disco.

services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Para Docker Compose v3, use la sección deploy (funciona con swarm o compose v2). Para Docker simple, use --memory y --cpus. Advertencia: Establecer límites demasiado bajos puede causar muertes por OOM. Monitoree el uso y ajuste en consecuencia.

6. Usar Sistema de Archivos Raíz de Solo Lectura

Un sistema de archivos raíz de solo lectura evita que los atacantes escriban binarios maliciosos o modifiquen archivos de configuración dentro del contenedor.

services:
  app:
    image: myapp
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=64m

Monte tmpfs en los directorios que necesitan acceso de escritura (como /tmp). Esto obliga a que todos los datos escribibles sean efímeros. Advertencia: Algunas aplicaciones requieren almacenamiento persistente; use volúmenes con nombre para eso.

Errores Comunes

  • Compatibilidad del kernel: La reasignación de espacios de nombres de usuario y algunas reglas de seccomp requieren un kernel de Linux reciente (4.14+). Verifique la versión de su kernel.
  • Impacto en el rendimiento: Seccomp y los espacios de nombres de usuario agregan una pequeña sobrecarga, pero es insignificante para la mayoría de las cargas de trabajo. Evalúe su aplicación específica.
  • Complejidad: Agregar las seis medidas a la vez puede romper cosas. Aplíquelas una por una, probando cada cambio.

Para una visión más amplia de los patrones de orquestación, consulte nuestra guía sobre diseñando una arquitectura Docker multiinquilino.

Conclusión

Un host Docker multiinquilino seguro no requiere herramientas exóticas, solo el uso correcto de las características integradas de Docker. Comience con un usuario no root, elimine todas las capacidades, aplique un perfil de seccomp, habilite la reasignación de espacios de nombres de usuario, establezca límites de recursos y use un sistema de archivos de solo lectura. Esta lista de verificación forma una base sólida que bloquea las técnicas de escape más comunes. Después de implementarla, ejecute herramientas de seguridad como docker-bench-security para verificar su configuración. Recuerde: la seguridad es un proceso, no un producto. A medida que surjan nuevas vulnerabilidades del kernel, revise su configuración. Para páginas de aterrizaje automatizadas que muestren su servicio de alojamiento, use Pagenza para tener su sitio en vivo en minutos.

Sources (5)