Saltar al contenido
Open Security
DevSecOps y AgentesAvanzado· 40 min

Docker image hardening: non-root, capabilities y filesystem

Controles prácticos para reducir daño si un contenedor se compromete: usuario no-root, capacidades mínimas, filesystem read-only y secretos fuera de la imagen.

#docker#hardening#devsecops

Antes de empezar necesitás

  • Saber construir una imagen Docker simple
  • Entender usuarios y permisos básicos en Linux

Al terminar vas a poder

  • Identificar riesgos de correr como root
  • Reducir capabilities innecesarias
  • Separar secretos de la imagen
  • Diseñar un checklist de hardening reproducible

Un contenedor no es una VM mágica. Comparte kernel con el host y tiene permisos. Hardening es reducir qué puede hacer el proceso si algo sale mal.

Dockerfile más seguro

Patrón mínimo:

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN addgroup -S app && adduser -S app -G app
USER app
CMD ["node", "server.js"]

No alcanza para producción, pero evita correr la app como root dentro del contenedor.

Runtime con menos permisos

vt@labs:~
docker run --rm \
  --read-only \
  --cap-drop=ALL \
  --tmpfs /tmp \
  app-de-juguete:local

Puede romper apps que escriben en disco o necesitan capabilities. Eso no es malo: te muestra dependencias ocultas.

Checklist de evidencia

control             evidencia
USER no-root         Dockerfile con USER app
capabilities         runbook con --cap-drop=ALL y excepciones justificadas
filesystem           --read-only + tmpfs donde haga falta
secretos             no hay .env ni tokens en layers
docker socket        no montado salvo caso justificado y defensivo

Lo que practicás en este lab

Llevátelo a tu repo si querés, pero no es obligatorio: es tu aprendizaje.

  • Dockerfile vulnerable y versión endurecida
  • Checklist de controles aplicados
  • Writeup: qué riesgo reduce cada control

Reto

Tomá una imagen de juguete. Proponé un Dockerfile que cree usuario no-root y un comando docker run con cap-drop y read-only. Explicá qué podría romper y cómo lo detectarías.

Resolvelo y escribí dos líneas explicando qué pasó. Con eso lo fijás.

¿Hiciste el lab?

Si querés, guardá lo que hiciste (comandos, notas, un repo) para volver después. Y si encontrás un error o querés mejorar este lab,contribuí al repo. El progreso se guarda solo en tu navegador.