Soluciones de seguridad contenerizadas: Anchore
Las soluciones basadas en contenedores como Docker son muy populares en la construcción de infraestructuras utilizando pocas líneas de código. Estas soluciones tienen un repositorio, conocido como Registry, donde almacenan todas las imágenes que han sido construidas previamente con objeto de ser usadas posteriormente. A lo largo de los pasados años ya han sido detectadas en el repositorio público (Docker Hub) muchas imágenes con malware incorporado o plagadas de vulnerabilidades, como podemos ver a continuación.
Esta problemática pone en riesgo la seguridad de la infraestructura a través de las aplicaciones que están consumiendo estas imágenes y es por ello que es de vital importancia evitar almacenar en nuestro repositorio imágenes que puedan suponer un problema de seguridad.
¿Qué es Anchore?
Anchore, o Anchore Engine, es una herramienta de código abierto (con versiones privativas) de análisis estático basado en políticas para contenedores de Docker. Automatiza la inspección, análisis y evaluación de imágenes con verificaciones añadidas por el usuario para asegurar los despliegues garantizando que el contenido de estos cumple ciertos criterios.
Además, la forma en que se definen y evalúan las políticas permite que la propia evaluación de políticas funcione como un mecanismo de auditoría, lo que permite evaluaciones puntuales de propiedades de la imagen y de atributos de contenido específicos.
¿Cómo funciona?
Anchore sigue las siguientes fases por cada imagen analizada:
- Obtiene y extrae el contenido de la imagen, pero nunca lo ejecuta.
- Analiza el contenido de la imagen, extrayendo y clasificando la mayor cantidad posible de metadatos.
- Guarda el resultado del análisis en la base de datos para su futuro uso y auditoría.
- Evalua las politicas contra el resultado del análisis guardado previamente, incluyendo vulnerabilidades encontradas en los artefactos descubiertos en la imagen.
- Actualiza los datos usados para la evaluación de políticas y vulnerabilidades y automaticamente actualiza el resultado del análisis de la imagen en caso de que haya nuevos datos.
- Notifica a los usuarios sobre los resultados obtenidos en la evaluación de políticas y descubrimiento de vulnerabilidades.
- Repite los pasos 5 y 6 para garantizar que han sido evaluados con los últimos cambios externos.
La interfaz principal es una API Rest que proporciona herramientas para solicitar análisis, evaluación de políticas, monitorización de las imágenes en los registros además de consultas sobre el contenido de las imágenes y los resultados del análisis.
Hay principalmente dos formas de ejecutar Anchore:
- Interactive Mode: usa la API para solicitar explícitamente un análisis de imágenes, obtención de una evaluación de políticas e informes de contenido, pero solo realiza operaciones cuando un usuario lo solicita específicamente.
- Watch Mode: usa la API para configurar Anchore Engine para sondear registros y repositorios/etiquetas específicas para ver si se agregan nuevas imágenes y extraerlas y evaluarlas automáticamente, emitiendo notificaciones cuando cambie la vulnerabilidad de una etiqueta determinada o el estado de evaluación de la política.
¿Cómo se usa?
Según su documentación, Anchore Engine puede usarse principalmente de dos formas:
Además, está disponible como imagen de Docker y puede ejecutarse localmente a través de un Docker Compose de forma sencilla. Podemos encontrar además diferentes plugin y alternativas para añadir Anchore al CI/CD, como por ejemplo Jenkins, Gitlab CI, Kubernetes, etc.
Anchore en local
Vamos a centrarnos en ejecutar Anchore en local usando Docker, pues es la forma más rápida para ejecutar la herramienta y ver sus diferentes funcionalidades.
Inicialización y comprobaciones iniciales
En primer lugar necesitamos descargar e iniciar el archivo docker-compose proporcionado por Anchore:
~ curl -O https://engine.anchore.io/docs/quickstart/docker-compose.yaml
~ docker-compose up -d
Tras ejecutar el segundo comando podemos verificar que se ha inicializado todo correctamente mediante el comando:
~ docker-compose ps
Obteniendo el siguiente resultado:
Uno de los servicios que tiene Docker Compose es la API, que podemos usar para usar el cliente directamente a través de Docker sin necesidad de instalarlo en nuestra máquina local. Así pues, aprovechemos esta ventaja para comprobar internamente que todo ha sido inicializado correctamente dentro de los contenedores:
~ docker-compose exec api anchore-cli system status
Obteniendo el siguiente resultado que indica que todo está operativo:
Por último, dentro de esta fase de comprobación conviene comprobar que estamos sincronizados correctamente:
~ docker-compose exec api anchore-cli system wait
Obteniendo el siguiente resultado:
Añadiendo una imagen a analizar
Vamos a analizar la imagen pública openjdk en su versión 8-jre-alpine, para ello en primer lugar hay que añadirla a través de nuestro cliente.
~ docker-compose exec api anchore-cli image add docker.io/library/openjdk:8-jre-alpine
Lo cual nos mostrará algo como la siguiente imagen:
Posteriormente, a modo de curiosidad, se podrían realizar comprobaciones sobre dicha imagen antes de analizarla. Por ejemplo podría verse el contenido de la misma.
Pudiendo especificarse que tipo de contenido se desea ver en más detalle:
En este caso estaríamos viendo instalaciones del SO de la imagen junto a su versión y sus licencias correspondientes, información que puede ser útil de cara a un futuro análisis.
Evaluando la imagen
En primer lugar para evaluar una imagen hay que analizar las vulnerabilidades de la misma, y se hace de la siguiente forma:
~ docker-compose exec api anchore-cli image vuln docker.io/library/openjdk:8-jre-alpine all
Como identificador de la imagen también puede usarse su digest, y es recomendable usarlo para evitar problemas de ambigüedad causado por el etiquetado de la misma. Como resultado obtendríamos algo parecido a la siguiente imagen:
Como podemos comprobar, nos ofrece un listado de vulnerabilidades identificadas por su código CVE, severidad, en que versión se arregla (en caso de estar documentado) y un enlace a MITRE para ver el detalle de la vulnerabilidad. En este caso se han identficado bastantes vulnerabilidades y muchas de ellas catalogadas como críticas y altas.
El último paso que nos quedaría por realizar sería aplicar las políticas a esta imagen cuyas vulnerabilidades han sido descubiertas. En este caso vamos a usar las políticas por defecto de Anchore, que simplemente comprueba que no haya ninguna vulnerabilidad alta o crítica.
~ docker-compose exec api anchore-cli evaluate check docker.io/library/openjdk:8-jre-alpine --detail
Obteniendo como resultado:
Como podemos observar, el estado de la evaluación ha sido «fail». Esto causaría que se parara el proceso de CI/CD en el que estuviera la herramienta y no pasara al siguiente, impidiendo que la imagen se subiera al repositorio por ejemplo.
Interpretación de los resultados
Antes de intentar entender los resultados que nos ofrece una evaluación, hay que hacer un repaso sobre qué son y cómo funcionan las políticas de Anchore.
Políticas de Anchore
Una política es un conjunto de reglas definidas por el usuario, representado como un objeto JSON dentro de un Bundle (paquete de políticas), cada una de las cuales define una verificación específica para realizar y una acción resultante para emitir si la verificación devuelve una coincidencia con el análisis de la imagen.
Cuando se lanza una evaluación de una política concreta lo que se hace es la ejecución de todos los triggers definidos dentro del archivo JSON comentado previamente, ejecutando las acciones definidas para cada una de las coincidencias encontradas durante la propia evaluación. Al final se ejecuta una comprobación final a partir del conjunto de acciones que hayan ocurrido previamente, como se puede observar en la siguiente imagen.
Para profundizar más sobre las políticas conviene visitar su documentación.
Falsos positivos
Como toda herramienta de análisis estático, es posible que entre sus resultados se encuentren falsos positivos. Es importante hacer un análisis con personal especializado (SIA) de los resultados obtenidos con motivo de descartar los que puedan suponer un bloqueo.
Evaluación de las políticas
Tras la evaluación de cada uno de los triggers definidos se ejecuta una acción final que puede resultar en uno de estos tres estados:
- STOP: si alguno de los triggers activados contiene esta acción se producirá una detención general.
- WARN: si alguno de los triggers activados contiene esta acción, pero ninguno de los otros tiene un STOP, la evaluación concluirá en WARN. No produce por tanto una detención.
- GO: si ninguno de los triggers tiene un WARN o STOP entonces la evaluación concluirá como GO. Esto no tiene impacto sobre la propia evaluación pero es bastante útil para llevar un registro de todas las versiones por la que ha pasado una imagen, algo bastante útil de cara a auditorías.
Conclusiones
- Anchore Engine es una herramienta muy útil dado que nos permite una inspección, análisis y evaluación de imágenes dentro y fuera del ciclo de CI/CD.
- Es fácilmente integrable al ciclo de CI/CD a través de Jenkins: https://plugins.jenkins.io/anchore-container-scanner/
- Lo que hace realmente interesante a esta solución es la definición de reglas y políticas personalizables, donde podemos indicar unas whitelist y blacklist según convenga, y definiciones de Stoppers o Alertas. Estas configuraciones al ser definidas en un JSON podrían almacenarse en un repositorio donde poder consultar, modificar y eliminar propiedades según convenga.
Referencias
- Anchore Engine Documentation: https://engine.anchore.io/docs/
- 10 Docker Security Best Practices: https://snyk.io/blog/10-docker-image-security-best-practices/
Imagen de cabecera: diarioinforme.com