Skip to main content

1.2 Los pilares de Docker

Aunque los contenedores han sido un gran avance en la adopción de la nube y las prácticas DevOps, no nos exime de conocer, prevenir y mitigar los posibles ataques que suframos. Este puede parecer una tarea abrumadora en un principio, sin embargo a lo largo del libro encontrarás estrategias y recursos que te ayudarán a superarlo.

El vector de ataque principal en el caso de los contenedores, se basa en la relación que existe entre el host y el propio contenedor. De esta forma, a medida que entendamos qué compartimos entre el host y el contenedor a nivel del sistema operativo y qué recursos podemos compartir o no con el contenedor, podremos prevenir o mitigar la mayoría de los vectores de ataques conocidos a día de hoy con Docker.

Arquitectura

Uno de los puntos más complicados de entender cuando trabajamos con Docker, es comprender que el Kernel es compartido entre el host (capítulo 2.1.3) y los contenedores, no como sucede con las máquinas virtuales que utilizan una solución Hypervisor

Comparativa que muestra como Docker es mucho más liviano al no tener que contar con un Guest OS para ejecutar los contenedores ya que comparte el kernel de su hostComparativa que muestra como Docker es mucho más liviano al no tener que contar con un Guest OS para ejecutar los contenedores ya que comparte el kernel de su host

Imagen derivada de Geek Flare para adaptar el formato

Como resultado de compartir el Kernel podemos sufrir una serie de ataques:

  • Cuando escapamos del contenedor y tenemos acceso a otros contenedores o al propio host. Ejemplo del uso de Dirty Cow (CVE-2016-5195) para salir del contenedor (capítulo 2.2.4).
  • Cuando no gestionamos correctamente el uso de namespaces y permitimos que un contenedor pueda tener acceso root a la máquina host o muchos de los recursos y dispositivos presentes (capítulo 2.2.2).
  • Al no imponer límites a los contenedores, podemos sufrir denegaciones de servicio dentro de la máquina host, impidiendo que recursos legítimos accedan a módulos y recursos del sistema host por falta de recursos (capítulo 2.2.5).

Ciclo de vida

Ciclo de vida en docker: Dockerfile, build, image, run, container en una secuencia linealCiclo de vida en docker: Dockerfile, build, image, run, container en una secuencia lineal

Cada parte del ciclo de vida tiene sus propios retos, pero teniendo unas estrategias claras podremos hacer frente sin problemas.

Dockerfile

En muchas ocasiones usaremos imágenes de terceros directa o indirectamente como base para las que nosotros creemos (añadiendo nuestras propias capas).

Podemos hacer mucho a la hora de crear nuestras propias imágenes para mejorar la seguridad, como utilizar imágenes firmadas y para minimizar los riesgos por ejemplo tener una política bien definida sobre qué ficheros y carpetas formarán parte de la imagen (capítulo 3).

Imagen

Las imágenes deben poder subirse y descargarse de una forma segura de los registros públicos o privados que usemos (capítulo 3).

Contenedor

Crear imágenes es una cosa, pero mantener nuestros contenedores corriendo en entornos productivos tiene muchos retos de seguridad que tienen que ver con cómo establecemos esa relación con la máquina host (redes, ficheros, dispositivos...) y cómo hacemos políticas efectivas (Seecomp, AppArmor, permisos, capacidades), sin olvidarnos de la configuración del propio demonio de Docker y las actualizaciones regulares de los contenedores y del propio host (capítulo 2)

Dependencias

Otro punto importante, es entender que Docker parte de la base de que el código que estamos ejecutando en esos contenedores es fiable y que nosotros como usuarios hemos validado previamente que esa imagen se corresponda con lo que nosotros esperamos. Si nosotros decidimos ejecutar imágenes de Docker que no cuentan con garantías de seguridad (potencialmente maliciosas) o que entrañan algún riesgo, podríamos poner en peligro nuestra máquina host o nuestra propia infraestructura, por ejemplo compartiendo variables de entorno u otros datos sensibles con contenedores malintencionados (capítulo 2.2.3).

En ocasiones usamos imágenes que son confiables pero sus dependencias no son inmutables pudiendo generar vulnerabilidades a través de ellas, lo que se conoce como Supply Chain attacks

Atención

Muchas de las dependencias de nuestros proyectos dependen directa o indirectamente del Software Libre. Esto lleva años generando presión sobre una comunidad de maintainers que está muy lejos de ser sostenible con garantías.

Desde hace algún tiempo se enmascara este problema estableciendo una metáfora con el concepto de "Supply Chain".

When you take on an additional dependency in a software project, often money does not change hands. npm install and cargo add do not bill your credit card. There is no formal agreement between a maintainer and its downstream users. Iliana Etaoin