¿Qué es lo que hace que Docker sea más seguro que las máquinas virtuales o el sistema completo?

264

Recientemente tuve una discusión con un experto en Docker sobre la seguridad de Docker frente a las máquinas virtuales. Cuando le dije que había leído de diferentes fuentes que es más fácil que el código que se ejecuta dentro de un contenedor Docker se escape de él que un código que se ejecuta en una máquina virtual, el experto explicó que estoy completamente equivocado y que Las máquinas Docker son en realidad más seguras en cuanto a evitar que el código malicioso afecte a otras máquinas, en comparación con las máquinas virtuales o las aplicaciones tradicionales .

Aunque intentó explicar qué hace que los contenedores Docker sean más seguros, su explicación fue demasiado técnica para mí.

Por lo que entiendo, "la virtualización a nivel de sistema operativo reutiliza el espacio del kernel entre las máquinas virtuales", como se explica en una respuesta diferente en este sitio. En otras palabras, el código de un contenedor de Docker podría explotar una vulnerabilidad del kernel, que no sería posible hacerlo desde una máquina virtual.

Por lo tanto, ¿qué podría hacer que sea intrínsecamente más seguro usar Docker en comparación con las máquinas virtuales o el aislamiento de metal, en un contexto donde el código que se ejecuta en un contenedor / máquina intente escapar e infectar / dañar otros contenedores / máquinas? Supongamos que Docker está configurado correctamente, lo que evita tres de las cuatro categorías de ataques descritos aquí .

    
pregunta Arseni Mourzenko 18.09.2017 - 00:08
fuente

9 respuestas

425

No, los contenedores Docker no son más seguros que una máquina virtual.

Cotizando Daniel Shapira :

  

Solo en 2017, 434 vulnerabilidades del núcleo de Linux donde se encontró , y como ha visto en esta publicación, las vulnerabilidades del kernel pueden ser devastadoras para entornos de contenedores. Esto se debe a que los contenedores comparten el mismo kernel que el host, por lo que confiar en los mecanismos de protección integrados por sí solos no es suficiente.

1. Explotaciones del núcleo de un contenedor

Si alguien explota un error del kernel dentro de un contenedor, lo explota en el sistema operativo host. Si esta vulnerabilidad permite la ejecución de código, se ejecutará en el sistema operativo host, no dentro del contenedor.

Si esta vulnerabilidad permite el acceso arbitrario a la memoria, el atacante puede cambiar o leer cualquier dato de cualquier otro contenedor.

En una VM, el proceso es más largo: el atacante tendría que explotar tanto el kernel de la VM como el hipervisor y el kernel del host (y esto podría no ser lo mismo que el kernel de la VM).

2. Hambre de recursos

Como todos los contenedores comparten el mismo kernel y los mismos recursos, si el acceso a algún recurso no está restringido, un contenedor puede usarlo todo y matar de hambre al sistema operativo host y los otros contenedores.

En una máquina virtual, los recursos están definidos por el hipervisor, por lo que ninguna máquina virtual puede negar el sistema operativo host de ningún recurso, ya que el propio hipervisor puede configurarse para hacer un uso restringido de los recursos.

3. Desglose de contenedores

Si cualquier usuario dentro de un contenedor puede escapar del contenedor utilizando algún exploit o configuración incorrecta, tendrá acceso a todos los contenedores que se ejecutan en el host. Esto sucede porque el mismo usuario que ejecuta el motor de la ventana acoplable es el usuario que ejecuta los contenedores. Si algún exploit ejecuta código en el host, se ejecutará bajo los privilegios del motor de la ventana acoplable, de modo que pueda acceder a cualquier contenedor.

4. Separación de datos

En un contenedor docker, hay algunos recursos que no tienen espacio de nombre:

  • SELinux
  • Cgroups
  • sistemas de archivos bajo /sys , /proc/sys ,
  • /proc/sysrq-trigger , /proc/irq , /proc/bus
  • /dev/mem , /dev/sd* sistema de archivos
  • Módulos de núcleo

Si cualquier atacante puede explotar cualquiera de esos elementos, será el propietario del sistema operativo host.

Un sistema operativo de VM no tendrá acceso directo a ninguno de esos elementos. Hablará con el hipervisor, y el hipervisor hará las llamadas al sistema apropiadas al sistema operativo host. Filtrará las llamadas inválidas, agregando un nivel de seguridad.

5. Enchufes crudos

El contenedor Unix docker predeterminado ( /var/run/docker.sock ) puede ser montado por cualquier contenedor si no está asegurado adecuadamente. Si algún contenedor monta este zócalo, puede cerrar, iniciar o crear nuevas imágenes.

Si está correctamente configurado y asegurado, puede lograr un alto nivel de seguridad con un contenedor docker, pero será menos que una VM correctamente configurada. No importa la cantidad de herramientas de endurecimiento que se empleen, una máquina virtual siempre será más segura. El aislamiento de metal desnudo es incluso más seguro que una máquina virtual. Algunas implementaciones simples (IBM PR / SM, por ejemplo) pueden garantizar que las particiones estén tan separadas como si estuvieran en un hardware separado. Que yo sepa, no hay forma de escapar de una virtualización PR / SM.

    
respondido por el ThoriumBR 18.09.2017 - 04:13
fuente
73

Decir que una VM o Docker es más seguro que la otra es una simplificación masiva.

VM proporciona virtualización de hardware; el hipervisor emula hardware para que el núcleo invitado piense que se está ejecutando en su propia máquina. Este tipo de virtualización es más fácil de aislar entre sí. Si su principal preocupación por la virtualización es el aislamiento (realmente no necesita que las máquinas virtuales interactúen entre sí), entonces la máquina virtual será mucho más sencilla de proteger.

Docker proporciona virtualización del sistema operativo / kernel, y Docker utiliza los espacios de nombres del kernel para virtualizar el kernel y el sistema operativo, de modo que el huésped cree que se está ejecutando en su propia instancia del sistema operativo. La virtualización del sistema operativo proporciona una flexibilidad significativamente mayor sobre cómo puede asegurar la interconexión entre sus contenedores. Si su principal preocupación con respecto a la virtualización requiere que interconecte contenedores, Docker le brinda la capacidad de definir estas reglas de uso compartido de manera que sea imposible o demasiado engorroso para las máquinas virtuales.

Con gran flexibilidad vienen grandes riesgos; es más fácil configurar erróneamente la ventana acoplable que la máquina virtual, y la flexibilidad del uso compartido de recursos de la ventana acoplable también crea más oportunidades tanto para errores de implementación como de configuración. Sin embargo, si logra configurar los permisos de uso compartido correctamente y asumiendo que no hay errores de implementación en Docker o en el kernel, Docker ofrece un intercambio mucho más detallado que la virtualización de hardware y puede brindarle una mejor seguridad general.

Por ejemplo, compartir socket. Con Docker, puede crear un socket con nombre compartido entre dos contenedores fácilmente compartiendo el archivo de socket, y puede definir permisos de seguridad (usando cualquier módulo de seguridad existente: permiso tradicional de Unix, capacidades, SELinux, AppArmor, seccomp, etc.) entre puntos finales de socket para que la ventana acoplable / kernel aplique cuáles y cómo las aplicaciones pueden acceder a los puntos finales de socket. Con una máquina virtual, puede compartir un socket un poco más engorroso al configurar una cadena de sockets para canalizar los datos que van al socket a través de TCP. Sin embargo, el hipervisor tiene una visibilidad muy limitada y no hay forma de controlar el acceso a los puntos finales del socket, ya que los núcleos invitados aplican permisos a estos puntos finales del socket.

Otro ejemplo es compartir carpetas. Con los contenedores, puede compartir una carpeta configurando un montaje compartido, y dado que Docker / kernel impone los permisos de archivos que utilizan los contenedores, el sistema huésped no puede pasar por alto esas restricciones. Con una VM, si desea compartir una carpeta, debe permitir que una máquina ejecute un servidor de archivos de red o un servidor Samba o FTP, y el hipervisor tiene poca visibilidad del recurso compartido y no puede hacer cumplir los permisos de uso compartido. Las partes móviles adicionales aquí (el servidor de archivos) también pueden tener sus propias vulnerabilidades y problemas de configuración incorrecta a considerar.

TL; DR: use VM para aislamiento y contenedores para compartir de forma controlada.

    
respondido por el Lie Ryan 18.09.2017 - 03:39
fuente
23

Como usted indicó correctamente, Docker usa "virtualización a nivel de sistema operativo". Puedes pensar en esto (si eres un fan de * nix) como una forma elegante de chroot .

Al aprovechar las características y la funcionalidad incorporadas en el sistema operativo, Docker actúa como director de contenedores. La vista del software del sistema operativo está dictada por Docker.

El mismo kernel se usa en todos los contenedores. Por ejemplo, si pude causar un pánico en el kernel en un contenedor (piense en "Pantalla azul de la muerte"), todos los demás contenedores están afectados. .

La configuración parece ser mucho más crítica que con las soluciones basadas en hardware. Todo está en el mismo espacio compartido efectivamente. Imagina poner un depredador salvaje al lado de su fuente de alimento natural. Si no colocó un cerco lo suficientemente fuerte alrededor del depredador, o si olvidó cerrar la puerta cada vez que abandonó el cercado, es probable que pueda imaginar lo que sucedería.

Aunque ciertamente es una solución liviana, ciertamente no ejecutaría ningún código desconocido al lado del código confiable.

El código malicioso tendría que determinar una forma de aumentar sus privilegios a un nivel de administrador / raíz para poder escapar del contenedor de cualquier manera significativa.

En una máquina virtual, el hipervisor sería atacado, no el kernel. Esto puede resultar más seguro, ya que existe un mayor nivel de aislamiento entre "contenedores", pero introduce una mayor sobrecarga para la administración.

A mi entender, no hay nada que haga que Docker sea más seguro que las soluciones basadas en hardware o "bare metal". Me gustaría decir que Docker es menos seguro. En términos de 1 contenedor por pieza de software, eso puede probar una historia diferente.

Si no está seguro de los ejemplos del mundo real, echaría un vistazo a OpenVZ. Utiliza la virtualización a nivel del sistema operativo en un estilo similar al igual que lo hace Docker, pero con un kernel modificado.

    
respondido por el dark_st3alth 18.09.2017 - 02:49
fuente
11

Los contenedores Docker no son intrínsecamente "más seguros", pero la capacidad de girar y destruir rápidamente los duplicados en un clúster es muy útil desde el punto de vista de seguridad.

Bien, hay muchas otras respuestas aquí, pero la gente tiende a olvidar que a veces la mejor herramienta que se puede usar para proteger un servidor / aplicación web es la capacidad de volver a implementar rápidamente el código limpio después de que el código ya instalado se haya visto comprometido.

Nada en el mundo 100% seguro o seguro. Especialmente en el mundo de las aplicaciones web expuestas. Pero Docker permite mejores prácticas si las personas realmente entienden su valor y se involucran en esas prácticas .

  • Haga copias de seguridad periódicas de activos y bases de datos.
  • Siempre tenga una configuración sólida y portátil.
  • Administra el código en un repositorio de código.
  • Use un proceso de implementación que permita la redistribución del código en unas pocas pulsaciones de teclas.
  • Y use una herramienta de configuración del sistema para garantizar que los sistemas / servidores puedan recrearse rápidamente con un mínimo esfuerzo.
  • Si es posible, implemente su código en algún tipo de clúster con carga equilibrada, de modo que si una “cosa” del código en ejecución se ve comprometida, puede eliminarlo sin que la aplicación finalice completamente.

Docker encaja en el último punto. Igual que las máquinas virtuales, pero Docker incluso mores porque una vez que ha tomado la decisión de usar Docker, está usando una herramienta cuya mentalidad / mentalidad es: "No duraré para siempre". Necesito ser recreado ".

Y en el caso de un contenedor Docker infectado, puede desconectarlo, en lo que concierne al mundo exterior, hacer algunos análisis forenses para ver qué sucedió y ver qué se puede hacer para volver a implementar el código de forma segura en otros. La nueva base de código se instala dentro de los contenedores de Docker.

Las máquinas virtuales podrían ser utilizadas de tal manera, pero en mi práctica y experiencia, solo los desarrolladores realmente piensan así sobre las máquinas virtuales. La mayoría de los administradores de sistemas, y los equipos de los que forman parte, ven las máquinas virtuales como una manera de extraer más fácilmente el uso y la utilidad de un servidor completo en lugar de verlas como máquinas desechables rápidamente que pueden recrearse a su antojo. p>

Con Docker, realmente tienes que esforzarte para hacer que un contenedor Docker sea un monolito no desechable. Docker es una herramienta para desarrolladores de aplicaciones creada para una era en la que la virtualización es rápida, barata y fácil. Y cuando se implementa en algún tipo de clúster de carga equilibrada, obtiene la estabilidad adicional de poco o ningún tiempo de inactividad.

    
respondido por el JakeGould 22.09.2017 - 15:55
fuente
10

Estoy de acuerdo con la respuesta de ThoriumBR si estamos comparando una VM en blanco con un contenedor Docker en blanco. Sin embargo, se debe tener en cuenta que la configuración correcta de su sistema, como en Red Hat Atomic Host mitiga muchos de esos factores e incluso elimina algunos.

Además, desde que Docker comenzó, puede contar con una mano el número de tipos de vulnerabilidades mencionadas en su respuesta, todo lo cual podría ser mitigado por otras capas como SELinux . También estamos empezando a ver tiempos de ejecución compatibles con OCI basados en hipervisores, que puede usar en lugar de ejecutar si es realmente paranoico y está dispuesto a recibir un impacto de rendimiento.

Además, señalaré que la gran mayoría de las vulnerabilidades del software no se encuentran en el espacio del kernel / controlador donde las máquinas virtuales tienen la ventaja de seguridad, sino en la capa application , donde los contenedores de Docker tienen la ventaja , porque facilitan la creación de superficies de ataque de un solo proceso. Puede crear un contenedor Docker utilizable con un único ejecutable enlazado estáticamente que se ejecute como un usuario no root, con recursos y capacidades limitados. No puedes hacer una VM con una superficie de ataque tan pequeña.

La conclusión es que tienes que mirar toda la imagen de seguridad. Los contenedores de Docker pueden ser muy seguros, pero debe mirar toda la cadena de suministro del software y asegurarse de configurar la ventana acoplable y el host correctamente. Las máquinas virtuales tienen su propio conjunto de fortalezas y debilidades. No puedes simplemente comparar los dos "fuera de la caja" y tomar una decisión. Necesita un proceso para endurecer cualquiera de las soluciones.

    
respondido por el Karl Bielefeldt 19.09.2017 - 15:13
fuente
6

En la capa de aplicación, sí

La pregunta es demasiado amplia para ser respondida por un simple "sí" o "no".

Hay superficies de ataque muy claras y abiertas para los contenedores de Docker:

  • Si el atacante es el que puede iniciar contenedores (es decir, tiene acceso a la API de Docker), entonces, inmediatamente, sin más acciones, tiene%% de acceso total al host. Esto es bien conocido desde hace años, ha sido probado y no está bajo debate por nadie (Google o SE le dará inmediatamente líneas de comando simples que ni siquiera necesitan un contenedor en particular para que funcione).
  • Si el atacante logra obtener root dentro del contenedor, entonces estás en problemas. En efecto, puede hacer llamadas al kernel bastante arbitrarias e intentar afectar al kernel del host. Desafortunadamente, muchas imágenes docker parecen ejecutar sus cosas como root y omitir root en el Dockerfile, esto no es un problema de Docker sino un problema del usuario.

Veo un escenario que de hecho haría que un sistema basado en imágenes de Docker sea más seguro (posiblemente ...):

  • Si religiosamente hace que sus imágenes sean lo más pequeñas posible, y solo una por preocupación.
  • Y todos se ejecutan sin privilegios (es decir, sin USER y no como --privileged ).
  • Y las redes son lo más ajustadas posible.

Entonces, esto probablemente sería más seguro que una solución VM con los siguientes parámetros:

  • Base instalada lo más pequeña posible.
  • Muchas preocupaciones instaladas en la misma máquina virtual.
  • Establecimiento de una red lo más ajustado posible.

La razón es que si, por ejemplo, un servidor HTTP se divide y se ejecuta dentro de un contenedor mínimo (y me refiero a "mínimo" aquí, es decir, root con nada excepto el mínimo indispensable, que no incluye redes salientes, no rw volúmenes, etc.), entonces hay menos posibilidades de que el atacante pueda hacer algo que si se tratara de una máquina virtual con otros servicios que se ejecutan en ella.

Obviamente, este escenario asume que las máquinas virtuales son en realidad más gordas que los contenedores. Si hace que las máquinas virtuales sean lo mismo que los contenedores, entonces es un punto discutible. Pero entonces, un escenario Docker bien diseñado se diseñaría de esa manera. Y una configuración de VM habitual podría , al menos con el tiempo, migrar a más y más cosas que se están instalando.

    
respondido por el AnoE 21.09.2017 - 13:47
fuente
2

Ya hay algunas respuestas geniales, pero para tener una ilustración completa de la diferencia entre la ventana acoplable y la máquina virtual, agregaré una imagen:

Source

Desde esa perspectiva, es más fácil comprender por qué es más segura la VM que el contenedor Docker.

    
respondido por el Mirsad 29.09.2017 - 06:32
fuente
1

El principal punto de venta de la ventana acoplable no es ser más seguro, sino más fácil. Esto incluye:

  • Valores predeterminados útiles, incluidas algunas opciones de seguridad.
  • No trabaje con la configuración de LXC, cgroups, etc.
  • Imágenes confeccionadas que se pueden descargar con una sola línea.
  • máquinas virtuales reproducibles. No más argumentos de "funciona en mi máquina".

Docker es tan seguro como las técnicas que usa, que son principalmente LXC (espacios de nombres de Linux), selinux y apparmor.

El uso de la ventana acoplable a menudo es terriblemente inseguro. Las personas están usando una línea para descargar una imagen hecha por alguien, ni siquiera leen el nombre antes de ejecutar el contenedor de su sistema operativo. Incluso cuando crea la imagen desde una imagen base propia (fácil de crear con debootstrap como cuando construye un chroot) y un Dockerfile, a menudo incluye el anti-patrón curl $URL|bash para instalar el software en el contenedor.

La otra cosa es que "la forma de conexión" no es actualizar las imágenes, sino reconstruirlas. Esto significa detenerse (mientras que la gente a menudo asume que tiene una conmutación por error ejecutándose con la nueva imagen), reconstruir y comenzar de nuevo.

Esto se debe a la forma en que se crean las instantáneas, donde un habitual apt-get dist-upgrade introduce capas que son semánticamente ruidosas desde el punto de vista de la ventana acoplable, donde el historial debería verse como "baseimage, agregado apache, agregado php, instalado roundcube" sin "actualización diaria de apt-get" entre los pasos.

Si está manteniendo un repo de imagen propio en su LAN, la ventana acoplable puede ser muy útil, ya que puede volver a desplegar las imágenes actualizadas rápidamente.

La función de instantánea es otra cosa que puede ser una buena mejora de seguridad, cuando puede retroceder o bifurcar rápidamente una imagen para probar algo nuevo en un entorno de prueba.

La conclusión es que la ventana acoplable es una herramienta muy útil para los desarrolladores, que desean probar la implementación de su código reproducible y sin cambiar su sistema operativo instalado, pero existen mejores soluciones para las producciones. Por lo tanto, puede ejecutar la ventana acoplable en la producción de forma segura, pero esto no hace que las cosas sean más seguras que una buena configuración LXC sin la ventana acoplable.

Por lo que sé, no están restringidos a LXC como su máquina virtual o no se restringirán pronto, especialmente cuando también apuntan a Windows. Elegir otro backend tiene implicaciones de seguridad, que son las mismas que las de LXC vs. KVM vs. VirtualBox. Los otros puntos probablemente permanecerán igual.

    
respondido por el allo 27.09.2017 - 16:11
fuente
0

Primero, me gustaría señalar que cuanto más reutilice / comparta más los mismos recursos, más seguro estará.

Dijo que, Docker intenta ejecutar cada proceso en un arenero (Contenedor) y esta es la única razón por la que la ventana acoplable puede considerarse más segura. Desde el proceso múltiple que ejecuta su servidor, teóricamente tendrá acceso a su propio proceso y expondrá una carpeta compartida o un socket al otro proceso. Los archivos de configuración, las credenciales, los secretos de otros puertos / sockets de depuración y mantenimiento no serán accesibles incluso desde la misma "máquina".

Docker se siente más seguro ya que la forma en que se ha diseñado para funcionar: es un entorno de prueba en cada proceso en ejecución. Cuando en Virtual Machines y Baremetal se encuentra un grupo de procesos y aplicaciones en sandbox, es responsabilidad suya configurar los permisos en consecuencia.

    
respondido por el albert 29.09.2017 - 11:10
fuente

Lea otras preguntas en las etiquetas