Tema 9

9. Fundamentos de contenedores: imágenes, capas, runtimes y superficie de ataque

Los contenedores permiten empaquetar y ejecutar aplicaciones de forma portable, pero su seguridad depende de cómo se construyen las imágenes, cómo se ejecutan los procesos y qué límites impone el host.

Objetivo Entender cómo funciona un contenedor y qué riesgos introduce
Enfoque Imágenes, capas, runtimes, aislamiento y host
Resultado Identificar la superficie de ataque de workloads contenerizados

9.1 Introducción

Un contenedor empaqueta una aplicación con sus dependencias y la ejecuta como un proceso aislado sobre un host. A diferencia de una máquina virtual, no trae su propio kernel: comparte el kernel del sistema operativo anfitrión.

Esta característica hace que los contenedores sean livianos y rápidos, pero también define su modelo de seguridad. El aislamiento depende de mecanismos del sistema operativo, configuración del runtime, permisos del proceso, sistema de archivos, red, capacidades y políticas aplicadas.

Antes de endurecer imágenes o proteger Kubernetes, es necesario entender qué es una imagen, qué son las capas, qué hace el runtime y dónde aparece la superficie de ataque.

9.2 Qué es un contenedor

Un contenedor es una unidad de ejecución que agrupa una aplicación, sus librerías y su entorno mínimo. Se ejecuta como uno o más procesos en el host, pero con aislamiento respecto de otros procesos.

Ese aislamiento suele apoyarse en:

  • Namespaces: separan vistas de procesos, red, usuarios, montajes y otros recursos.
  • Cgroups: limitan y contabilizan CPU, memoria, I/O y otros recursos.
  • Capabilities: dividen privilegios tradicionales de root en permisos más específicos.
  • Seccomp: restringe llamadas al sistema permitidas.
  • AppArmor o SELinux: aplican políticas de control de acceso a procesos.
Un contenedor no es una máquina virtual pequeña. Es un proceso aislado que comparte el kernel del host. Ese detalle es central para entender sus riesgos.

9.3 Contenedores frente a máquinas virtuales

Las máquinas virtuales aíslan mediante hipervisor y cada VM ejecuta su propio sistema operativo. Los contenedores aíslan procesos dentro del mismo kernel del host. Esto cambia rendimiento, densidad y modelo de seguridad.

Aspecto Máquina virtual Contenedor
Aislamiento Hipervisor y sistema operativo invitado Kernel compartido con namespaces, cgroups y políticas
Inicio Más lento por arranque de SO Rápido porque inicia procesos
Consumo Mayor uso de CPU, memoria y disco Más liviano y denso
Riesgo principal Escape de VM o mala configuración de red Escape de contenedor, privilegios excesivos o imagen vulnerable
Gestión Parches de SO por VM Actualización de imágenes, host y runtime

9.4 Qué es una imagen de contenedor

Una imagen de contenedor es un paquete inmutable que contiene el sistema de archivos necesario para ejecutar una aplicación: binarios, librerías, configuraciones, dependencias y metadatos.

La imagen no es el contenedor en ejecución. La imagen es el artefacto; el contenedor es una instancia ejecutada a partir de esa imagen.

Una imagen puede incluir:

  • Una imagen base, como una distribución mínima o runtime de lenguaje.
  • Paquetes del sistema operativo.
  • Dependencias de aplicación.
  • Código compilado o interpretado.
  • Variables, comandos de inicio y metadatos.
  • Usuarios y permisos definidos durante el build.

9.5 Capas de imagen

Las imágenes se construyen por capas. Cada instrucción relevante del Dockerfile o archivo equivalente puede agregar una nueva capa. Las capas se reutilizan para acelerar builds y descargas.

Desde seguridad, las capas importan porque:

  • Un archivo agregado en una capa puede seguir existiendo en el historial aunque luego se elimine.
  • Dependencias vulnerables pueden quedar incluidas aunque no se usen directamente.
  • Capas grandes aumentan superficie de ataque y tiempo de escaneo.
  • Imágenes base antiguas arrastran vulnerabilidades a todas las imágenes derivadas.
  • El orden de instrucciones puede afectar caché, reproducibilidad y exposición de secretos.
Nunca se deben copiar secretos durante el build y luego borrarlos en otra capa. El secreto puede permanecer recuperable en el historial de la imagen.

9.6 Registry o registro de imágenes

Un registry almacena y distribuye imágenes. Puede ser público, privado, administrado por el proveedor cloud o interno de la organización. Es una pieza crítica de la cadena de suministro.

Riesgo Impacto Control
Imagen maliciosa publicada Ejecución de código no autorizado Control de publicación, firma y aprobación
Imagen pública usada sin control Dependencia no confiable o alterada Fuentes aprobadas y pinning por digest
Credenciales de registry filtradas Lectura o modificación de artefactos MFA, roles temporales y permisos mínimos
Tags mutables Despliegue de contenido distinto al esperado Usar digest, firmas y políticas de promoción

9.7 Runtime de contenedores

El runtime es el componente que crea y ejecuta contenedores. Recibe una imagen, configura aislamiento, monta sistemas de archivos, prepara red y lanza el proceso principal.

Ejemplos de componentes relacionados son Docker Engine, containerd, CRI-O y runc. En Kubernetes, el kubelet se comunica con un runtime mediante una interfaz estándar.

Desde seguridad, el runtime debe:

  • Estar actualizado y parcheado.
  • Ejecutar contenedores con perfiles restrictivos.
  • Evitar modo privilegiado salvo casos muy justificados.
  • Restringir capacidades Linux innecesarias.
  • Registrar eventos relevantes de ejecución.
  • Impedir montajes sensibles del host cuando no son necesarios.

9.8 Host de contenedores

El host es el sistema donde corren los contenedores. Su seguridad es fundamental porque todos los contenedores dependen de su kernel, runtime, configuración de red y permisos de sistema.

Riesgos del host:

  • Kernel vulnerable compartido por múltiples contenedores.
  • Runtime desactualizado.
  • Socket Docker expuesto o montado dentro de contenedores.
  • Contenedores privilegiados con acceso excesivo al host.
  • Montajes de directorios sensibles como /var/run, /proc o rutas de credenciales.
  • Falta de límites de recursos que permita denegación de servicio local.

9.9 Aislamiento y sus límites

El aislamiento de contenedores es útil, pero no absoluto. Si el contenedor se ejecuta con demasiados privilegios, con montajes sensibles o como root, el límite entre contenedor y host se debilita.

Factores que reducen aislamiento:

  • Modo privilegiado.
  • Capacidades Linux innecesarias.
  • Acceso al socket del runtime.
  • Montajes de host con escritura.
  • Uso de red del host.
  • Ejecución como usuario root sin necesidad.
  • Perfiles seccomp, AppArmor o SELinux deshabilitados.
La seguridad de contenedores no consiste solo en escanear imágenes. También importa cómo se ejecuta el contenedor y qué permisos recibe en runtime.

9.10 Superficie de ataque de una imagen

La imagen define buena parte del riesgo inicial. Cuantos más paquetes, herramientas, shells, gestores de paquetes y dependencias incluya, mayor será la superficie de ataque.

Elementos que aumentan exposición:

  • Imágenes base antiguas o sin mantenimiento.
  • Paquetes del sistema innecesarios.
  • Herramientas de debugging en producción.
  • Dependencias de lenguaje con vulnerabilidades conocidas.
  • Usuarios root por defecto.
  • Secretos o archivos sensibles incluidos por error.
  • Permisos amplios en archivos y directorios.

9.11 Superficie de ataque en runtime

Cuando un contenedor se ejecuta, aparecen riesgos adicionales relacionados con configuración, red, identidad, almacenamiento y permisos.

Área Riesgo Control
Usuario Proceso ejecutado como root Usuario no root y filesystem con permisos mínimos
Red Comunicación libre con otros servicios Políticas de red y exposición mínima
Recursos Consumo excesivo de CPU o memoria Límites y requests adecuados
Secretos Credenciales accesibles por procesos no autorizados Montaje controlado y rotación
Host Acceso a archivos o sockets sensibles Evitar montajes y privilegios innecesarios

9.12 Cadena de suministro de imágenes

Una imagen no aparece de la nada. Se construye desde código, dependencias, imagen base, scripts, herramientas de build y registries. Cada paso puede introducir riesgo.

Preguntas importantes:

  • ¿De dónde proviene la imagen base?
  • ¿Está fijada por digest o solo por tag?
  • ¿Qué dependencias se instalan durante el build?
  • ¿El build es reproducible?
  • ¿La imagen se escanea antes de publicarse?
  • ¿Se firma la imagen y se verifica antes del despliegue?
  • ¿Quién puede publicar o sobrescribir imágenes?

9.13 Observabilidad de contenedores

Los contenedores son efímeros. Pueden crearse, escalarse y destruirse rápidamente. Sin observabilidad, investigar incidentes es difícil porque la evidencia puede desaparecer junto con el contenedor.

Se recomienda capturar:

  • Logs de aplicación y del runtime.
  • Eventos de creación, inicio, parada y eliminación.
  • Imagen exacta ejecutada, preferentemente por digest.
  • Usuario, capacidades, montajes y configuración de seguridad.
  • Conexiones de red y destinos relevantes.
  • Consumo de recursos y anomalías de comportamiento.

9.14 Errores frecuentes

  • Asumir que un contenedor es tan aislado como una máquina virtual.
  • Usar imágenes base grandes y antiguas sin revisión.
  • Ejecutar procesos como root por defecto.
  • Montar el socket Docker dentro del contenedor.
  • Agregar herramientas de administración innecesarias a imágenes productivas.
  • Usar tags mutables como latest en producción.
  • Incluir secretos durante el build.
  • No limitar CPU, memoria ni permisos de runtime.

9.15 Lista de verificación

  • ¿La imagen base proviene de una fuente confiable y mantenida?
  • ¿La imagen evita paquetes, shells y herramientas innecesarias?
  • ¿El contenedor se ejecuta como usuario no root?
  • ¿Se restringen capacidades, privilegios y montajes del host?
  • ¿Se evita usar tags mutables para despliegues productivos?
  • ¿El registry aplica permisos mínimos y controles de publicación?
  • ¿Los eventos de runtime y logs se conservan para investigación?
  • ¿La cadena de build puede explicar qué código y dependencias generaron la imagen?

9.16 Qué debes recordar de este tema

  • Un contenedor comparte el kernel del host; no equivale a una VM completa.
  • La imagen define dependencias, capas y parte de la superficie de ataque.
  • El runtime y la configuración de ejecución determinan el nivel real de aislamiento.
  • El host de contenedores es un activo crítico porque sostiene todos los workloads.
  • La seguridad debe cubrir build, registry, despliegue y runtime.

9.17 Conclusión

Los contenedores aportan portabilidad y eficiencia, pero no eliminan la necesidad de controles. La seguridad depende de imágenes pequeñas y confiables, runtimes actualizados, permisos mínimos, aislamiento efectivo y observabilidad.

En el próximo tema veremos cómo construir imágenes seguras: Dockerfile, hardening, usuarios no root y reducción de superficie.