Docker y Kubernetes en entornos exigentes de seguridad

Nota perev. : El artículo original fue escrito por un ingeniero de Suecia, Christian Abdelmassih, aficionado a la arquitectura de nivel empresarial, la seguridad de TI y la computación en la nube. Recientemente, recibió una maestría en Ciencias de la Computación y tiene prisa por compartir su trabajo: una tesis de maestría, o más bien, parte de ella, dedicada a los problemas de aislar una aplicación en contenedores [y lanzada en Kubernetes]. Como el "cliente" para quien se preparó este trabajo de investigación, actúa no menos que la policía de su tierra natal.



La orquestación de contenedores y la informática nativa de la nube se han vuelto muy populares en los últimos años. Su adaptación ha alcanzado un nivel tal que incluso las empresas financieras, los bancos y el sector público muestran interés en ellos. En comparación con otras empresas, se distinguen por sus amplios requisitos en el campo de la seguridad de la información y la TI.

Uno de los aspectos importantes es cómo se pueden usar los contenedores en entornos de producción y, al mismo tiempo, se puede mantener la separación del sistema entre las aplicaciones. Dado que tales organizaciones usan entornos de nube privada basados ​​en la virtualización sobre metal desnudo, la pérdida de dicho aislamiento al migrar a un entorno con contenedores orquestados es inaceptable. Dadas estas limitaciones, mi disertación fue escrita, y la policía sueca es considerada como un cliente objetivo.

El tema específico del estudio considerado en la tesis es:

¿Cómo se admite la demarcación de aplicaciones en Docker y Kubernetes en comparación con las máquinas virtuales que se ejecutan sobre el hipervisor ESXi que se ejecuta en metal desnudo?

Este problema requiere un estudio cuidadoso. Para comenzar con algo, mire el denominador común: aplicaciones.

Las aplicaciones web son confusas


Vulnerabilidades en aplicaciones web: un verdadero zoológico de vectores de ataque. Los riesgos más significativos se presentan en OWASP Top 10 ( 2013 , 2017 ). Estos recursos ayudan a educar a los desarrolladores para reducir los riesgos típicos. Sin embargo, incluso si los desarrolladores escribieron código perfecto, la aplicación aún puede ser vulnerable, por ejemplo, a través de dependencias de paquetes.

David Gilbertson escribió una gran historia sobre cómo puede inyectar código a través de un paquete malicioso distribuido, por ejemplo, como parte de NPM para aplicaciones basadas en Node.js. Para detectar vulnerabilidades, puede usar escáneres de dependencia, pero solo reducen el riesgo, pero no lo eliminan por completo.

Incluso si crea aplicaciones sin dependencias de terceros, sigue siendo poco realista creer que la aplicación nunca será vulnerable.

Debido a estos riesgos, no podemos decir que las aplicaciones web sean seguras.

En cambio, mantén una estrategia de defensa en profundidad (DID). Echemos un vistazo al siguiente nivel: contenedores y máquinas virtuales.

Contenedores versus máquinas virtuales: una historia de aislamiento


Un contenedor es un entorno de espacio de usuario aislado que a menudo se implementa utilizando las capacidades del kernel. Por ejemplo, Docker usa los espacios de nombres de Linux, cgroups y capacidades para esto. En este sentido, el aislamiento de los contenedores Docker es muy diferente de las máquinas virtuales lanzadas por hipervisores tipo 1 (es decir, que trabajan directamente en hardware; hipervisores de metal desnudo) .

La diferenciación para tales máquinas virtuales se puede implementar a un nivel tan bajo como en el hardware real, por ejemplo, a través de Intel VT . Los contenedores Docker, a su vez, dependen del kernel de Linux para la demarcación. Es muy importante tener en cuenta esta diferencia cuando se trata de ataques de capa por debajo .

Si un atacante puede ejecutar código en una máquina virtual o contenedor, puede llegar potencialmente a un nivel inferior realizando un ataque de escape .


dependiendo de si se utilizan contenedores o máquinas virtuales en el hardware, la diferenciación se implementa en diferentes niveles de infraestructura.

La posibilidad de tales ataques se probó para el hipervisor VMware ESXi durante el concurso de piratas informáticos Pwn2Own 2017, así como para GeekPwn2018. El resultado fue un par de CVE ( CVE-2017–4902 , CVE-2018–6981 ) que se pueden usar en ataques de capa inferior para salir de máquinas virtuales ( escape de máquina virtual ) . Las máquinas virtuales en servidores de hierro no garantizan una seguridad absoluta, a pesar de que utilizan tecnología para diferenciar el nivel de hierro.

Por otro lado, si miramos los vectores de ataque en un hipervisor de metal desnudo versus el kernel de Linux, es obvio que este último tiene una superficie de ataque mucho mayor, debido a su tamaño [kernel de Linux] y su rango de capacidades. Una superficie de ataque más grande implica más vectores de ataque potenciales para entornos de nube que usan aislamiento de contenedor. Esto se manifiesta en la creciente atención a los ataques de escape de contenedores , que fueron posibles gracias a las vulnerabilidades del kernel (por ejemplo, CVE-2016–5195 [es decir, Dirty COW - aprox. Transl.] , CVE-2017–1000405 )

Se pueden utilizar módulos como SELinux o AppArmor para aumentar el aislamiento dentro del contenedor. Desafortunadamente, tales mecanismos de seguridad en el núcleo no evitan los ataques de escape en el núcleo mismo. Solo limitarán las posibles acciones del atacante si no es posible ir más allá de los límites. Si queremos lidiar con las salidas fuera del contenedor, se necesita un mecanismo de aislamiento fuera del contenedor o incluso el núcleo. Por ejemplo, un sandbox (sandbox) !

gVisor es un espacio aislado para el tiempo de ejecución del contenedor, cuyo código fue abierto por Google y que agrega un núcleo adicional entre el contenedor y el núcleo del sistema operativo. Este tipo de sandbox puede mejorar la situación con los ataques de contenedores fuera del límite que tienen lugar a nivel del núcleo . Sin embargo, los exploits principales son solo una de las herramientas del atacante.

Para ver cómo otros ataques pueden conducir a resultados similares, debe mirar una imagen más general de cómo se usan los contenedores en la era nativa de la nube.

El efecto de la orquestación de contenedores en el aislamiento.


Para gestionar contenedores que se ejecutan en entornos con muchos nodos, introducen la orquestación, en la que Kubernetes le da el papel principal. Como resultado, los errores del orquestador también pueden afectar el aislamiento del contenedor.

Tim Allclair hizo una presentación maravillosa en KubeCon 2018, en la que observó algunas superficies de ataque. En su informe, menciona un ejemplo ( CVE-2017-1002101 ), cómo los errores de orquestación pueden afectar el aislamiento, en este caso, a través de la capacidad de montar espacio en disco fuera del pod. Las vulnerabilidades de este tipo son muy problemáticas porque puede evitar la caja de arena en la que está envuelto el contenedor.

Al presentar Kubernetes, hemos expandido la superficie de ataque. Incluye sistemas alojados en el maestro Kubernetes. Uno de ellos es el servidor API de Kubernetes, donde recientemente descubrieron una vulnerabilidad que podría permitir privilegios excesivos ( CVE-2018–1002105 ). Dado que la superficie de ataque del maestro Kubernetes está más allá del alcance de mi disertación, esta vulnerabilidad particular no se tiene en cuenta.

¿Por qué son tan importantes los ataques de escape? Los contenedores proporcionan la capacidad de ejecutar muchas aplicaciones cohospedadas dentro del mismo sistema operativo. Por lo tanto, existía un riesgo asociado con el aislamiento de la aplicación. Si una aplicación crítica para el negocio y otra aplicación vulnerable se ejecutan en el mismo host, un atacante podría obtener acceso a una aplicación crítica a través de un ataque a una aplicación vulnerable.

Dependiendo del tipo de datos con los que trabaje la organización, su filtración puede dañar no solo a la organización en sí, sino también a las personas y a todo el país. Como recordarán, estamos hablando del sector público, las finanzas, los bancos ... una fuga puede afectar seriamente la vida de las personas.

Entonces, ¿se puede usar la orquestación de contenedores en tales entornos? Antes de embarcarse en una mayor reflexión, se debe realizar una evaluación de riesgos.

¿Qué riesgo es aceptable?


Antes de introducir medidas de seguridad, es importante pensar qué tipo de información la organización realmente está tratando de proteger. La decisión sobre si se necesitan más pasos para evitar posibles ataques de escape en los contenedores depende de los datos con los que la organización está trabajando y de los servicios que proporciona.

A largo plazo, esto significa que para lograr la posibilidad de salir del contenedor en un host configurado correctamente protegido por el sandbox para el contenedor, el atacante debe:

  1. ejecutar código en un contenedor, por ejemplo, mediante inyección de código o utilizando vulnerabilidades en el código de la aplicación;
  2. aproveche otra vulnerabilidad, día cero, o para la cual aún no se ha aplicado un parche para salir del contenedor a pesar de que hay un entorno limitado .

Como puede suponer, una organización que no considera que tal escenario sea aceptable debería trabajar con datos u ofrecer servicios que sean muy exigentes en cuanto a confidencialidad , integridad y / o accesibilidad .

Dado que la disertación está dedicada solo a dichos clientes, la pérdida del aislamiento del sistema al salir del contenedor no está permitida, ya que Sus consecuencias son demasiado significativas. ¿Qué pasos se pueden tomar para mejorar el aislamiento? Para subir un nivel en la escalera de aislamiento, también debe mirar los sandboxes en los que está envuelto el núcleo del sistema operativo, es decir máquinas virtuales!

Las tecnologías de virtualización que utilizan hipervisores alojados mejorarán la situación, pero queremos limitar aún más la superficie de ataque. Por lo tanto, examinemos los hipervisores instalados en hierro y veamos a qué nos llevarán.

Hipervisores en hierro


Un estudio realizado por la Agencia Sueca de Investigación de Defensa Sueca examinó los riesgos de virtualización en relación con las Fuerzas Armadas suecas. Su conclusión habló de los beneficios de estas tecnologías para los militares, incluso con los estrictos requisitos de seguridad y los riesgos que conlleva la virtualización.

En este sentido, podemos decir que la virtualización se utiliza (hasta cierto punto) en la industria de la defensa, ya que conlleva riesgos aceptables . Dado que las agencias y empresas en la industria de defensa son uno de los clientes más exigentes para la seguridad de TI, también podemos argumentar que el riesgo aceptable para ellos significa que es aceptable para los clientes considerados en la disertación. Y todo esto, a pesar de las posibles salidas más allá de la máquina virtual, discutido anteriormente.

Si decidimos utilizar este tipo de sandbox para contenedores, hay algunas cosas a tener en cuenta en el contexto de los detalles nativos de la nube.

Sandbox nodos para máquinas virtuales


La idea es que los nodos del clúster de Kubernetes son máquinas virtuales que utilizan la virtualización de hardware. Dado que las máquinas virtuales desempeñarán el papel de sandboxes para contenedores que se ejecutan en pods, cada nodo puede considerarse como un entorno protegido de sandbox.

Una nota importante sobre estos sandboxes en el contexto de los sandboxes de contenedores ya mencionados: este enfoque le permite colocar muchos contenedores en un sandbox. Esta flexibilidad le permite reducir los gastos generales en comparación con el caso en que cada contenedor tiene su propia caja de arena. Como cada sandbox trae su propio sistema operativo, queremos reducir su número mientras mantenemos el aislamiento.


Las máquinas virtuales instaladas en el hardware (nodos del clúster) actúan como cajas de arena para contenedores. Los contenedores que se ejecutan en diferentes máquinas virtuales están delimitados con un nivel de riesgo aceptable. Sin embargo, esto no se aplica a los contenedores que se ejecutan en la misma máquina virtual.

Sin embargo, dado que Kubernetes es capaz de cambiar la ubicación de las cápsulas por varias razones, lo que puede arruinar la idea de que se usen cajas de arena , será necesario agregar restricciones al mecanismo para la colocación conjunta de las cápsulas. Puede lograr lo deseado de muchas maneras.

Al momento de escribir, Kubernetes (v1.13) admite tres métodos principales para controlar la planificación y / o lanzamiento de pods:


El (los) método (s) a utilizar depende de la aplicación de la organización. Sin embargo, es importante tener en cuenta que los métodos difieren en su capacidad para descartar pods después de que entran en la etapa de ejecución. Ahora solo las manchas son capaces de esto, a través de la acción NoExecute . Si no procesa este momento de ninguna manera y algunas etiquetas cambian, entonces todo puede conducir a una ubicación conjunta no deseada.

Cumplimiento de los requisitos de uso compartido


La disertación propone la idea de utilizar un sistema de clasificación que muestre cómo se refleja la sensibilidad en la ubicación conjunta. La idea es utilizar la relación 1: 1 entre el contenedor y la cápsula y determinar la ubicación conjunta de las cápsulas en función de la clasificación de las aplicaciones en contenedores.

Para simplificar y reutilizar, se utiliza el siguiente sistema de clasificación de 3 pasos:

  • Clase O : la aplicación no es sensible y no tiene requisitos de aislamiento. Se puede colocar en cualquier nodo que no pertenezca a otras clases.
  • Clase PG (grupo privado) : una aplicación, junto con un conjunto de otras aplicaciones, forma un grupo privado para el que se requiere un nodo dedicado. Una aplicación solo puede alojarse en nodos de clase PG que tengan el identificador de grupo privado correspondiente.
  • Clase P (privado) : una aplicación requiere un nodo privado y separado y solo se puede colocar en nodos vacíos de su clase (P).

Para cumplir con los requisitos de ubicación conjunta para muchas aplicaciones clasificadas, se utilizan contaminaciones y tolerancias, con las cuales se asigna una clase a cada nodo, y PodAffinity para aplicar restricciones adicionales para las cápsulas con aplicaciones de clase P o PG.

Este ejemplo simplificado muestra cómo las contaminaciones y las tolerancias se pueden usar para implementar el control de ubicación conjunta:



Los pods 2 y 3 contienen aplicaciones de un grupo privado, y la aplicación en el Pod 1 es más sensible y requiere un nodo dedicado.

Sin embargo, las clases P y PG requerirán reglas de afinidad adicionales para garantizar que las solicitudes de demarcación se ejecuten a medida que crecen el clúster y las aplicaciones alojadas. Veamos cómo puede implementar estas reglas para diferentes clases:

 # Class P affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: "kubernetes.io/hostname" namespaces: ["default"] labelSelector: matchExpressions: - key: non-existing-key operator: DoesNotExist 

Las reglas de afinidad para aplicaciones de clase P requieren nodos dedicados. En este caso, el pod no se programará si sale sin non-existing-key . Todo funcionará hasta que un solo pod tenga esta clave.

 # Class PG affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: "kubernetes.io/hostname" labelSelector: matchLabels: class-pg-group-1: foobar podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: "kubernetes.io/hostname" labelSelector: matchExpressions: - key: class-pg-group-1 operator: DoesNotExist 

Para las aplicaciones de clase PG, las reglas de afinidad serán anfitriones compartidos de pods que tengan un identificador de grupo class-pg-group-1 y en nodos que tengan pods sin un identificador.

Tal enfoque nos permitirá utilizar un sistema de clasificación para delimitar contenedores en función de los requisitos relevantes de una aplicación en contenedores.

Que conseguimos

Conclusión


Consideramos una forma de implementar sandboxes basados ​​en el hipervisor tipo 1 (es decir, lanzado en metal desnudo) para crear nodos en grupos de Kubernetes y presentamos un sistema de clasificación que define los requisitos para delimitar aplicaciones en contenedores. Si comparamos este enfoque con las otras soluciones consideradas, tiene ventajas en términos de asegurar el aislamiento del sistema.

Una conclusión importante es que la estrategia de aislamiento restringe la propagación de los ataques de escape al contenedor. En otras palabras, no se evita dejar el contenedor solo, pero se mitigan sus efectos. Obviamente, junto con esto vienen dificultades adicionales que deben tenerse en cuenta al hacer comparaciones similares.

Para utilizar el método especificado en un entorno de nube y proporcionar escalabilidad, se impondrán requisitos adicionales a la automatización. Por ejemplo, para automatizar la creación de máquinas virtuales y su uso en el clúster de Kubernetes. Lo más importante será la implementación y verificación de la clasificación generalizada de las aplicaciones.

Esto es parte de mi disertación sobre el aislamiento de una aplicación en contenedor .

Para evitar la posibilidad de que un atacante que se desconectó del contenedor en un nodo ataque los servicios de otros nodos, es necesario considerar los ataques propagados por la red . Para tener en cuenta estos riesgos, mi disertación propone la segmentación de la red de clúster e introduce arquitecturas en la nube, una de las cuales tiene un firewall de hardware .

Aquellos que lo deseen pueden familiarizarse con el documento completo: el texto de la disertación es de acceso público: " Orquestación de contenedores en entornos exigentes de seguridad en la Autoridad de Policía de Suecia ".

PD del traductor


Lea también en nuestro blog:

Source: https://habr.com/ru/post/440504/


All Articles