Para empezarCreer que un contenedor Docker te aísla igual que una máquina virtual es el billete perfecto para que comprometan todo tu servidor.
La falsa ilusión de aislamiento
Un contenedor no es una máquina virtual ligera. Comparte directamente el kernel del sistema operativo host con otros contenedores. Si el kernel sufre una vulnerabilidad o hay una mala configuración, todo el sistema operativo subyacente queda expuesto al atacante.
El peligro de root en el contenedor
Más del 60% de las imágenes oficiales en Docker Hub ejecutan procesos por defecto con privilegios de usuario root. Si un atacante compromete la aplicación dentro del contenedor, automáticamente obtiene privilegios de root dentro del espacio de nombres.
Inspeccionando el usuario actual
Vamos a comprobar con quién estamos ejecutando los procesos dentro de un contenedor predeterminado mal configurado.
$ docker run --rm ubuntu whoami
root
Pilares del aislamiento en Linux
Docker se apoya en características nativas del kernel de Linux para simular un entorno independiente para cada contenedor.
Marca cada paso al entenderlo · 0/3
Linux Namespaces explicados
Los namespaces restringen lo que un proceso puede ver. Por ejemplo, el 'pid namespace' hace que el proceso dentro del contenedor crea que es el PID 1, ocultando todos los demás procesos que corren en el sistema host real.
El peligro de PID namespace compartido
Si inicias un contenedor usando el parámetro --pid=host, rompes por completo esa barrera. El contenedor podrá ver y manipular todos los procesos del sistema operativo anfitrión, facilitando un ataque de escalada de privilegios.
Vulnerando el aislamiento de procesos
Ejecutar un contenedor con el flag de host expone inmediatamente la tabla de procesos del servidor principal.
$ docker run --rm --pid=host alpine ps aux
PID USER TIME COMMAND
1 root 0:05 /sbin/init
1423 root 0:00 nginx: master process
Linux Capabilities
Linux divide los superpoderes del usuario root en unidades más pequeñas llamadas capabilities. Por defecto, Docker elimina muchas de ellas al iniciar un contenedor, pero algunas se mantienen y pueden ser abusadas.
Capabilities peligrosas en Docker
Ciertas capabilities permiten saltarse restricciones del sistema si se asignan de forma innecesaria a un contenedor.
Marca cada paso al entenderlo · 0/3
El riesgo del socket de Docker
Montar el socket de Docker (/var/run/docker.sock) dentro de un contenedor equivale a entregarle las llaves de root de todo el servidor host, ya que permite crear nuevos contenedores con privilegios totales.
Controlando el host vía socket
Un contenedor con acceso al socket de Docker puede levantar otro contenedor que monte la raíz del host.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock -ti alpine
/ # apk add docker
/ # docker run -v /:/host -it alpine chroot /host
Nunca expongas el demonio de Docker
Exponer el puerto TCP del demonio de Docker sin autenticación TLS o sin restricciones de red es una puerta trasera instantánea para cualquier atacante en internet que escanee el puerto 2375.
Buenas prácticas de hardening base
Aplica estas reglas desde el día uno en tus despliegues de contenedores para minimizar la superficie de ataque.
Marca cada paso al entenderlo · 0/4
Imágenes base seguras
Las imágenes oficiales gigantes como Ubuntu completo traen herramientas innecesarias como compiladores y gestores de paquetes que un atacante puede usar si compromete el contenedor. Se deben priorizar imágenes mínimas como Alpine o distroless.
Definiendo un usuario no root
Así es como debe estructurarse un Dockerfile profesional para asegurar que el proceso no corra como root.
FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD ["node", "server.js"]
La seguridad es un proceso continuo
Un contenedor seguro hoy puede ser vulnerable mañana debido a una nueva CVE descubierta en sus librerías internas. La auditoría automatizada en pipelines CI/CD es obligatoria.
¿Te acuerdas? Toca para comprobarlo
Atajos: ← → para cambiar de pieza · / para buscar
