Sysdig
Learn Cloud Native

Sign up to receive our newsletter

Sécurité du cluster Kubernetes : composant par composant

Si Kubernetes n’a plus de secret pour vous, vous savez qu’il ne s’agit pas d’un outil unique, mais d’une multitude de types de services et de ressources distincts, tels qu’un serveur API, des agents de nœuds, des moteurs d’exécution de containers, etc.

Chaque composant d’un cluster Kubernetes est confronté à des types de menaces de sécurité différentes et nécessite des configurations de sécurité différentes. Dans certains cas, vous pouvez appliquer la même technique de sécurité à plusieurs composants. Par exemple, vous pouvez utiliser le contrôle d’accès basé sur les rôles pour gérer les autorisations pour divers types de ressources dans Kubernetes.

Pourtant, certains composants ont des exigences de sécurité uniques et nécessitent des solutions de sécurité uniques. La sécurisation du serveur API est différente de la sécurisation des nœuds, par exemple. La sécurité des clusters Kubernetes consiste à comprendre et à traiter les menaces de sécurité possibles pour chaque composant.

Avec cette réalité à l’esprit, voici comment sécuriser un cluster Kubernetes en sécurisant chacun de ses différents composants.

Comment sécuriser un cluster Kubernetes

  1. Sécuriser le serveur API Kubernetes

Le serveur API Kubernetes, kube-apiserver, est le centre névralgique de votre cluster Kubernetes. Le serveur API est ce qui accorde les demandes d’accès, maintient les workloads en fonctionnement, etc.

L’outil principal pour sécuriser le serveur API dans Kubernetes est le framework Kubernetes Role-Based Access Control, ou RBAC. Avec les politiques RBAC, vous pouvez définir des utilisateurs et des comptes de service, puis leur attribuer des autorisations qui leur permettent d’effectuer certaines actions en utilisant l’API Kubernetes.

Par exemple, vous pouvez créer un rôle RBAC qui permet à une ressource d’obtenir, de surveiller et de lister les pods dans le namespace Kubernetes par défaut. Le rôle ressemblerait à ceci :

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
Vous devez ensuite associer le rôle à un utilisateur ou à un groupe de services dans Kubernetes en créant un RoleBinding ou un ClusterRoleBinding avec une commande telle que la suivante :
kubectl create rolebinding podreader-binding --user=john

Ce RoleBinding donne à l’utilisateur « jean » les permissions d’obtenir, de regarder et de lister les pods qui sont définis dans le Rôle ci-dessus.

Contrôleurs d’admission et sécurité de l’API Kubernetes

Vous pouvez fournir une deuxième couche de défense pour l’API Kubernetes – et, par extension, pour l’ensemble de votre cluster Kubernetes – avec des contrôleurs d’admission. En substance, un contrôleur d’admission est un code qui intercepte les requêtes adressées à l’API Kubernetes après que l’API a déjà authentifié et autorisé une requête, mais avant que l’API ne finisse de répondre à celle-ci.

Vous pouvez utiliser les contrôleurs d’admission pour limiter le volume de ressources qu’un objet peut demander à l’API, par exemple, ou empêcher l’exécution de certaines commandes même si les politiques RBAC et les contextes de sécurité les autorisent.

Utilisation des journaux d’audit pour renforcer la sécurité

Une troisième ressource de sécurité permettant de prévenir les problèmes de sécurité liés à l’API Kubernetes est la journalisation des audits. La journalisation d’audit est une fonctionnalité facultative de Kubernetes qui vous permet d’enregistrer et de suivre les requêtes à mesure que le serveur API les traite.

En créant des journaux d’audit et en les analysant en permanence à l’aide d’un outil comme Falco, vous recevrez des alertes automatiques lorsqu’un utilisateur ou un service effectue des requêtes suspectes, par exemple en essayant de manière répétée d’accéder à des ressources auxquelles l’utilisateur ou le service n’est pas autorisé à accéder.

  1. Sécuriser et sauvegarder etcd 

Par défaut, Kubernetes utilise etcd, un magasin de clés et valeurs, qui stocke toutes les données de configuration de votre cluster.

Kubernetes n’offre pas d’outil natif pour sécuriser etcd, mais vous devez vous assurer que vous activez la sécurité du transport. Reportez-vous à la documentation d’etcd pour plus de détails.

En tant que meilleure pratique de sécurité du cluster, vous devriez également vous assurer que vous sauvegardez etcd en utilisant la commande etcdctl snapshot save. Même si vous exécutez Kubernetes dans un endroit où vous avez une grande confiance dans la fiabilité d’etcd, les sauvegardes d’etcd vous protègent contre les rançongiciels ou d’autres attaques où quelqu’un pourrait essayer de désactiver votre accès aux données de configuration critiques stockées dans etcd.

Enfin, une bonne pratique lorsque vous travaillez avec etcd est d’éviter de stocker des données secrètes sensibles, comme les mots de passe et les clés d’accès, dans etcd. La plupart des distributions Kubernetes stockent les secrets dans etcd par défaut, mais vous devriez plutôt utiliser un gestionnaire de secrets externe.

  1. Protéger le(s) nœud(s) master 

Un nœud master Kubernetes est le nœud qui héberge le serveur d’API, le planificateur, le contrôleur et etcd de Kubernetes – en d’autres termes, tous les services essentiels qui relient et gèrent un cluster Kubernetes. Certains clusters Kubernetes peuvent exécuter plusieurs nœuds master afin d’augmenter la disponibilité du cluster, auquel cas chaque master exécute des instances redondantes des services Kubernetes de base.

Étant donné le rôle central que jouent les nœuds master dans le cluster, la sécurisation des nœuds master est essentielle à la sécurité globale du cluster. Il existe plusieurs bonnes pratiques à suivre afin de protéger les nœuds master :

  • Provisionner des nœuds master avec des distributions Linux minimalistes, telles que Alpine Linux. Éviter d’installer des applications ou des bibliothèques supplémentaires sur le nœud, sauf si elles sont strictement nécessaires. 
  • Utiliser les politiques RBAC pour restreindre les actions qui peuvent être effectuées sur les nœuds. Moins les cybercriminels ont accès à vos nœuds et disposent d’informations à leur sujet, plus les nœuds sont sécurisés.
  • Utiliser des frameworks de durcissement de sécurité comme SELinux, AppArmor et seccomp pour restreindre les contrôles d’accès au niveau du noyau sur le master. Ces frameworks contribueront à empêcher l’escalade d’un événement de sécurité en rendant plus difficile l’accès d’un processus malveillant aux ressources du noyau ou l’interférence avec d’autres processus.
  • Surveiller en permanence les fichiers journaux des nœuds pour détecter les signes d’activité suspecte.
  1. Sécuriser les nœuds worker et limiter les autorisations des Kubelets et des Kube-Proxy

La principale fonction des nœuds worker est d’héberger des containers ou des pods en cours d’exécution. Chaque nœud worker communique avec le reste du cluster via kubelet, un agent qui s’exécute localement sur chaque nœud worker. Les nœuds worker utilisent également un service appelé kube-proxy pour gérer les communications réseau pour les pods qui sont hébergés sur les nœuds worker.

Par nature, les nœuds worker de Kubernetes sont remplaçables. Si un nœud tombe en panne, Kubernetes réaffecte automatiquement les pods de ce nœud à d’autres nœuds. En ce sens, la sécurisation des nœuds worker est moins critique que celle des nœuds master, car la défaillance de quelques nœuds worker due à des problèmes de sécurité ne constitue pas une menace critique pour l’ensemble de votre cluster.

Néanmoins, un cybercriminel qui parvient à compromettre un nœud worker peut potentiellement accéder à tous les pods hébergés sur ces nœuds. C’est pourquoi il est important de prendre des mesures pour sécuriser les nœuds worker dans le cadre du processus global de sécurité de votre cluster.

Toutes les meilleures pratiques pour sécuriser les nœuds master, que nous avons abordées ci-dessus, s’appliquent également aux nœuds worker. En outre, envisagez de restreindre les autorisations accordées à kubelet et kube-proxy afin de réduire les dommages potentiels qu’un cybercriminel pourrait causer s’il parvient à sortir d’un container et à pénétrer dans le nœud worker qui héberge le container.

  1. Analyser en continu les images des containers

Les images de containers, qui définissent les ressources nécessaires à l’exécution des containers, ne font pas partie de Kubernetes à proprement parler, mais elles constituent un élément essentiel de la plupart des clusters Kubernetes et ne doivent pas être négligées lors de la sécurisation du cluster.

La clé pour sécuriser les images des containers est de les analyser en permanence. En outre, vous pouvez réduire les problèmes de sécurité associés aux containers de plusieurs façons :

  • N’utiliser que des images provenant de sources fiables. Ne pas être tenté de récupérer des images d’un registre aléatoire juste parce que c’est pratique.
  • Éviter d’utiliser la balise « latest » (le plus récent) lors d’une recherche de containers. Spécifiez plutôt une version, ce qui vous permet de savoir exactement quelle version du container vous exécutez et quelles vulnérabilités de sécurité peuvent l’affecter.
  • Adopter une approche minimaliste de la conception des images de containers. Au lieu d’essayer de regrouper plusieurs ressources dans une seule image, créez des images différentes pour chaque fonctionnalité que vous devez mettre en œuvre.
  1. Sécurité du moteur d’exécution des containers

Le moteur d’exécution du container est le service qui exécute réellement les containers. Kubernetes prend en charge une multitude de moteurs d’exécution. Les différences entre les moteurs d’exécution ne sont généralement pas importantes pour la plupart des cas d’utilisation actuels, car la plupart des moteurs d’exécution sont capables d’exécuter la plupart des containers.

Une faille de sécurité dans le logiciel du moteur d’exécution du container peut permettre aux cybercriminels de réaliser un certain nombre d’exploits. Par exemple, en 2019, les développeurs ont découvert une vulnérabilité majeure dans le moteur d’exécution Docker qui permettait effectivement aux containers d’obtenir un accès de niveau root à l’ensemble de l’hôte.

Kubernetes lui-même ne fait rien pour surveiller les vulnérabilités du moteur d’exécution de container ou pour vous alerter des violations qui pourraient résulter de ces vulnérabilités. Vous devez donc vous appuyer sur des outils externes pour sécuriser les moteurs d’exécution, notamment :

  • Des frameworks de durcissement de la sécurité, comme SELinux et AppArmor, que vous pouvez utiliser pour limiter les actions qu’un container malveillant peut effectuer. Lorsqu’ils sont correctement configurés, ces frameworks fournissent une deuxième couche de défense dans le cas où un cybercriminel exploite une vulnérabilité de sécurité du moteur d’exécution du container pour effectuer des actions qui ne devraient pas être autorisées.
  • Les outils d’audit, comme Falco, peuvent surveiller en permanence les journaux d’audit et les autres flux de données de votre environnement de moteur d’exécution de containers et vous alerter lorsqu’ils détectent un comportement qui pourrait être le signe d’une violation. Bien que les outils d’audit puissent détecter une variété de menaces de sécurité en plus de celles associées aux moteurs d’exécution de containers, ils constituent un moyen principal d’identifier les brèches qui proviennent d’une vulnérabilité au niveau du moteur d’exécution.
  • Sauf en cas de nécessité absolue, utilisez les contextes de sécurité Kubernetes pour empêcher les containers de s’exécuter en mode privilégié et pour restreindre les ressources auxquelles ils peuvent accéder. Si les contextes de sécurité n’empêchent pas directement les vulnérabilités du moteur d’exécution des containers, ils constituent une couche de défense supplémentaire qui peut atténuer l’impact d’une violation du moteur.

Une approche holistique de la sécurité des clusters Kubernetes

Ce serait bien s’il existait « une seule et unique astuce » permettant de sécuriser tous les composants de Kubernetes ad vitam aeternam. Mais ce n’est pas le cas. La sécurité de Kubernetes est aussi complexe que l’architecture de Kubernetes elle-même. Si certaines pratiques au niveau du cluster, comme l’audit et la surveillance, peuvent offrir une protection étendue contre certains types de menaces, vous devez également déployer des ressources de sécurité capables de protéger les différents composants individuels qui forment un cluster Kubernetes, du serveur API aux nœuds worker et master, en passant par etcd et au-delà.

Controller di ammissione e sicurezza dell’API di Kubernetes

È inoltre possibile creare un secondo livello di difesa per l’API di Kubernetes (e, per estensione, per l’interno cluster) utilizzando i controller di ammissione. In pratica, i controller di ammissione sono codici che intercettano le richieste indirizzate all’API di Kubernetes dopo che l’API le ha già autenticate e autorizzate ma prima che vengano applicate.

È possibile utilizzare i controller di ammissione, ad esempio, per limitare il volume delle risorse che un oggetto può richiedere dall’API, oppure per impedire l’esecuzione di alcuni comandi anche quando le policy RBAC e i contesti di protezione le consentono.

Utilizzare i registri di controllo per migliorare la sicurezza

Una terza risorsa che aiuta a prevenire i problemi di sicurezza legati all’API di Kubernetes è rappresentata dai registri di controllo. I registri di controllo sono una funzione opzionale di Kubernetes che consente di registrare e tenere traccia delle richieste mentre il server API le elabora.

Creando registri di controllo e analizzandoli continuamente con uno strumento come Falco, si ricevono avvisi automatici quando un utente o un servizio effettuano richieste sospette, ad esempio quando cercano ripetutamente di accedere a risorse a cui non sono autorizzati ad accedere.

Protezione e backup di etcd 

Per impostazione predefinita, Kubernetes utilizza etcd, un archivio di valori chiave, per archiviare tutti i dati relativi alle configurazioni del cluster.

Kubernetes non offre alcuno strumento nativo per proteggere etcd, ma è necessario abilitare la sicurezza del trasporto. Consultare la documentazione etcd per maggiori dettagli.

Come migliore prassi per la sicurezza del cluster, bisogna inoltre effettuare il backup di etcd utilizzando il comando etcdctl snapshot save. Anche se Kubernetes viene eseguito in ambienti nei quali la sicurezza di etcd è praticamente garantita, i backup proteggono dal ransomware o da altri attacchi che cercano di impedire l’accesso ai dati di configurazione critici archiviati in etcd.

Infine, quando si lavora con etcd, è consigliabile evitare di archiviare in esso dati segreti o sensibili come password e chiavi d’accesso. Molte distribuzioni di Kubernetes archiviano informazioni segrete su etcd per impostazione predefinita, ma bisognerebbe piuttosto utilizzare un sistema di gestione esterno.

Proteggere il nodo master 

In Kubernetes, un nodo master è il nodo che ospita il server API, il pianificatore, il controller ed etcd, ovvero tutti i servizi fondamentali che tengono insieme e gestiscono un cluster di Kubernetes. Alcuni cluster di Kubernetes possono eseguire più nodi master per aumentare la loro disponibilità, nel qual caso ciascuno dei nodi eseguirà istanze ridondanti dei principali servizi di Kubernetes.

Dato il ruolo centrale dei nodi master nel cluster, la loro protezione è vitale per la sicurezza generale del cluster. Diverse sono le migliori prassi da seguire per proteggere i nodi master:

  • Dotare i nodi di distribuzioni minimaliste di Linux, ad esempio Alpine Linux. Evitare di installare applicazioni o librerie extra sul nodo a meno che non siano strettamente necessarie. 
  • Utilizzare policy RBAC per limitare le azioni che possono essere svolte sui nodi. Minore è l’accesso ai nodi e minori sono le informazioni che li riguardano, più i nodi stessi saranno protetti dagli hacker.
  • Utilizzare strumenti di applicazione quali SELinux, AppArmor e seccomp per limitare il controllo degli accessi a livello di kernel sul master. Questi strumenti consentiranno di evitare l’escalation degli eventi di sicurezza rendendo più difficile per un processo dannoso accedere alle risorse del kernel o interferire con altri processi.
  • Monitorare costantemente i file di registro dei nodi per rilevare segnali di attività sospette.

Protezione dei nodi worker e limitazione delle autorizzazioni Kubelet e Kube-Proxy

    Lo scopo principale dei nodi worker è ospitare container o pod in esecuzione. Ciascun nodo worker comunica con il resto del cluster attraverso kubelet, un agente eseguito localmente su ciascun nodo worker. I nodi worker utilizzano inoltre un servizio chiamato kube-proxy per gestire le comunicazioni di rete per i pod ospitati su di essi.

    Da design, i nodi worker di Kubernetes sono sostituibili. Se un nodo smette di funzionare, cioè, Kubernetes riassegnerà automaticamente i suoi pod ad altri nodi. In questo senso, proteggere i nodi worker è meno critico che proteggere i nodi master, perché un problema ad alcuni nodi worker causato da questioni di sicurezza non pone una minaccia tanto grave al cluster.

    Ciononostante, l’autore di un attacco che riesce a compromettere un nodo worker può potenzialmente accedere a qualunque pod ospitato su di esso. Per questa ragione, è importante adottare delle misure per proteggere i nodi worker nel contesto del processo di sicurezza generale del cluster.

    Tutte le migliori prassi per la protezione dei nodi master indicate sopra valgono anche per i nodi worker. Inoltre, bisogna considerare di limitare le autorizzazioni assegnate a kubelet e kube-proxy per ridurre il potenziale danno causato da un attacco che riesce a evadere da un container e a introdursi nel nodo worker che lo ospita.

    Scansione continua delle immagini dei container

    Le immagini dei container, che definiscono le risorse richieste per eseguire un container, non fanno parte di Kubernetes, tuttavia sono un elemento fondamentale di molti cluster Kubernetes e non dovrebbero essere trascurate nella loro protezione.

    La chiave per proteggere le immagini dei container è scansionarle continuamente. Inoltre, è possibile minimizzare i problemi di sicurezza legati ai container:

    • Utilizzando solo immagini derivanti da fonti affidabili. Resistendo alla tentazione di ottenere immagini da un registro casuale solo per comodità.
    • Evitando di utilizzare il tag “latest” (più recente) quando si cercano le immagini. Al contrario, è bene specificare una versione per conoscere esattamente qual è la versione del container in esecuzione e quali vulnerabilità potrebbero interessarla.
    • Adottando un approccio minimalista alla progettazione delle immagini dei container. Piuttosto che ammassare molte risorse in un’unica immagine, creando diverse immagini per ciascuna funzionalità che si desideri implementare.

    Sicurezza del runtime dei container

      Il runtime di un container è un servizio che esegue i container. Kubernetes supporta molti runtime diversi. Le differenze tra i runtime di solito non sono rilevanti per i casi d’uso, perché molti di essi sono in grado di eseguire la maggior parte dei container.

      Una falla nella sicurezza del software di runtime di un container potrebbe consentire agli autori di un attacco di svolgere una molteplicità di azioni. Per esempio, nel 2019 gli sviluppatori hanno scoperto una grave vulnerabilità nel runtime di Docker che consentiva ai container di ottenere accesso a livello di root all’intero host.

      Kubernetes non prevede funzioni per monitorare le vulnerabilità dei runtime dei container o per avvisare di eventuali violazioni che potrebbero derivare da tali vulnerabilità. È pertanto necessario affidarsi a strumenti esterni per proteggere i runtime, tra cui:

      • Strumenti di applicazione quali SELinux e AppArmor, che possono essere utilizzati per limitare le azioni svolte da un container dannoso. Se adeguatamente configurati, questi strumenti rappresentano un secondo livello di difesa in caso di attacco che sfrutta una vulnerabilità del runtime di un container e gli consente di svolgere azioni che non dovrebbe poter svolgere.
      • Strumenti di controllo quali Falco monitorano continuamente i registri di controllo e altri stream di dati dall’ambiente di runtime del container e generano un avviso quando rilevano comportamenti che potrebbero indicare una violazione. Sebbene gli strumenti di controllo siano in grado di rilevare diverse minacce per la sicurezza oltre a quelle associate con i runtime dei container, sono uno dei principali strumenti per l’individuazione di violazioni derivanti da una vulnerabilità a livello di runtime.
      • A meno che non sia strettamente necessario, i contesti di protezione di Kubernetes impediscono ai container di eseguire la modalità privilegiata e limitano le risorse a cui hanno accesso. Anche se i contesti di protezione non impediscono direttamente le vulnerabilità del runtime dei container, forniscono un ulteriore livello di difesa in grado di mitigare l’impatto di una eventuale violazione.

      Un approccio olistico alla sicurezza dei cluster di Kubernetes

      Sarebbe molto più semplice se esistesse un trucco magico da utilizzare per proteggere in una sola volta tutti i componenti di Kubernetes. Ma non esiste. La sicurezza di Kubernetes è tanto complessa quanto l’architettura che lo caratterizza. Mentre alcune prassi a livello di cluster, come il controllo e il monitoraggio, possano fornire ampia protezione da alcuni tipi di minacce, è anche necessario ricorrere a risorse di sicurezza in grado di proteggere i singoli componenti che formano un cluster Kubernetes, dal server API ai nodi worker e master, a etcd, e così via.