Containers - imágenes y cadena de suministro
Las imágenes basadas en capas heredan privilegios: el escaneo de CVE, el signing y el runtime rootless reducen la superficie que el contenedor entrega al host.
Qué es
Un contenedor es un proceso Linux aislado por namespaces y cgroups, que ejecuta un sistema de archivos apilado en capas (layers). Cada capa es una decisión: la base que descargas, el apt install que corres, el usuario que abre el shell, el binario que entra. Cada una pasa a ser parte de la superficie que encuentra el atacante.
Dos principios resuelven el 80% de la defensa: imágenes mínimas (menos cosas, menos bugs) y runtime endurecido (menos privilegio, menos caminos). El resto es proceso: escaneo, signing, política.
Imagen base mínima
La imagen base es el cimiento de todo lo que venga después. ubuntu:latest o python:latest traen un shell, un gestor de paquetes y un conjunto de CVEs que crece cada semana. Para producción, elige una base que tenga solo lo que el binario necesita para correr.
- distroless (gcr.io/distroless/*): sin shell, sin apt, sin gestor de paquetes. Para aplicaciones Go, Java, Node, Python estáticas
- alpine: busybox + musl, ~5MB, aún tiene shell pero es mucho más pequeña que Debian
- scratch: nada, solo el binario. Válido para binarios Go/C/Rust compilados estáticamente
- wolfi/chainguard: distroless con cadena de suministro auditada y rebuild diario de CVEs
Registry confiable y signing
Saber de dónde vino vale más que saber qué hay adentro. Los registries privados (ECR, GCR, Harbor) dan control sobre quién publica, con SSO y auditoría. El signing prueba la integridad: la imagen que está corriendo es exactamente la que construyó el CI.
Cosign (del proyecto Sigstore) firma y verifica imágenes OCI. El par de claves puede venir del propio equipo, de un (la clave queda en un HSM), o de Fulcio, que emite un certificado efímero basado en un login OIDC (útil para CI sin secretos).
# firma en el push
cosign sign --key cosign.key ghcr.io/loja/checkout@sha256:abc123
# verifica antes de subir (admission controller o job de pre-deploy)
cosign verify \
--key cosign.pub \
--certificate-identity-regexp 'https://github.com/loja/checkout/.github/workflows/release.yml@refs/tags/.*' \
ghcr.io/loja/checkout@sha256:abc123Image scanning: encontrar CVEs antes de subir
Los scanners comparan la de la imagen (o cada layer) con bases de vulnerabilidades (, GHSA, OSV). La salida es la lista de paquetes y CVEs, con severidad y versión corregida. Corre en tres momentos: en el build (bloquea el PR con un crítico), en el registry (encuentra un CVE nuevo contra una imagen ya publicada) y en el admission (rechaza un pod con una imagen no escaneada).
- Trivy: scanner único (FS, imagen, , SBOM), corre offline, sin base central
- Grype (Anchore): foco en imagen y SBOM CycloneDX
- Docker Scout: integrado a Docker Hub, usa la SBOM que Docker construye de forma nativa
- Snyk Container: comercial, bueno para equipos que ya usan Snyk para
Correr como non-root y endurecer el runtime
Un contenedor corriendo como UID 0 dentro del host es un proceso root en el host. Si el atacante escapa del contenedor, ya tiene privilegios administrativos en el nodo. Lo mismo con los sistemas de archivos escribibles: marcan dónde intentará persistir el atacante. Endurecer el runtime es cortar caminos antes de que existan.
FROM python:latest
RUN apt-get update && apt-get install -y curl netcat
COPY . /app
WORKDIR /app
EXPOSE 8080
CMD ["python", "app.py"] # corre como root (UID 0)# base mínima, sin shell, multi-stage para no heredar dev deps
FROM python:3.12-slim AS builder
WORKDIR /build
RUN pip install --no-cache-dir -r requirements.txt
FROM gcr.io/distroless/python3-debian12
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY . /app
USER 65532 # UID no-root fijo
EXPOSE 8080
ENTRYPOINT ["python", "/app/app.py"]Dónde aparece
Los contenedores tocan build, deploy y runtime. En el build, el scan cierra el PR. En el registry, el signing autentica el origen. En el admission, el clúster rechaza una imagen sin firmar o con violación de policy. En el runtime, el vigila el comportamiento (próximo tema). Saltarse cualquiera de estos eslabones es abrir una ventana.
Puntos fuertes
- inmutabilidad: la misma imagen que fue probada es la que sube, sin 'funciona en mi máquina'
- las imágenes mínimas reducen los CVEs en un orden de magnitud: Python distroless tiene ~20 paquetes, Debian tiene ~600
- la firma y la SBOM dan trazabilidad real, pieza por pieza, hasta el paquete instalado
Limitaciones
- el scan encuentra CVEs conocidos: un en una dependencia pasa, y el signing no ayuda con eso
- distroless y scratch dificultan el debug (sin shell). Es el trade-off entre seguridad y ergonomía, no un bug
- las políticas de runtime (non-root, fs de solo lectura) deben ser aceptadas por la aplicación: no todo binario arranca sin root, y reescribir toma tiempo
conexiones en el mapa
- CWPP - protección de workloadsmonitorea el runtimeContainers - imágenes y cadena de suministro
- Network - segmentación y zero-trustaísla la redContainers - imágenes y cadena de suministro
actualizado el 14/10/2026 · fuentes para profundizar · reportar un error
en otros dominios
- Contenedores e imágenesdevopsla buena imagen y el clúster seguro: dos mitades del mismo problema
- Fundamentos de Kubernetesdevopsel mismo clúster visto como plataforma y como superficie de ataque
- SCAappsecalimenta: la imagen hereda las dependencias
- SBOMappsecinventaría lo que va dentro de la imagen
Estudia antes
Desbloquea
pon a prueba lo que entendiste
Cargando preguntas…