Guide pratique pour sécuriser votre application sur Kubernetes
Dans cet article, nous allons nous intéresser à comment sécuriser une application déployée sur Kubernetes et présenter différents outils qui vont nous assister dans cette tâche.
Le modèle 4C - la défense en profondeur
Quand on parle de sécurisation d’une application Cloud Native - et en particulier d’une application déployée sur Kubernetes - un modèle de sécurité ressort, celui des 4C :
Cloud
Cluster
Conteneur
Code
Ce modèle souligne l’importance du concept de défense en profondeur, une bonne pratique de sécurité applicative que l’on aime pousser chez OCTO Technology. A l’inverse du modèle de sécurité dit “périmétrique” ou "château fort" (qui se concentre sur la sécurité externe à l’application, à coup de pare-feux divers, protections réseaux et autres détections d’intrusion), la sécurité en profondeur vise à améliorer le niveau de sécurité de chaque couche, pour s’assurer d’une protection multiple contre les attaques.
Le modèle C4 peut être représenté comme ci-dessous, chaque couche se reposant sur la précédente :
Les couches du modèle 4C
L’objectif de cet article est de voir ensemble comment l’on peut sécuriser chacune de ces couches à l’aide d’outils de sécurité open source.
A noter que les outils présentés dans l’article ne sont bien entendu pas les seuls outils possibles pour répondre au besoin et que de multiples alternatives existent. Nous allons vous présenter ceux que l’on a pu utiliser et éprouver sur nos projets et missions.
Pourquoi des outils open source ?
Nous privilégions l’utilisation d’outils open source, pour les raisons suivantes :
La confiance dans l’outil, primordiale en sécurité, via l’accès au code mais aussi la visibilité sur la maintenance, la fréquence des nouvelles versions, etc.
La possibilité de contribuer pour améliorer les outils ou leurs règles de détection.
La question des licences : il est plus facile avec un outil open source de s’assurer que chaque personne membre de l’équipe puisse lancer/maîtriser l’outil et ainsi s’assurer d’une responsabilité partagée de la sécurité dans les équipes.
Voyons voir plus en détail comment sécuriser chacune des couches du modèle 4C.
Sécuriser le Cloud (checkov, tfsec)
Quand on parle de la sécurité du Cloud, un mauvais réflexe serait de se dire “C’est bon, mon cloud provider gère la sécurité, j’ai rien à faire ! 🙆”
Il est au contraire primordial de bien connaître son modèle de responsabilité en fonction de l’offre souscrite (IaaS, PaaS, etc.). Ainsi, on saura quelle partie est de notre responsabilité (application, OS, superviseur) et donc quelle partie sécuriser.
Un bon réflexe en sécurité est de se baser sur la documentation officielle de l’outil que l’on utilise (pour un langage, framework, mais aussi un cloud provider). Chaque cloud provider digne de ce nom possède une partie de sa documentation dédiée à la sécurité et la plupart des liens sont trouvables sur la documentation de Kubernetes.
En ce qui concerne la sécurité de l’infrastructure que l’on va provisionner sur le cloud provider, un des composants du Dev(Sec)Ops est de le faire via de l’Infrastructure As Code (ou IaC). Cela nous permet de lancer des outils de sécurité directement sur le code source de notre infrastructure. Ainsi, le feedback sera plus rapide et nous permettra de détecter les failles éventuelles avant même de construire l’infrastructure.
Si vous utilisez Terraform - un des langages d’IaC les plus populaires - les deux outils que nous recommandons sont checkov et tfsec. Ces outils vont nous permettre de détecter des problèmes de sécurité dans la configuration de nos ressources, comme par exemple des flux un peu trop ouverts, des versions de protocole non sécurisées ou encore l’absence de chiffrement. Checkov semble plus complet, mais la possibilité de lancer tfsec par niveau de sévérité apporte plus de flexibilité et de facilité d’usage, surtout lorsqu’on a une base de code d’infrastructure conséquente. À vous de faire votre choix !
Exemple de résultats de l’outil tfsec sur un cluster AKS mal configuré
A noter qu’il est important de mettre en place ces outils dans le pipeline de sa CI, et de le faire idéalement dès le début du projet. En effet, certains changements d’infrastructure (par exemple l’activation d’une option de sécurité) nécessitent de détruire et reconstruire la brique en question. Ce qui est facile en début de projet, beaucoup moins quand on est en production !
Sécuriser le Cluster (cert-manager, gatekeeper, falco, …)
La sécurité dans Kubernetes étant un sujet vaste (gestion des accès, configuration des ressources, surveillance au runtime, etc.), de nombreux outils peuvent nous assister dans la tâche de vérifier que notre cluster est correctement configuré :
Plusieurs outils, comme Teleport ou Boundary, permettent de sécuriser l’accès à l’administration du cluster.
cert-manager permet de générer et renouveler automatiquement ses certificats TLS.
Gatekeeper permet d’utiliser Open Policy Agent afin de vérifier la conformité de ses ressources Kubernetes contre un jeu de règles. On peut écrire ses propres règles, et/ou utiliser des règles communautaires. À noter que l’on peut utiliser l’outil en mode audit pour surveiller le cluster, ou en mode bloquant pour s’assurer qu’aucune ressource non conforme ne puisse être créée. Il existe d’autres outils pour répondre au même besoin, comme Kyverno, qui présente une syntaxe plus simple (coût d’entrée moindre) mais moins puissante que le rego utilisé pour Gatekeeper.
Popeye permet de détecter des soucis de configuration, basés sur des règles écrites pour l’outil (et configurables). L’outil ne se limite pas à la sécurité.
rbac-tool, KubiScan, ou encore Krane permettent de s’assurer que la gestion des droits sur le cluster via les RBAC ne soit pas trop permissive.
Falco permet de surveiller l’état du cluster en temps réel et de remonter des comportements anormaux.
Vous pouvez aussi contrôler la conformité de votre cluster avec des normes telles que le CIS benchmark, via des outils comme kube-bench, kubescape ou encore kubeaudit.
Enfin, un outil comme Mozilla Observatory permet, de manière manuelle ou automatique, de vérifier la sécurité de sa configuration web de bout en bout (certificats, headers HTTP, cookies, etc.)
Sécuriser le Conteneur (hadolint, trivy, helm, nova, …)
En ce qui concerne les conteneurs, la première étape à sécuriser est la création de l’image. Plusieurs outils peuvent nous aider à détecter des mauvaises pratiques, comme l’utilisation de l’utilisateur root par exemple. On peut recommander le linter hadolint ou encore dockle. À noter que le premier s'exécute sur le Dockerfile et le second sur l’image déjà buildée. Dockle aura donc une boucle de feedback plus longue mais pourra détecter davantage de mauvaises pratiques, comme celles liées à l’image de base choisie. On peut donc utiliser les deux de manière complémentaire.
Une fois notre image correctement construite, il est primordial de vérifier les vulnérabilités présentes dans nos conteneurs en production, ou même avant qu’ils arrivent en production. Nous recommandons vivement l’outil trivy (dont nous parlions déjà il y a 4 ans), qui s’intègre parfaitement dans une CI.
À noter qu’une fois le conteneur parti en production, de nouvelles vulnérabilités peuvent apparaître, donc il ne faut pas oublier de scanner aussi l’ensemble des images déployées sur le cluster (par exemple via l'opérateur kubernetes de trivy). La plupart des registry d’images Docker offrent aussi la possibilité de scanner les images stockées de manière régulière.
Nous avons déjà parlé de ces outils de sécurité liés aux conteneurs dans un précédent article du blog.
Si vous déployez des applications open source dans votre cluster (par exemple Kong, Prometheus, Grafana, etc.) via Helm, l’outil nova va vous permettre de suivre ces différentes charts pour savoir quand de nouvelles versions sont disponibles (ou alors si elles sont dépréciées).
Enfin, il est possible de s’assurer que les images que l’on déploie sur son cluster sont bien celles que l’on souhaite déployer, afin de se protéger contre les attaques de type supply chain. On peut signer ses images et vérifier la signature lors du déploiement, via l’outil notary par exemple. Celui-ci est intégré à de nombreuses registry d‘images Docker.
Sécuriser le Code (SCA, SAST, DAST)
Pour la dernière couche, celle du code, les outils que l’on peut utiliser sont plus classiques et ne sont pas spécifiques aux applications déployées sur Kubernetes.
On peut citer les outils d’analyse :
des dépendances ou SCA (Software Composition Analysis) : npm audit, yarn audit, audit-ci, DependencyCheck, osv-scanner
statique ou SAST (Static Application Security Testing) : semgrep, SonarQube
dynamique ou DAST (Dynamic Application Security Testing) : ZAP
Les deux premiers (SCA et SAST) sont indispensables et doivent être mis en place dans l’idéal au début du projet, pour faciliter la prise en compte des retours des outils. Le choix des outils doit être fait en fonction du langage utilisé (il existe des SCA et des SAST pour tous les langages modernes).
Nous avons déjà parlé en détail du SAST dans cet article : https://blog.octo.com/efficace-et-pas-cher-cest-le-sast-que-je-prefere/
En ce qui concerne les outils de type SCA, nous recommandons de les associer à des outils qui aident au maintien à jour des dépendances, tels que renovate ou dependabot.
L’analyse dynamique, par le biais d’outils DAST, est plus complexe à mettre en place car nécessite une maîtrise à la fois de l’outil utilisé et du contexte de l’application. On la recommande dans un second temps, une fois des outils de type SCA et SAST mis en place.
Conclusion
Aujourd’hui, la prise en compte des différents niveaux d’une infrastructure est essentielle en sécurité, c’est la défense en profondeur. Pour chacune des couches, des outils open source sont disponibles pour nous aider à automatiser et améliorer la sécurité.
Cela étant dit, les meilleurs outils du monde ne remplaceront pas la réflexion humaine mais vont plutôt l’accompagner, et lui permettre de se concentrer sur les points les plus sensibles (lors des revues par exemple) : architecture, moindre privilèges (RBAC et ouvertures de flux), ségrégation des tâches, etc.
Il reste aussi indispensable de former les différentes personnes intervenant sur le projet (devs, ops, etc.) aux bonnes pratiques de sécurité, afin de connaître les vulnérabilités à éviter.
Pour conclure, et même si cet article est essentiellement une liste d’outils, il ne faut pas oublier que mettre en place la méthodologie DevSecOps nécessite de travailler en parallèle sur 3 axes : la culture, l’organisation et l’automatisation. Il faut désiloter la sécurité via une culture de responsabilité partagée, une organisation qui permet d’exploiter cette culture ainsi que des outils aux mains de toutes les personnes qui travaillent au quotidien sur les applications à sécuriser.