- Artículo de seguridad en Kubernetes, en el que se analiza la superficie de ataque de Kubernetes, la arquitectura de seguridad, los tipos de ataques según su origen y recomendaciones para administradores y desarrolladores.
- Documento de amenazas, donde se describen tanto la metodología como las 17 amenazas encontradas (en otro artículo analizaré algunas de ellas).
- Informe final de la auditoría de seguridad. Aquí es donde se detallan cada una de las 37 vulnerabilidades de seguridad encontradas.
La auditoría de seguridad
La auditoría se hizo sobre Kubernetes v1.13.4 y se realizaron tanto inspecciones de código manuales como automáticas, así como despliegues de clusters en local como en la nube. Para ello utilizaron Kubespray, ya que permitía configuraciones consistentes entre el entorno local y el de la nube.
De entre las 37 vulnerabilidades encontradas, vamos a analizar las 5 de mayor gravedad. El resto se reparte en 17 de nivel medio, 8 de nivel bajo y 7 informativas. En el issue #81146 se listan las diferentes vulnerabilidades, el estado de la resolución y el issue de cada una.
El tipo HostPath de PersistentVolumes permite saltarse la directiva PodSecurityPolicy
En Kubernetes, PodSecurityPolicy es uno de los recursos que permite al admission controller decidir si un pod puede crearse por parte de un service account o no dependiendo de la configuración que tenga. Por ejemplo, si en un PodSecurityPolicy no se permiten pods en modo privilegiado, cualquier pod que intente crearse en modo privilegiado desde esa service account dará un error.
Esto normalmente funciona, pero en la auditoría de seguridad se encontró un caso en el que, aún teniendo restringido la definición del pod el montaje de volúmenes hostPath (este tipo de volumen monta un directorio del nodo anfitrión haciéndolo accesible desde dentro del contenedor), si se hace en lugar de con un volumen normal con un volumen persistente, a través de un PersistentVolumeClaim esta restricción no se tienen en cuenta.
El efecto es que cualquiera podría montar un directorio de la máquina huésped desde el contenedor y tener acceso al sistema de ficheros, consiguiendo escapar del contenedor. En el apéndice C del informe final hay un ejemplo con los yalm y código necesario para la prueba de concepto de la vulnerabilidad.
El efecto es que cualquiera podría montar un directorio de la máquina huésped desde el contenedor y tener acceso al sistema de ficheros, consiguiendo escapar del contenedor. En el apéndice C del informe final hay un ejemplo con los yalm y código necesario para la prueba de concepto de la vulnerabilidad.
A corto plazo la solución de esta vulnerabilidad ha sido documentar que las PodSecurityPolicy no limitan los tipos de volúmenes persistentes, y que estos deben de darse acceso sólo a usuarios confiables y está cerrado para la v1.16.
No se puede revocar un certificado sin revocar todos los de la red
Los diferentes servicios de Kubernetes utilizan certificados X.509 para asegurar la autenticación, autorización y seguridad del transporte de datos entre ellos. Es el servidor API el que ejerce de entidad certificadora, firma y manda los certificados del resto de servicios.
El problema viene cuando uno de los nodos queda comprometido (por una intrusión, un uso sospechoso de recursos, comportamiento extraño de un contenedor...). En el caso de que se sospeche que el certificado puede haberse visto comprometido no se puede revocar uno de los certificados individualmente, sino que hay que revocar toda la cadena de certificados del sistema, volver a generarlos y volver a mandarlos a los diferentes nodos y servicios.
La solución pasará por tener una lista de certificados revocados. De momento se está proponiendo la implementación de OCSP stampling. Esto implicaría tener un servidor de certificados en el que se podría revocar individualmente el que se quisiera y que estamparía la fecha y hora del certificado antes de usarse para asegurar que sigue siendo válido.
Por defecto no se fuerza el uso de TLS en las conexiones HTTPS
En las configuraciones por defecto de Kubernetes, el servidor API no verifica que las conexiones con el kubelet de los nodos utilice TLS. Esto puede provocar que alguien malintencionado registre en el servidor API servicios kubelet maliciosos que reciban configuraciones e información sensible del cluster.
De momento la solución es utilizar las opciones para forzar la conexión mediante TLS de cada uno de lo servicios. El issue que soluciona esta vulnerabilidad está etiquetado como 'important-longterm', por lo que no parece que a corto plazo vaya a cambiar esta opción insegura por defecto y que tendremos que poner las opciones explícitamente para forzar la comprobación de TLS.
Vulnerabilidad de condición de carrera en los PID que puede dar acceso de root en el host a un proceso en un contenedor
Esta vulnerabilidad es algo más complicada de realizar que las que hemos visto antes. De hecho, requiere que el atacante tenga acceso root a un contenedor del nodo y acceso de usuario a un proceso del propio nodo (fuera de cualquier contenedor).
El ataque se basa en conseguir mediante los PID del proceso de dentro de dentro del contenedor y de fuera del contenedor, que el de cgroup del proceso dentro del contenedor cambie y tenga acceso a leer y escribir fuera del contenedor (recordad que cgroup es junto con los namespaces uno de los mecanismos que se utilizan del kernel de Linux para aislar los contenedores).
De momento no hay una solución para esta vulnerabilidad, también teniendo en cuenta que no es el escenario habitual tener procesos en los nodos corriendo fuera de contenedores y que la solución puede no ser sencilla, se ha etiquetado también como 'important-longterm'.
Vulnerabilidad del comando kubectl cp no resuelta correctamente
El comando 'kubectl cp' es una funcionalidad que permite a administradores copiar ficheros de un contenedor a otro. Sin embargo, no se validaba la estructura de los tar que se utilizaban para traspasar los ficheros, de forma que un atacante podría introducir ficheros malintencionados en un contenedor.
Esto se arregló parcialmente en v1.13 y v1.14 de Kubernetes. Sin embargo, seguían sin comprobarse los links simbólicos. En principio, parece que esta vulnerabilidad está resuelta desde el 30 de abril.
Conclusiones
La primera conclusión es el compromiso firme de Kubernetes con la seguridad al haber dedicado recursos a una auditoría externa de los 1.5 millones de líneas de código (largos) que tiene.
Pero no sólo eso, sino que haber publicado el resultado de la auditoría junto con la respuestas para solucionar cada una de las vulnerabilidades detectadas hace que Kubernetes saque pecho con una de sus mayores fortalezas: la gran comunidad de desarrolladores open source que lo respalda.
Seguiremos los adelantos en la resolución de las diferentes vulnerabilidades y en futuros posts intentaré profundizar en los otros documentos de la auditoría de seguridad, ya que son muy interesantes y permiten conocer la estructura interna de Kubernetes con los puntos fuertes y débiles de sus componentes, su superficie de ataque y las posibles amenazas que existen en el sistema.
No hay comentarios:
Publicar un comentario