Raccourcis

Introduction à la sécurité de Kubernetes

Copier l'URL

Malgré l'adoption croissante des conteneurs et de Kubernetes, la sécurité demeure une préoccupation majeure. Heureusement, de nombreuses solutions existent pour mieux protéger les environnements de conteneurs. Dans cette introduction à la sécurité de Kubernetes, vous découvrirez bon nombre des mesures à votre disposition pour sécuriser vos conteneurs.

Les images de conteneurs sont souvent l'une des principales sources de vulnérabilités d'un environnement cloud-native. Une stratégie de sécurité efficace consiste essentiellement à veiller au respect des meilleures pratiques en matière de création d'images sécurisées dans l'entreprise. Si l'analyse de sécurité est un aspect important de cette stratégie, la sécurisation des images permet d'assurer la sécurité des applications conteneurisées plus tôt dans le cycle de vie.

Adoptez les meilleures pratiques suivantes pour créer des images de conteneurs sécurisées :

  1. Réduisez le nombre d'images de base

    Pour diminuer la surface d'attaque, l'image doit contenir uniquement les bibliothèques et les outils dont le conteneur a besoin.

  2. Utilisez des images de base qui proviennent de sources fiables

    Si vous ne créez pas votre image à partir de zéro, choisissez des images de base issues d'une source fiable. Le fichier Dockerfile et le code source de chaque composant doivent être accessibles et stockés dans un registre réputé fiable. Les images de base doivent aussi être mises à jour régulièrement.

  3. Définissez un utilisateur

    Si aucun utilisateur n'est défini dans le fichier Dockerfile, le conteneur s'exécute par défaut avec l'utilisateur root, ce qui augmente la surface d'exposition aux attaques et facilite l'augmentation des privilèges lorsque l'intégrité de l'application est compromise.

  4. Vérifiez les images Docker

    Il est certes difficile de vérifier l'authenticité des images, mais cela reste essentiel pour créer des images sécurisées. Chaque image de base doit être signée et validée. Veillez à n'utiliser que des images issues de registres fiables pour vous assurer de leur authenticité.

  5. Recherchez les vulnérabilités

    L'identification et la correction des vulnérabilités qui touchent les images de conteneurs, y compris celles qu'introduisent les bibliothèques Open Source, s'avèrent primordiales.

  6. N'utilisez pas de secrets dans les images

    Les secrets contiennent des données sensibles telles que des informations d'identification et des clés. Aussi mieux vaut-il éviter de les intégrer dans vos images de conteneurs.

  7. Limitez les ressources

    En limitant les ressources en processeur et en mémoire auxquelles un conteneur a accès, vous diminuez les dommages que d'éventuels pirates pourraient causer s'ils exploitaient ce conteneur.

  8. Limitez les privilèges

    Définissez des privilèges extrêmement restrictifs et configurez le conteneur de manière à empêcher leur augmentation.

  9. Utilisez des builds en plusieurs étapes

    Il existe un risque de piratage des outils de création qui servent à générer et compiler les applications lors de leur exécution dans les systèmes de production. Au lieu d'utiliser les mêmes images pour les phases de création et d'exécution, préférez un Dockerfile en plusieurs étapes. Vous éviterez ainsi de retrouver des outils compliqués et superflus dans les images lors de l'exécution. Supprimez également les débogueurs dans les images en production.

  10. Appliquez des techniques de codage axées sur la sécurité

    Détectez les portions de code non sécurisées pendant le développement grâce à un linter.

Ces principes, propres au processus de création d'images sécurisées, doivent aussi guider la sécurisation des autres composantes de l'application. Ainsi, il conviendra de réduire au maximum la surface d'attaque, de limiter les privilèges et de définir des configurations très précises plutôt que d'utiliser les paramètres par défaut de Kubernetes et des autres éléments de la pile cloud-native.

Benchmarks CIS pour Kubernetes

Le CIS (Center for Internet Security) a pour mission de définir des meilleures pratiques en matière de cyberdéfense. Il s'appuie sur le crowdsourcing pour fournir des recommandations de sécurité. Les benchmarks comptent parmi les outils du CIS prisés par les entreprises.

Les entreprises peuvent s'appuyer sur le benchmark CIS pour Kubernetes afin de renforcer leurs environnements Kubernetes. Plusieurs outils Open Source et commerciaux permettent de comparer automatiquement les configurations aux paramètres et aux contrôles du benchmark afin de détecter les failles de sécurité.

Le benchmark CIS propose un certain nombre de vérifications de configuration utiles. C'est un bon point de départ pour les entreprises, mais elles ne doivent pas s'arrêter là pour assurer le respect des meilleures pratiques Kubernetes. Il est recommandé de mettre en œuvre des politiques réseau, le contrôle d'accès basé sur les rôles, des privilèges d'administrateur et d'autres protections destinées au serveur d'API Kubernetes.

Le contrôle d'accès basé sur les rôles de Kubernetes est la méthode standard de gestion des autorisations pour les points de terminaison des API Kubernetes. Au niveau du cluster, la configuration de cette fonction permet de choisir les sujets autorisés à exécuter telle ou telle action pour des types de ressources en particulier et dans des espaces de noms spécifiques. Par exemple, l'utilisateur « alice » peut être autorisé à voir les ressources de type « pod » dans l'espace de noms « external-api ». L'API de contrôle d'accès basé sur les rôles inclut quatre objets déclaratifs : Role, ClusterRole, RoleBinding et ClusterRoleBinding.

La ressource Role existe au sein d'espaces de noms et est constituée de règles qui définissent les permissions de chaque espace, contrairement à la ressource ClusterRole (« rôle de cluster ») qui accorde des permissions à l'échelle d'un cluster ou de plusieurs espaces de noms. Une règle est une combinaison d'actions, de types de ressources et de sélecteurs d'espaces de noms.

Le RoleBinding (ou « liaison de rôle ») relie un utilisateur, un groupe d'utilisateurs ou un compte de service (les « sujets ») à un rôle et lui accorde les permissions définies dans ce rôle. L'objet ClusterRoleBinding (« liaison de rôle de cluster »), pour sa part, lie un ClusterRole à l'ensemble des espaces de noms du cluster. Autrement dit, les permissions peuvent s'appliquer soit à un espace de noms (avec le RoleBinding), soit à tout le cluster (avec le ClusterRoleBinding).

D'après l'expérience de nos clients, voici cinq erreurs courantes à surveiller dans les paramètres de configuration du contrôle d'accès basé sur les rôles.

 

Erreur de configuration n° 1 : accorder inutilement le rôle d'administrateur du cluster

Le rôle intégré d'administrateur du cluster octroie un accès illimité au cluster. Au moment de passer du contrôle d'accès basé sur les attributs au contrôle d'accès basé sur les rôles, il arrive que certains administrateurs et utilisateurs répliquent la configuration permissive de l'ancien système en accordant largement le rôle d'administrateur du cluster, sans tenir compte des mises en garde de la documentation associée. Lorsqu'un ou plusieurs utilisateurs se voient régulièrement accorder ce rôle, une faille de sécurité au niveau du compte ou une erreur de configuration devient potentiellement dangereuse, et ce à grande échelle. Bien souvent, cet accès est aussi inutile pour les comptes de service. Dans tous les cas, il est important de créer et d'accorder un Role ou un ClusterRole, plus personnalisé, uniquement aux utilisateurs qui en ont besoin.

Erreur de configuration n° 2 : utiliser l'agrégation des rôles de manière inappropriée

Dans Kubernetes 1.9 et versions ultérieures, l'agrégation des rôles simplifie le processus en permettant d'ajouter de nouveaux privilèges à des rôles existants. Mal encadrée, cette démarche peut modifier l'utilisation prévue pour un rôle. Prenons comme exemple le rôle system:view qui autorise à voir le système. Si on lui ajoute par erreur des actions autres que « voir », ce rôle risque d'autoriser les sujets qui le reçoivent à modifier le cluster.

Erreur de configuration n° 3 : accorder plusieurs rôles qui octroient les mêmes privilèges

Certaines définitions de rôle peuvent se chevaucher, ce qui a pour effet d'accorder aux sujets plusieurs fois le même accès. Parfois, ce chevauchement est intentionnel, même s'il est ensuite plus difficile de savoir quels sujets bénéficient de quels accès. Cette situation complique la révocation des accès, notamment si l'administrateur ne s'aperçoit pas qu'un sujet dispose de plusieurs rôles lui accordant les mêmes privilèges.

Erreur de configuration n° 4 : ne pas utiliser un rôle

Les rôles inutilisés compliquent la gestion du contrôle d'accès basé sur les rôles. De la même manière, il est difficile d'identifier les configurations importantes lorsque des rôles sont accordés uniquement à des sujets inexistants (par exemple, à des comptes de service dans des espaces de noms supprimés ou à des utilisateurs qui ont quitté l'entreprise). La prudence veut que l'on supprime les rôles inactifs ou inutilisés pour se focaliser sur les rôles actifs.

Erreur de configuration n° 5 : accorder des rôles inexistants

Une liaison de rôle peut faire référence à un rôle qui n'existe pas. Supposons maintenant que le nom de ce rôle inexistant soit repris pour un usage différent. La liaison de rôle inactive pourrait, de façon soudaine et imprévue, accorder des privilèges à d'autres sujets que ceux visés par la création du nouveau rôle.

 

Pour limiter les conséquences du piratage d'une application, de l'usurpation d'un compte utilisateur, d'un bogue dans une application ou d'une simple erreur humaine, il convient de configurer correctement les rôles et les liaisons du contrôle d'accès basé sur les rôles pour le cluster.

Sécurité : les conteneurs/Kubernetes et les machines virtuelles

Les machines virtuelles et les conteneurs reposent sur des architectures radicalement différentes, mais ils présentent suffisamment de similitudes pour être confondus. Les différences entre ces deux technologies ont des incidences très importantes sur la sécurité. Les machines virtuelles et les conteneurs prennent en charge l'isolation des applications, à des degrés plus ou moins élevés, ainsi que la portabilité. Complètement autonomes, les machines virtuelles disposent de leur propre système d'exploitation et ne partagent pas de ressources avec les autres machines virtuelles. Avec les conteneurs, au contraire, l'hébergement est mutualisé, ce qui complique la notion de frontière sécurisée.

Les conteneurs et Kubernetes utilisent un modèle architectural différent qui nécessite une autre approche de la sécurité. En effet, les techniques de protection basées sur les hôtes, qui ont fait leurs preuves par le passé, ne conviennent pas. Pas plus d'ailleurs que les autres méthodes comme la mise en place de pare-feu réseau autour d'un périmètre donné. En outre, les meilleures pratiques de sécurité des machines virtuelles consistent principalement en l'application de correctifs. Or, il est impossible d'appliquer un correctif à un conteneur en cours d'exécution. Il faut mettre à jour l'image du conteneur et le recréer.

Pour sécuriser vos conteneurs, vous devez :

  • contrôler la connexion entre chaque conteneur ;
  • vérifier que les conteneurs ne présentent pas de vulnérabilités connues ;
  • bloquer l'accès par l'utilisateur root ;
  • limiter les permissions et l'accès aux ressources nécessaires au bon fonctionnement de l'application.

Kubernetes entraîne davantage de complexité et introduit de nouveaux risques pour la sécurité. La gestion des configurations Kubernetes et des politiques réseau est essentielle pour sécuriser efficacement les applications conteneurisées.

De plus, avec l'adoption des applications conteneurisées, les workflows ont évolué, ce qui nécessite d'intégrer la sécurité tout au long du cycle de vie. La sécurité doit être prise en compte dès le début, dès la configuration des images et des conteneurs. Il est impossible de l'ajouter à la fin du développement des applications conteneurisées, juste avant leur déploiement.

La sécurisation des applications conteneurisées s'articule autour de plusieurs axes : contrôle de la source de l'ensemble des composants (y compris des éléments Open Source), gestion des configurations, analyse des images et activation de contrôles d'accès granulaires basés sur les rôles. Les conteneurs et Kubernetes obligent à repenser la sécurité. Cependant, grâce à leur nature déclarative et immuable, ils offrent l'opportunité de créer des applications plus sécurisées que jamais, à condition toutefois d'être correctement configurés.

Dans Kubernetes, les conteneurs s'exécutent dans un pod, l'un des nombreux objets Kubernetes. Pour chaque pod, la configuration de l'environnement d'exécution peut être définie et appliquée en combinant un contexte de sécurité (dans la spécification du pod), des politiques de sécurité des pods (PSP) et/ou un contrôleur d'admission tel que OPA (Open Policy Agent) Gatekeeper.

Le contexte de sécurité permet de définir des exigences précises pour chaque charge de travail dans le manifeste de déploiement. Il peut être configuré pour un pod ou un conteneur. Les politiques de sécurité des pods sont une ressource Kubernetes au niveau du cluster qui aide à contrôler le contexte de sécurité dans lequel les pods peuvent s'exécuter. Lorsque ces politiques sont activées pour un cluster, le contrôleur d'admission rejette toute tentative de création d'un pod non conforme.

Limitez les privilèges pour l'environnement d'exécution des conteneurs :

  • N'exécutez aucun processus d'application avec l'utilisateur root (définissez runAsUser sur MustRunAsNonRoot).
  • N'autorisez pas l'augmentation des privilèges (définissez allowPrivilegeEscalation sur false).
  • Utilisez un système de fichiers root en lecture seule (définissez readOnlyRootFilesystem sur true).
  • Utilisez le montage de système de fichiers /proc par défaut (masqué).
  • N'utilisez pas le réseau ni l'espace de processus hôte (définissez hostPID, hostNetwork et hostIPC sur false).
  • Supprimez les fonctionnalités Linux inutiles et n'ajoutez pas d'options facultatives qui ne soient pas indispensables pour votre application.
  • Utilisez des options SELinux pour contrôler avec plus de précision les processus.
  • Créez un compte de service Kubernetes par application.
  • Ne montez pas les informations d'identification des comptes de service dans un conteneur qui n'a pas besoin d'accéder à l'API Kubernetes.

 

Utilisez les espaces de noms Kubernetes

Les espaces de noms Kubernetes déterminent la portée des objets du cluster, ce qui permet de les gérer avec précision. Il est possible d'isoler les conteneurs ou pods, les services et les déploiements au sein d'un espace de noms au moyen de contrôles (des politiques réseau Kubernetes, par exemple) ou de limiter leur accès à l'aide du contrôle d'accès basé sur les rôles de Kubernetes.

Déterminez la méthode d'affectation des espaces de noms avant de déployer des charges de travail dans vos clusters. Avec un espace de noms par application, vous bénéficiez d'un meilleur contrôle, même si cela vous demande des efforts supplémentaires pour affecter les privilèges aux rôles et définir les politiques réseau par défaut. Si vous choisissez de regrouper plusieurs applications dans un même espace de noms, déterminez avant tout si ces applications sont soumises à des exigences communes en matière de contrôle d'accès basé sur les rôles. Voyez aussi s'il est prudent d'accorder ces privilèges aux comptes de service et aux utilisateurs qui doivent accéder à l'API Kubernetes depuis cet espace de noms.

La gestion des configurations désigne une pratique d'ingénierie qui consiste à établir des politiques liées aux configurations et à s'assurer de leur application cohérente dans l'ensemble de l'entreprise, tout au long du cycle de vie des applications. Les configurations représentent un aspect essentiel de la gestion des risques dans les applications cloud-native, surtout parce que beaucoup de configurations par défaut des conteneurs et de Kubernetes ne sont pas sécurisées. Les erreurs de configuration sont la principale source de risque pour la sécurité des applications conteneurisées exécutées sur Kubernetes.

D'où la nécessité d'automatiser la gestion des configurations et de centraliser la gestion des mesures de sécurité afin d'épargner aux équipes de développement et d'exploitation la configuration manuelle des charges de travail. En outre, ces mesures doivent reposer sur des politiques de sécurité au niveau de l'entreprise.

Selon IBM, 95 % des failles de sécurité dans le cloud proviennent d'erreurs humaines. À mesure que les applications (exécutées sur des systèmes distribués dans des conteneurs et Kubernetes) se complexifient, le risque de faire des erreurs de configuration augmente. Sans outil de gestion centralisée des configurations, il est presque impossible pour les entreprises de s'assurer que les politiques de configuration sont appliquées de manière cohérente. La tâche est d'autant plus ardue dans les environnements multicloud ou de cloud hybride, qui nécessitent chacun un ensemble de configurations spécifique. De plus, les équipes de développement et d'exploitation ne sont pas encore suffisamment formées sur les meilleures pratiques pour sécuriser les configurations.

Bien souvent, la méthode la plus simple pour configurer les applications est également la moins sûre. Ainsi, il n'est pas rare que les équipes de développement autorisent un accès root, accordent des privilèges d'administrateur ou fixent des limites de ressources très élevées. Avec des outils adaptés, il est possible d'intégrer la gestion des configurations au workflow DevOps, ce qui évite de ralentir le développement. Cette pratique est recommandée, car elle permet de lancer des applications rapidement, tout en sécurisant la configuration des charges de travail.

En plus d'apporter de la visibilité sur les configurations, la gestion des configurations doit être l'occasion d'ajouter des garde-fous pour identifier les configurations autorisées et rejeter automatiquement les versions non sécurisées ou les déploiements risqués. Pour les entreprises, il est essentiel de pouvoir visualiser sur une même interface toutes les configurations pertinentes pour les conteneurs et Kubernetes, et de recevoir des alertes en cas de détection de configurations potentiellement risquées.

Voici les éléments essentiels de la gestion des configurations pour les conteneurs et Kubernetes.

  • Contrôle d'accès basé sur les rôles : les configurations trop permissives et/ou les rôles superflus doivent être identifiés.
  • Secrets : un outil efficace de gestion des configurations limite l'accès aux secrets de manière proactive.
  • Évaluations basées sur les politiques : la définition de politiques de sécurité au niveau de l'entreprise est primordiale dans une posture de sécurité, et la conformité des déploiements doit pouvoir être vérifiée.
  • Privilèges : le principe du moindre privilège prévaut.
  • Limites appliquées aux ressources : il faut limiter les ressources en processeur et en mémoire mises à la disposition des conteneurs et des clusters Kubernetes.
  • Politiques réseau : les échanges entre les différentes composantes de l'application doivent être limités au maximum au moyen de politiques réseau pour réduire les dommages dans l'éventualité où l'intégrité d'un conteneur serait compromise.

Le plus simple pour commencer est de suivre les meilleures pratiques de gestion des configurations reconnues par le secteur, comme les benchmarks CIS. Une fois que l'entreprise a adopté plus largement les conteneurs, il est conseillé de définir des politiques de gouvernance organisationnelles pour encadrer la gestion adaptée des configurations, à la fois pour les conteneurs et pour Kubernetes, afin de renforcer la posture de sécurité.

Par défaut, les pods Kubernetes communiquent librement entre eux au sein du cluster. Ce fonctionnement simplifie les opérations au niveau des applications, mais présente aussi des risques pour la sécurité. Outre les paramètres par défaut, trop permissifs, Kubernetes intègre des fonctionnalités d'application qui permettent de limiter les communications entre les éléments. Le mécanisme de segmentation du réseau, notamment, restreint les échanges entre les différentes composantes du déploiement. Il est également exigé par certains cadres de conformité, comme la norme PCI-DSS.

La segmentation du réseau permet de scinder un réseau en plusieurs sous-réseaux de plus petite taille. D'un point de vue sécuritaire, le principal avantage est le suivant : lorsqu'une personne malveillante accède à une application exécutée sur un cluster Kubernetes qui héberge d'autres applications, elle n'a pas accès aux autres applications. Et grâce à la segmentation du réseau, les charges de travail sensibles et/ou soumises à un cadre de conformité sont isolées du reste de l'application.

Les politiques réseau doivent être extrêmement restrictives : chaque conteneur doit être autorisé à communiquer seulement avec les conteneurs nécessaires pour l'usage prévu de l'application.

Dans Kubernetes, la segmentation du réseau consiste à appliquer des politiques réseau, par le biais des fonctionnalités d'application natives de Kubernetes et de couches d'infrastructure supplémentaires, telles que les Service Mesh.

Par défaut, les échanges entre les pods, les conteneurs et les nœuds dans un même espace de noms ou entre des espaces différents ne font l'objet d'aucune restriction. L'application de politiques réseau permet donc de limiter ces échanges. Il est conseillé de refuser toutes les communications pour commencer. Cependant, comme les pods ont besoin d'échanger entre eux, il faudra ensuite lister ceux avec lesquels un pod spécifique doit pouvoir communiquer. Le trafic entrant et sortant vers et depuis l'Internet public doit également être autorisé, mais uniquement pour les pods qui en ont besoin.

Les entreprises courent aussi des risques en modifiant leurs politiques réseau et en ayant davantage recours à la segmentation du réseau. Un outil adapté peut leur permettre de visualiser l'incidence de l'ajustement de ces politiques à l'échelle du système sur l'application et les aider à limiter les effets imprévus qui en découlent.

Aucune entreprise ne disposera jamais d'une infrastructure informatique ou d'applications parfaitement sécurisées. La sécurité implique une hiérarchisation des mesures ainsi qu'une bonne compréhension des risques et compromis associés aux différentes actions possibles. Le processus d'établissement du profil de risques consiste à dresser un état des risques connus ainsi que des politiques et pratiques que met en place l'entreprise pour les gérer. Chaque entreprise doit accepter une part de risque. Reste à déterminer avec précision quel niveau de risque est acceptable. L'établissement du profil de risques concerne non seulement l'entreprise dans sa globalité, mais aussi chaque application. Le profil de risques sera différent pour les charges de travail sensibles ou soumises à des exigences de conformité et pour les charges non sensibles.

Ce processus permet également d'évaluer l'importance des vulnérabilités dans l'environnement. Il n'est pas possible de traiter chaque vulnérabilité. Une posture de sécurité efficace consiste donc à évaluer le risque des différentes vulnérabilités pour hiérarchiser au mieux les mesures à mettre en œuvre.

Dans le cas d'une application conteneurisée et distribuée, il peut s'avérer difficile d'analyser le profil de risques et d'accorder la priorité à telle ou telle vulnérabilité. Une application peut présenter un nombre plus ou moins élevé de vulnérabilités, mais chaque vulnérabilité a un niveau de risque différent. Le risque pour la sécurité induit par une vulnérabilité dépend de plusieurs facteurs :

  • La gravité de la vulnérabilité
  • Si l'application est accessible à l'extérieur de l'entreprise
  • Si l'application est en production
  • Si l'application fait l'objet de réglementations
  • Si l'application accède à des données sensibles
  • Les privilèges définis pour le conteneur
  • L'exposition du conteneur au réseau

Les entreprises doivent déterminer en amont le niveau de risque acceptable, souvent en fixant des politiques internes en matière de délai de résolution pour chaque degré de gravité. Cependant, l'établissement du profil de risques n'est pas une opération ponctuelle et figée. L'évaluation des risques liés à la sécurité, en particulier pour une application conteneurisée, doit se poursuivre tout au long de la phase d'exécution.

Le tri manuel des incidents potentiels de sécurité, des vulnérabilités et des politiques est source d'erreurs et tend à épuiser les équipes. À grande échelle, sans outils automatisés de détection et de hiérarchisation des risques, il est souvent impossible d'établir un profil de risques. Pour mener à bien l'exercice, il faut exploiter les données contextuelles et déclaratives de Kubernetes, ce qui permet d'automatiser le classement des risques. Ainsi, les équipes de sécurité concentrent leurs efforts sur la correction des déploiements au niveau de risque élevé, et non plus sur le processus d'établissement du profil de risques.

Dans l'idéal, le profil de risques est utilisé de manière proactive et réactive. Dès qu'un risque est identifié et écarté dans un déploiement, l'information peut être réutilisée pour identifier d'autres déploiements qui présentent des facteurs de risque similaires et ainsi gérer les risques potentiels en amont.

La sécurité de l'environnement d'exécution est une ligne de défense essentielle contre les attaques. Idéalement, les vulnérabilités non corrigées, les configurations risquées et les informations d'identification non sécurisées doivent être détectées lors de la création ou du déploiement des applications. En réalité, il n'est pas rare que des vulnérabilités échappent aux équipes au début du cycle de vie, d'où la nécessité de détecter les menaces et de résoudre les incidents en cours d'exécution. D'autant plus que de nouvelles vulnérabilités sont régulièrement identifiées. Cette vigilance est d'ailleurs également importante pour des raisons de conformité et pour se protéger contre les menaces internes.

Les charges de travail immuables et déclaratives obligent à changer de modèle pour la détection et la résolution des incidents potentiels liés à la sécurité en cours d'exécution. Cette nature déclarative de Kubernetes et le fait que les conteneurs exécutent généralement un nombre réduit de processus simplifient certains aspects de la sécurité pendant l'exécution par rapport à une infrastructure basée sur des machines virtuelles. Par contre, il n'est pas possible de « corriger » des conteneurs en cours d'exécution en appliquant des correctifs comme avec une application basée sur des machines virtuelles. Comme ils sont considérés comme immuables, ils doivent être supprimés, mis à jour, puis redémarrés.

La détection est le fondement de la sécurité dans l'environnement d'exécution. Elle implique de définir le comportement de référence de l'application et d'analyser toute activité qui s'en éloignerait trop. Les requêtes réseau et les exécutions de processus sont des exemples d'activités qui peuvent faire l'objet d'un suivi. Une activité devient potentiellement suspecte ou malveillante dès lors qu'elle ne correspond pas au comportement attendu. C'est le cas, par exemple, des tentatives de connexion non autorisées à Internet. Dans tous les cas, un comportement anormal indique un problème qui doit être résolu.

La détection des anomalies se veut plus précise dans les conteneurs que dans les machines virtuelles, car les conteneurs ne renferment qu'une seule application. Il est donc plus facile de faire la distinction entre les comportements de référence et les comportements anormaux pour un conteneur. En revanche, la détection des anomalies doit toujours être corrélée à un processus de résolution des incidents.

Selon le type de comportement anormal, la meilleure solution est peut-être de gérer le problème automatiquement en laissant la plateforme supprimer les pods ou les conteneurs affectés. Dans certains cas cependant, il sera plus adapté d'envoyer une alerte et d'évaluer le comportement manuellement. Quoi qu'il en soit, la résolution des incidents potentiels doit être automatisée autant que possible pour réduire les temps de réponse et renforcer la sécurité globale des applications conteneurisées.

Le kubelet est l'« agent de nœud » principal qui s'exécute sur chaque nœud. Une erreur de configuration au niveau du kubelet peut entraîner une multitude de risques pour la sécurité. Pour configurer le kubelet, vous pouvez utiliser des arguments dans le fichier exécutable du kubelet en cours d'exécution ou un fichier de configuration dédié.

Exécutez la commande suivante pour accéder au fichier de configuration du kubelet :

ps -ef | grep kubelet | grep config

Cherchez l'argument --config, qui indique l'emplacement du fichier de configuration du kubelet.

Exécutez ensuite cette commande sur chaque nœud :

ps -ef | grep kubelet

Effectuez les vérifications suivantes dans le résultat :

L'argument --anonymous-auth est false. Dans l'article sur le kubelet mentionné précédemment, une erreur de configuration a été utilisée pour autoriser le serveur de kubelet à envoyer des requêtes anonymes (et donc non authentifiées).

S'il existe, l'argument --authorization-mode est défini sur AlwaysAllow. Sinon, assurez-vous qu'un fichier de configuration de kubelet a été spécifié par --config, avec authorization-mode défini sur quelque chose de plus que AlwaysAllow.

S'il existe, l'argument --client-ca-file est défini sur l'emplacement du fichier d'autorité de certification des clients. Sinon, assurez-vous qu'un fichier de configuration de kubelet a été spécifié par --config, avec le paramètre authentication: x509: clientCAFile défini sur l'emplacement du fichier d'autorité de certification des clients.

S'il existe, l'argument --read-only-port est défini sur 0. Sinon, assurez-vous qu'un fichier de configuration de kubelet a été spécifié par --config, avec le paramètre readOnlyPort défini sur 0 (s'il existe dans le fichier).

S'il existe, l'argument --protect-kernel-defaults est true. Sinon, assurez-vous qu'un fichier de configuration de kubelet a été spécifié par --config, avec le paramètre protectKernelDefaults défini sur true.

L'argument --hostname-override n'est pas présent. Ainsi, les communications TLS entre le kubelet et le serveur d'API ne peuvent pas être coupées.

S'il existe, l'argument --event-qps est défini sur 0. Sinon, assurez-vous qu'un fichier de configuration de kubelet a été spécifié par --config, avec le paramètre eventRecordQPS défini sur 0.

Les arguments --tls-cert-file et --tls-private-key-file sont correctement définis. Sinon, dans le fichier de configuration du kubelet spécifié par --config, les paramètres tlsCertFile et tlsPrivateKeyFile sont définis sur les valeurs appropriées. Cette configuration permet de s'assurer que toutes les connexions transiteront via le protocole TLS sur les kubelets.

Les arguments RotateKubeletServerCertificate et --rotate-certificates sont true si les certificats des kubelets proviennent du serveur d'API. Votre kubelet doit utiliser un algorithme de chiffrement fort.

Dans le cadre de la gestion du cluster, le serveur d'API Kubernetes traite les appels d'API REST qui proviennent d'utilisateurs ou d'applications exécutées dans le cluster. Le serveur d'API, qui joue le rôle de passerelle vers le plan de contrôle Kubernetes, est accessible via l'interface en ligne de commande kubectl, des bibliothèques client ou des requêtes d'API directement. Le contrôle d'accès basé sur les rôles de Kubernetes est l'une des solutions qui permettent de gérer les autorisations de ce serveur. Les requêtes au serveur d'API peuvent aussi être validées à l'aide de contrôleurs d'admission.

Le contrôle des accès est le premier mécanisme de protection du serveur d'API. À ce titre, le CIS suggère des meilleures pratiques de configuration pour renforcer davantage la sécurité du serveur d'API.

Exécutez la commande suivante sur le nœud de gestion :

ps -ef | grep kube-apiserver

Effectuez les vérifications suivantes dans le résultat :

L'argument --anonymous-auth est false. Ainsi, les requêtes non rejetées par d'autres méthodes d'authentification ne sont pas considérées comme anonymes. Elles sont donc autorisées, car conformes.

L'argument --basic-auth-file n'existe pas. L'authentification de base utilise des informations d'identification en texte brut à la place de certificats ou de jetons préférés.

L'argument --insecure-allow-any-token n'existe pas. Par conséquent, seuls les jetons sécurisés et authentifiés sont autorisés.

L'argument –kubelet-https n'existe pas ou est true. Les données en transit entre le serveur d'API et les kubelets sont donc protégées via le protocole TLS.

L'argument --insecure-bind-address n'existe pas. Cette configuration empêche le serveur d'API d'être relié à une adresse non sécurisée et bloque ainsi les accès non authentifiés et non chiffrés au nœud de gestion, ce qui limite le risque d'attaques visant les données sensibles en transit.

L'argument --insecure-port est défini sur 0. Ce paramètre empêche le serveur d'API de se connecter sur un port non sécurisé et bloque ainsi les accès non authentifiés et non chiffrés au nœud de gestion, ce qui limite le risque d'attaques visant à prendre le contrôle du cluster.

L'argument --secure-port n'existe pas ou est défini sur un entier compris entre 1 et 65 535. Le but est que tout le trafic soit authentifié, autorisé, puis acheminé via HTTPS.

L'argument --profiling est false. Sauf en cas de goulets d'étranglement ou de problèmes, l'argument d'établissement de profil est superflu, car il expose inutilement les informations sur le système et le programme.

L'argument --repair-malformed-updates est false. Ainsi, le serveur d'API rejette les requêtes de clients dans lesquelles une erreur de mise en forme a été délibérément introduite.

L'argument --enable-admission-plugins est défini sur une valeur qui ne contient pas AlwaysAdmit. Avec la valeur AlwaysAdmit, le serveur accepte les requêtes non explicitement autorisées par le plug-in de contrôle des admissions, ce qui a pour effet de diminuer l'efficacité du plug-in.

L'argument --enable-admission-plugins est défini sur une valeur qui contient AlwaysPullImages. Ainsi, les utilisateurs ne sont pas autorisés à extraire des images depuis le nœud vers un pod simplement en utilisant le nom de l'image. Lorsque ce contrôle est activé, les images sont systématiquement extraites avant le démarrage du conteneur, ce qui nécessite la saisie d'informations d'identification valides.

L'argument --enable-admission-plugins est défini sur une valeur qui contient SecurityContextDeny. Ce contrôle empêche de définir un contexte de sécurité personnalisé non conforme aux politiques de sécurité des pods au niveau du pod.

L'argument --disable-admission-plugins est défini sur une valeur qui ne contient pas NamespaceLifecycle. Ne désactivez pas ce contrôle, car il empêche de créer des objets dans un espace de noms inexistant ou qui doit être supprimé.

L'argument --audit-log-path est défini sur l'emplacement de stockage des journaux d'audit. Il est toujours préférable d'activer les audits pour les composants Kubernetes, si possible, y compris pour le serveur d'API.

L'argument --audit-log-maxage est défini sur 30 ou une autre valeur. Il spécifie le nombre maximal de jours pendant lesquels les journaux d'audit sont stockés, conformément aux politiques internes et externes de conservation des données.

L'argument --audit-log-maxbackup est défini sur 10 ou une autre valeur. Il spécifie le nombre maximal de journaux d'audit à conserver, conformément aux exigences de conformité.

L'argument --audit-log-maxsize est défini sur 100 ou une autre valeur. Il spécifie la taille maximale du journal d'audit, conformément aux exigences de conformité. Le nombre 100 correspond à 100 Mo.

L'argument --authorization-mode existe et n'est pas défini sur AlwaysAllow. Ainsi, le serveur d'API accepte uniquement les requêtes autorisées, en particulier dans les clusters de production.

L'argument --token-auth-file n'existe pas. Lorsqu'il est présent, cet argument utilise l'authentification statique basée sur des jetons, qui présente plusieurs failles de sécurité. Préférez une autre méthode d'authentification, comme les certificats.

L'argument --kubelet-certificate-authority existe. Ce paramètre bloque les attaques dites de l'homme du milieu (ou « man-in-the-middle ») en cas de connexion entre le serveur d'API et le kubelet.

Les arguments --kubelet-client-certificate et --kubelet-client-key existent. Cette configuration oblige le serveur d'API à s'authentifier auprès des points de terminaison HTTPS du kubelet, ce qui n'est pas le cas par défaut.

L'argument --service-account-lookup existe et est true. Ce paramètre évite que le serveur d'API vérifie seulement la validité du jeton d'authentification, sans s'assurer au préalable que le jeton de compte de service indiqué dans la requête figure bien dans la base de données etcd.

L'argument --enable-admission-plugins est défini sur une valeur qui contient PodSecurityPolicy.

L'argument --service-account-key-file existe et est défini sur une paire de clés publique/privée distincte pour la signature des jetons de compte de service. Si vous n'indiquez pas cette paire, la clé privée du certificat TLS sera utilisée, ce qui empêchera la rotation des clés pour les jetons de compte de service.

Les arguments --etcd-certfile et --etcd-keyfile existent. Cela signifie que le serveur d'API s'identifie auprès du serveur etcd à l'aide de la clé et du certificat client. La base etcd contient des objets potentiellement sensibles. Le chiffrement TLS est donc obligatoire pour les connexions aux clients.

L'argument --disable-admission-plugins est défini sur une valeur qui ne contient pas ServiceAccount. Cette configuration empêche d'utiliser un compte de service par défaut dans le même espace de noms lors de la création d'un pod.

Les arguments --tls-cert-file et --tls-private-key-file existent. Grâce à ces paramètres, le serveur d'API n'achemine que le trafic HTTPS via TLS.

L'argument --client-ca-file existe et permet de s'assurer que l'authentification par certificat client et TLS est configurée pour les déploiements de clusters Kubernetes.

L'argument --etcd-cafile existe et est configuré de sorte que le serveur d'API s'autovalide auprès du serveur etcd via le fichier d'autorité de certification SSL.

L'argument --tls-cipher-suites autorise l'utilisation d'algorithmes de chiffrement forts.

L'argument --authorization-mode existe et est défini sur une valeur qui contient Node. Avec cette configuration, les kubelets ont accès en lecture à une liste limitée d'objets associés à leurs nœuds.

L'argument --enable-admission-plugins est défini et contient la valeur NodeRestriction. Ce plug-in autorise un kubelet à modifier uniquement son propre objet d'API de nœud et les objets d'API de pod associés à son nœud.

L'argument --encryption-provider-config est défini sur un fichier EncryptionConfig qui contient toutes les ressources requises. Ainsi, les objets d'API REST stockés dans le magasin de données clé-valeur etcd sont chiffrés au repos.

Veillez à utiliser le fournisseur de chiffrement aescbc (le plus fiable actuellement disponible sur le marché) pour toutes les ressources souhaitées.

L'argument --enable-admission-plugins contient la valeur EventRateLimit, qui permet de limiter le nombre d'événements acceptés par le serveur d'API afin d'optimiser les performances du cluster.

La valeur de l'argument --feature-gates ne contient pas AdvancedAuditing=false. En d'autres termes, vérifiez que les options d'audits avancés ne sont pas désactivées pour les processus d'audit et d'analyse.

L'argument --request-timeout n'existe pas ou est défini sur une valeur appropriée (ni trop longue, ni trop courte). La valeur par défaut est 60 secondes.

L'argument --authorization-mode existe et est défini sur une valeur qui contient RBAC.

Ce paramètre permet d'activer le contrôle d'accès basé sur les rôles de Kubernetes. Néanmoins, pour utiliser au mieux cette fonction, vous devez également respecter les recommandations suivantes :

  • Évitez d'attribuer aux utilisateurs le rôle d'administrateur du cluster (cluster-admin), car il confère des pouvoirs très étendus sur l'environnement. Vous l'utiliserez donc avec parcimonie, voire pas du tout.
  • Vérifiez que vous utilisez comme il se doit les règles liées à l'agrégation des rôles.
  • N'accordez pas deux fois la même permission à un sujet, car cela risque de compliquer davantage la révocation des accès.
  • Supprimez régulièrement les rôles superflus.

Défi de la sécurité lié aux paramètres par défaut

L'un des risques majeurs avec les conteneurs et Kubernetes est que leur configuration par défaut n'est jamais sûre. Pour limiter le risque d'incidents, il faut modifier ces configurations de manière proactive et cohérente, dans toute l'entreprise. Si vous ne le faites pas, que ce soit par négligence, par méconnaissance ou en oubliant d'inclure la gestion des configurations dans les workflows, vous rendrez les charges de travail inutilement vulnérables.

 

Paramètres par défaut des conteneurs

La plupart des paramètres par défaut et les techniques de création courantes fragilisent les conteneurs. Voici donc quelques précautions à prendre pour configurer vos conteneurs.

  • Définissez un utilisateur. Sinon, l'utilisateur root est défini par défaut et le conteneur risque de disposer d'un accès root à l'hôte.
  • Vérifiez les images. La vérification des images n'est pas activée par défaut. Par conséquent, des images dont l'intégrité a été compromise peuvent être extraites sans laisser de traces.
  • Limitez les ressources. Ce n'est pas le cas par défaut. La limitation des ressources en processeur et en mémoire empêche le conteneur d'utiliser une grande quantité de ressources en cas de piratage.
  • Installez vos outils et bibliothèques de façon sélective. En supposant qu'une personne malveillante parvienne à accéder au conteneur, elle pourra détourner moins d'outils et de bibliothèques si vous limitez leur nombre. N'installez que le strict nécessaire dans chaque conteneur, plutôt que l'ensemble d'outils standard.
  • Contrôlez l'accès au registre en utilisant une liste. L'utilisation d'images issues de sources fiables ne suffit pas. Il est aussi important de contrôler avec précision l'accès au registre, idéalement à l'aide d'une liste d'utilisateurs de confiance.

Paramètres par défaut de Kubernetes

Kubernetes propose de nombreux outils afin d'améliorer la posture de sécurité de l'entreprise. Pour en tirer pleinement parti, il convient cependant de les configurer de manière adéquate. Voici les principales vérifications à effectuer dans Kubernetes.

  • Configurez le contrôle d'accès basé sur les rôles. Activée par défaut dans Kubernetes 1.6 et versions ultérieures, cette fonction doit être configurée correctement pour être bénéfique. L'idéal est d'accorder l'accès au niveau de l'espace de noms et non du cluster.
  • Utilisez des espaces de noms. Par défaut, tous les objets sont exécutés dans le même espace de noms. Servez-vous des espaces de noms pour isoler les charges de travail.
  • Utilisez les politiques réseau de Kubernetes. Les politiques réseau ne sont pas préconfigurées. C'est à l'entreprise d'installer un plug-in réseau pour contrôler le trafic entrant et sortant au niveau de l'application et de définir des politiques adaptées.
  • Activez la journalisation des audits. En général, elle est désactivée par défaut, mais il est conseillé de l'activer pour bénéficier d'une meilleure visibilité sur les appels d'API anormaux et les échecs d'autorisation.

Risques de l'inaction

En général, les équipes de développement sont les premières à utiliser les conteneurs et Kubernetes bien qu'elles disposent d'une expertise limitée en matière de sécurité. Or, en ignorant la sécurité, les entreprises s'exposent à des risques, et ce, quelle que soit leur infrastructure.

Il est important de le répéter : les configurations par défaut des conteneurs et de Kubernetes ne sont pas sûres. Pour être efficaces, les fonctionnalités de sécurité natives de Kubernetes doivent être correctement configurées. Une application peut être distribuée facilement et rapidement si on lui accorde beaucoup de privilèges et/ou si on l'autorise à consommer bien plus de ressources que nécessaire, voire si on conserve les paramètres par défaut. Au départ, les entreprises peuvent être tentées de négliger la sécurité, surtout lorsqu'elles se familiarisent avec les conteneurs et Kubernetes. Cette attitude les expose pourtant à un risque majeur. Une personne malveillante arrivera à attaquer une application conteneurisée sur Kubernetes tout aussi facilement qu'une application traditionnelle.

Le principal risque de l'inaction est que des personnes malveillantes compromettent l'intégrité de l'application. Ce risque peut être plus ou moins catastrophique selon le secteur d'activité de l'entreprise, le type d'application ainsi que la nature et l'ampleur de la faille. Un certain nombre de facteurs, comme la mise à disposition de l'application sur le Web, conditionnent aussi la probabilité de survenue d'un incident en raison d'un manque de sécurité.

Ne rien faire pour sécuriser vos applications conteneurisées, c'est courir le risque de les rendre inutilement vulnérables. Voici les dangers auxquels vous vous exposez en faisant l'impasse sur la sécurité.

Vulnérabilités de sécurité non corrigées : la liste des vulnérabilités ne cesse de s'allonger et certaines ont déjà fait de sérieux dégâts. Ces vulnérabilités n'échappent pas à la communauté Open Source, pas plus qu'aux personnes mal intentionnées, malheureusement. L'absence de correction représente un risque.

Permissions souples : le contrôle d'accès basé sur les rôles est certes activé par défaut dans Kubernetes, mais sa mise en œuvre incombe à l'équipe de développement. Si cette dernière ne reçoit pas de conseils sur la sécurité, elle aura tendance à accorder un accès trop étendu aux charges de travail.

Charges de travail non isolées : par défaut, tous les objets peuvent s'exécuter dans un seul et même espace de noms préconfiguré. Une mesure de sécurité de base consiste à isoler les charges de travail dans différents espaces de noms. Cette étape nécessite une attention toute particulière pour bien isoler les charges de travail.

Politiques réseau non contrôlées : les politiques réseau de Kubernetes permettent à l'entreprise de contrôler le trafic, à condition d'être correctement configurées et accompagnées d'un plug-in réseau.

À terme, l'application tardive des contrôles aboutit à des pratiques de sécurité hétérogènes, qui freinent le développement et augmentent le risque d'incidents. Par conséquent, il est préférable pour les entreprises de mettre en place ces contrôles plus tôt et tout au long du cycle de vie du logiciel.

Kubernetes, le système de choix pour l'orchestration des conteneurs, facilite la gestion des conteneurs, mais introduit également des vulnérabilités potentielles dans les environnements d'infrastructure. Les disparités qui concernent la sécurité des conteneurs et de Kubernetes par rapport à celle des machines virtuelles et le déficit de compétences persistant dans le domaine de la sécurité de Kubernetes génèrent des risques inutiles.

Les meilleures pratiques de sécurité appliquées à Kubernetes, comme toutes les meilleures pratiques en matière de sécurité, s'articulent autour de deux axes : renforcer la sécurité des applications et de l'infrastructure, et centraliser la gestion de la sécurité en agissant au niveau organisationnel et culturel.

Définir et appliquer des politiques de sécurité à l'échelle de l'entreprise : cette meilleure pratique est valable pour tous types de piles technologiques. La sécurité consiste à gérer les risques. On ne peut pas se fier à des outils pour évaluer le niveau de risque que chaque application peut accepter, par exemple. Ce genre de décisions doivent être prises par des équipes qui pourront considérer le niveau de risque acceptable pour l'ensemble de l'entreprise, pour ses différentes divisions et pour chaque application.

Centraliser le contrôle de la sécurité : cette meilleure pratique est liée à la première. Une fois les politiques de sécurité et de gouvernance définies, l'entreprise doit s'assurer qu'elles sont suivies. Il est important que les équipes centrales aient une bonne visibilité sur les configurations et les vulnérabilités de toute l'application distribuée, et qu'elles puissent visualiser et hiérarchiser les problèmes potentiels. Elles doivent aussi pouvoir poser des garde-fous pour faire remonter immédiatement les problèmes détectés dans une version, comme une configuration risquée, une image non sécurisée ou tout autre risque pour la sécurité.

Intégrer la sécurité plus tôt : la mise en œuvre de la sécurité plus tôt dans le processus de développement permet d'alléger les révisions de sécurité et accélère la distribution des applications, mais pas seulement. Cette pratique diminue aussi le risque qu'une vulnérabilité ou une erreur de configuration soit exploitée.

Automatiser : lorsque l'environnement Kubernetes contient plusieurs clusters et des centaines d'espaces de noms, il devient impossible de gérer les configurations ou de surveiller manuellement l'exécution.

Les pratiques techniques ci-dessous sont également très importantes pour optimiser la sécurité de Kubernetes :

  • Maintenir Kubernetes à jour : il n'existe pas toujours de correctifs de sécurité pour les anciennes versions, c'est pourquoi il vaut mieux exécuter une version plus récente et prise en charge.
  • Utiliser le contrôle d'accès basé sur les rôles : le principe du moindre privilège doit s'appliquer pour les accès.
  • Limiter les communications entre les pods : fixez des limites très restrictives pour que les pods fonctionnent comme prévu.
  • Segmenter le réseau : chaque pod doit communiquer seulement avec les ressources internes ou externes dont il a besoin et doit être isolé des autres ressources.

La gestion des vulnérabilités, composant essentiel de la sécurité des applications, consiste à identifier, évaluer et corriger les vulnérabilités à toutes les étapes du cycle de développement de logiciels. Dans le contexte des applications conteneurisées cloud-native, ce processus doit être automatisé et intégré aux activités DevOps de création et de distribution. En effet, il est impossible de gérer manuellement les vulnérabilités dans un environnement trop complexe. D'ailleurs, dans la réalité, si le développement est trop ralenti, les entreprises risquent de ne pas mettre en place de mesures de sécurité.

La gestion des vulnérabilités n'est pas une action ponctuelle, mais un processus continu qui commence par un travail d'analyse des images et d'introspection lors de la phase de création et se poursuit tout au long du cycle de vie de l'application, dans les environnements de test et de production.

L'analyse des images et l'application de politiques liées aux vulnérabilités de ces images lors de la phase de création posent les premiers jalons d'une gestion efficace des vulnérabilités natives pour les conteneurs. Pour détecter les vulnérabilités potentiellement révélées en cours d'exécution, il est important de réaliser ces analyses à la demande, au moment de la création des images ou de l'exécution des conteneurs. Cette exposition doit pouvoir être identifiée à la fois dans les conteneurs et dans Kubernetes, car le risque de vulnérabilité existe dans ces deux environnements.

Une application n'est jamais totalement sûre. C'est pourquoi la gestion efficace des vulnérabilités fournit non seulement une visibilité sur les vulnérabilités, mais également des informations pour aider à les catégoriser selon leur degré de gravité pour l'entreprise. En effet, une CVE de priorité élevée ne présente pas le même profil de risques en fonction du niveau de sensibilité de la charge de travail. En matière de gestion des vulnérabilités, il est important de trouver un équilibre, d'évaluer et de donner la priorité aux corrections qui pourront optimiser la posture de sécurité.

La gestion des vulnérabilités doit d'abord être automatisée dans les applications cloud-native. L'intelligence de l'homme est indispensable pour définir les politiques, mais les outils doivent permettre d'identifier les manquements et d'appliquer des mesures adaptées selon la vulnérabilité, le niveau de risque et l'étape concernée dans le cycle de vie. De l'arrêt automatique de la création au blocage des déploiements, en passant par la mise à l'échelle à zéro en production, le panel des mesures est vaste.

L'analyse des images et des vulnérabilités doit démarrer lors de la phase de création et se poursuivre tout au long du cycle de vie de l'application, y compris dans l'environnement d'exécution. De nouvelles vulnérabilités de sécurité peuvent apparaître à tout moment. Par conséquent, il est essentiel de les détecter dans les déploiements en cours d'exécution, car elles peuvent directement menacer la sécurité de l'entreprise. L'objectif consiste donc à détecter et corriger au plus vite les vulnérabilités.

Les images non conformes, notamment celles qui présentent des vulnérabilités graves et corrigibles, ne devraient pas passer l'étape de création. Et cette information devrait être remontée aux équipes DevOps directement dans le système CI. Lors du déploiement, les outils de sécurité peuvent appliquer le contrôle d'admission pour bloquer automatiquement le déploiement des conteneurs dont l'image contient des vulnérabilités connues. Il est crucial de savoir hiérarchiser les mesures correctives en fonction de la gravité de la vulnérabilité, du degré de sensibilité de la charge de travail et du niveau de risque acceptable par l'entreprise. Cette dernière doit prendre le temps de définir des politiques personnalisées et de mettre en œuvre des outils pour les appliquer automatiquement, au moment de la création et du déploiement de l'application. Ensuite, une fois que l'exécution des déploiements a démarré, elle doit continuer à rechercher les vulnérabilités.

 

Les analyseurs d'images n'offrent pas tous les mêmes fonctionnalités

Analyse des bibliothèques, du langage de programmation, du contenu des fichiers, du système d'exploitation uniquement, etc. Les analyseurs d'images ne proposent pas tous le même niveau de vérification. Choisissez un outil suffisamment complet pour répondre aux besoins de votre entreprise et qui soit compatible avec les langages de programmation de vos applications.

Certains analyseurs d'images analysent en temps réel chaque extraction d'image, ce qui augmente malheureusement la latence. C'est à vous de voir si cette perte de performance en vaut la peine.

 

Lancer des analyses en cours d'exécution

Les mesures à prendre dépendent de la vulnérabilité détectée, comme avec l'analyse des images lors de la création. Les entreprises doivent en effet hiérarchiser les mesures correctives selon le degré de sensibilité des charges de travail et des données, le niveau d'exposition sur Internet et la gravité des vulnérabilités détectées. Or, aucune ne se base sur les mêmes procédures ou objectifs de niveau de service pour identifier la réponse adaptée. Il y a toujours des compromis à faire, par exemple en bloquant tous les conteneurs qui présentent des vulnérabilités, peu importe leur niveau de gravité ou de sensibilité. L'analyse des vulnérabilités dans les déploiements en cours d'exécution exige à la fois des outils adaptés qui apportent de la visibilité et fournissent des informations, et des politiques de sécurité réfléchies à l'échelle de l'entreprise qui permettent d'établir un juste équilibre entre gestion des vulnérabilités et répercussions sur l'exploitation.

Les réseaux d'entreprise se sont complexifiés, au même titre que leurs applications distribuées. Et les modèles de menace et méthodes d'infiltration ont suivi le mouvement. La sécurisation des périmètres, la première ligne de défense des réseaux internes, n'offrira jamais une stratégie complète de protection de l'infrastructure et des données. Pour déployer une approche de sécurité robuste, il est nécessaire de combiner contrôles et stratégies.

Le réseau à vérification systématique vise à protéger davantage le trafic interne lié aux applications ; il représente donc un élément clé de la sécurité. Ce modèle déconstruit l'idée bien ancrée selon laquelle tout le trafic d'un réseau protégé par des pare-feu est authentique, et part du principe opposé, à savoir qu'aucune connexion réseau n'est digne de confiance jusqu'à preuve du contraire.

Jusqu'à maintenant, les administrateurs réseau considéraient que chaque entité des réseaux internes (les applications, serveurs, ou logiciels/matériels de mise en réseau) existait de façon légitime et était digne de confiance. L'authentification des connexions client n'était pas systématique et les applications utilisaient parfois des informations d'identification statiques et partagées, par exemple un mot de passe pour une base de données. Quand des schémas d'authentification ou d'autorisation étaient mis en place, leur gestion revenait aux applications elles-mêmes. Enfin, le chiffrement des connexions réseau internes, y compris pour les services sensibles, n'était pas généralisé.

Beaucoup de réseaux d'entreprise reposent encore sur ce modèle. Pourtant, dans un environnement si laxiste, une personne malveillante peut causer de gros dégâts en profitant de cette confiance implicite et en s'introduisant dans le réseau, que ce soit par une attaque directe, un cheval de Troie installé accidentellement par un utilisateur autorisé ou une simple faille dans un pare-feu. Si les possibilités sont sans doute limitées, elles sont aussi prévisibles. De l'aspiration des paquets réseau qui contiennent des informations en texte brut à l'identification des mots de passe utilisés pour accéder aux bases de données ou à d'autres systèmes critiques en passant par la prise de contrôle des équipements du réseau, les entreprises s'exposent à des risques inacceptables, notamment le vol ou la perte de données.

La vérification systématique est à la base d'un nombre croissant d'infrastructures de production orientées sécurité. Au lieu de partir du principe que chaque entité d'un réseau est digne de confiance et n'a pas besoin d'être vérifiée, on considère au contraire qu'aucune entité n'est fiable, pas même l'infrastructure du réseau. Le modèle à vérification systématique n'impose pas de mise en œuvre normative ou de pile technologique spécifique. Il décrit un ensemble de principes et d'objectifs, en laissant chaque entreprise choisir ensuite sa propre configuration technique.

Architectures à vérification systématique

La plupart des architectures à vérification systématique se basent sur les principes suivants :

  • Les contrôles de sécurité doivent s'appliquer de façon uniforme à toutes les entités logicielles et matérielles, dans l'ensemble du réseau.
  • L'authentification des connexions réseau doit être activée pour le trafic entrant et sortant, par le serveur et le client. En général, on s'attend à ce que le serveur authentifie les clients, mais les clients doivent eux aussi s'assurer qu'ils se connectent à un serveur valide. Les connexions sont donc authentifiées deux fois. En outre, dès lors qu'une requête couvre plusieurs transactions, elle doit à nouveau être autorisée.
  • Le principe du moindre privilège doit s'appliquer pour les autorisations, afin de limiter au strict minimum les permissions requises pour la charge de travail du client.
  • Enfin, toutes les connexions réseau et les transactions doivent faire l'objet d'une surveillance continue à des fins d'analyse.

Mettre en place un modèle à vérification systématique dans Kubernetes

Dans un cluster Kubernetes, l'application des principes de vérification systématique ne correspond à aucune méthode universelle. Cependant, le Service Mesh est désormais une solution courante qui permet de couvrir la plupart des besoins de ce type d'architecture.

Le Service Mesh ajoute une couche de réseau virtuel pour la connexion et le contrôle des services d'applications distribués. À l'origine, les solutions de Service Mesh n'étaient pas axées sur la sécurité du réseau, mais sur la gestion et la simplification de la découverte intelligente des services et du routage des requêtes. Désormais, les projets Open Source largement répandus incluent des fonctions compatibles avec une architecture à vérification systématique. Bon nombre de fournisseurs de Service Mesh essaient d'ajouter une couche en superposition sans modifier chaque application, ce qui évite d'importants changements pour activer des contrôles stricts d'autorisation et d'authentification.

Les Service Mesh compatibles avec Kubernetes utilisent généralement le routage point à point et décentralisé, et affectent un proxy différent à chaque pod du cluster. Le proxy gère les certificats TLS des clients, ce qui lui permet de prouver son identité lorsqu'il se connecte à d'autres services ou que d'autres clients souhaitent s'y connecter. Ce protocole qui consiste à utiliser des certificats TLS comme preuve d'identité côté client et côté serveur s'appelle mTLS (mutual Transport Layer Security). Il est employé pour l'authentification des connexions et pour le chiffrement des connexions réseau. En plus de l'authentification et du chiffrement de site à site, certains Service Mesh prennent en charge une variété de sources d'autorisation (listes statiques, intégrations à des systèmes tiers d'authentification unique et unifiée ou d'autres services).

Le Service Mesh ne propose pas de solution complète pour la vérification systématique des clusters Kubernetes, mais il offre certains avantages clés liés à ce modèle. Même si l'architecture à vérification systématique de vos clusters Kubernetes n'est pas parfaite, chaque petit changement dans ce sens permettra de renforcer leur sécurité et celle des charges de travail.

La sécurisation des applications cloud-native et de l'infrastructure sous-jacente nécessite des changements importants dans l'approche de la sécurité d'une entreprise. Celle-ci doit effectuer des contrôles plus tôt dans le cycle de développement des applications, utiliser des contrôles intégrés pour appliquer les politiques qui préviennent les problèmes opérationnels et d'évolutivité, et rester en phase avec les calendriers de lancement toujours plus serrés.

Plateforme de sécurisation native pour Kubernetes, Red Hat® Advanced Cluster Security for Kubernetes permet aux entreprises de créer, de déployer et d'exécuter des applications cloud-native dans tous les environnements de manière plus sécurisée, et d'innover plus rapidement en toute confiance. Elle contribue à l'amélioration de la sécurité pendant la phase de création des applications, à la protection de la plateforme et des configurations d'applications, et à la détection des problèmes d'exécution ainsi qu'à leur résolution.

Pour aller plus loin

ARTICLE

Conteneurs et machines virtuelles

Les conteneurs Linux et les machines virtuelles sont des environnements informatiques en paquets qui associent divers composants et les isolent du reste du système.

ARTICLE

L'orchestration des conteneurs, qu'est-ce que c'est ?

L'orchestration des conteneurs permet d'automatiser le déploiement, la gestion, la mise à l'échelle et la mise en réseau des conteneurs.

ARTICLE

Un conteneur Linux, qu'est-ce que c'est ?

Un conteneur Linux est un ensemble de processus isolés du système. Un conteneur s'exécute à partir d'une image distincte qui fournit tous les fichiers nécessaires à la prise en charge des processus qu'il contient.

En savoir plus sur les conteneurs

Produits

Une plateforme d'applications d'entreprise comprenant un ensemble unifié de services testés conçus pour distribuer des applications sur votre choix d'infrastructure.

Ressources

Formations

Cours gratuit

Présentation technique de l'exécution de conteneurs avec Red Hat

Cours gratuit

Présentation technique du déploiement d'applications conteneurisées

Cours gratuit

Développement d'applications cloud-native avec des architectures de microservices