BLOG

Notions de base sur la sécurité des conteneurs : Orchestration

  Jordan Zebor

  Lori MacVittie

Publié le 24 juillet 2019

Si vous débutez dans cette série, vous souhaiterez peut-être commencer par le début : 
Notions de base sur la sécurité des conteneurs : Introduction
Notions de base sur la sécurité des conteneurs : Pipeline

Selon l'état de la sécurité des conteneurs 2019 de Tripwire , environ une organisation sur trois (32 %) exploite actuellement plus de 100 conteneurs en production. Un pourcentage plus faible (13 %) en exploite plus de 500. Et 6 % des adoptants vraiment enthousiastes en gèrent actuellement plus de 1 000. Peu d’organisations exploitent des conteneurs à grande échelle sans un système d’orchestration pour les aider.

La couche d’orchestration de la sécurité des conteneurs se concentre sur l’environnement responsable du fonctionnement quotidien des conteneurs. D’après les données disponibles aujourd’hui, si vous utilisez des conteneurs, vous profitez presque certainement de Kubernetes en tant qu’orchestrateur.

Il est important de noter que d’autres orchestrateurs existent, mais la plupart d’entre eux exploitent également des composants et des concepts dérivés de Kubernetes. Nous allons donc nous concentrer sur la sécurité de Kubernetes et de ses composants.

L'environnement Kubernetes

Kubernetes est composé de plusieurs éléments mobiles. Cela rend la sécurisation plus difficile, non seulement en raison du nombre de composants impliqués, mais également de la manière dont ces composants interagissent. Certains communiquent via l'API. D'autres via le système de fichiers hôte. Tous ces éléments constituent des points d’entrée potentiels dans l’environnement d’orchestration qui doivent être traités. 

environnement kubernetes de base

Environnement Kubernetes de base

Un aperçu rapide des principaux composants nécessitant une attention particulière :

  • Serveur API et Kubelet
  • Gousses
  • Etc.

Cela signifie que vous devez prendre une tasse de café, car cela va prendre un peu plus de temps à passer.

1. L'authentification n'est pas facultative

Les lecteurs attentifs remarqueront que cela semble familier. Vous l'avez peut-être entendu parler de la règle de sécurité numéro deux, alias Verrouillez la porte. C’est un thème commun que nous continuerons à répéter car il est souvent ignoré. Une authentification forte est indispensable. Nous avons observé que le nombre d’incidents de sécurité dus à de mauvaises pratiques de sécurité concernant les conteneurs continue d’augmenter. L’une des sources les plus courantes est l’échec de l’utilisation de l’authentification, généralement lorsqu’elle est déployée dans le cloud public.

Exigez de solides qualifications et faites-les tourner souvent. L’accès au serveur API (via des consoles non sécurisées) peut conduire à une situation de « game over » car l’ensemble de l’environnement d’orchestration peut être contrôlé via celui-ci. Cela signifie déployer des pods, modifier les configurations et arrêter/démarrer les conteneurs. Dans un environnement Kubernetes, le serveur API est « l’API unique qui les gouverne tous » que vous souhaitez garder hors de portée des mauvais acteurs.

Comment sécuriser le serveur API et Kubelet

Il est important de noter que ces recommandations sont basées sur le modèle d’autorisation Kubernetes actuel. Consultez toujours la documentation la plus récente pour la version que vous utilisez.

  • Activer mTLS partout
    - Dédier une autorité de certification par service – k8s, etcd, applications
    - Faites tourner les certificats et méfiez-vous des autorisations de clé privée sur le disque
  • Se lier uniquement à des adresses sécurisées
    - Attention à la configuration de l'API « insecure-bind-address » et « insecure-port »
    - Appliquez ceci à _tous_ les services (SSH, Vault, etc.)
  • Désactiver « Authentification anonyme »
    - « L’authentification anonyme » semble-t-elle être une bonne idée ?
    - Désactivé par défaut à partir de la version 1.5, activé manuellement avec « --anonymous-auth=True »
  • Activer l'autorisation
    - N'utilisez pas « --authorization-mode=AlwaysAllow »
    - Le serveur API doit avoir « --authorization-mode=RBAC,Node »
    - Kubelet doit avoir « --authorization-mode=Webhook »
    - Limitez l'accès de Kubelet aux ressources uniquement sur son propre nœud.

Il est important de noter que ces recommandations sont basées sur le modèle d’autorisation Kubernetes actuel. Consultez toujours la documentation la plus récente pour la version que vous utilisez. 

2. Pods et privilèges 

Les pods sont une collection de conteneurs. Il s'agit du plus petit composant Kubernetes et, dépendant du plugin Container Network Interface (CNI), tous les pods peuvent être en mesure de se joindre les uns aux autres par défaut. Il existe des plugins CNI qui peuvent utiliser des « politiques réseau » pour implémenter des restrictions sur ce comportement par défaut. Ceci est important à noter car les pods peuvent être planifiés sur différents nœuds Kubernetes (qui sont analogues à un serveur physique). Les pods montent également couramment des secrets, qui peuvent être des clés privées, des jetons d'authentification et d'autres informations sensibles. C’est pour cela qu’on les appelle « secrets ».

Cela signifie qu’il existe plusieurs problèmes liés aux pods et à la sécurité. Chez F5, nous supposons toujours que le pod est compromis lorsque nous commençons la modélisation des menaces. C’est parce que les pods sont l’endroit où les charges de travail des application sont déployées. Étant donné que les charges de travail des application sont les plus susceptibles d’être exposées à des accès non fiables, elles constituent le point de compromis le plus probable. Cette hypothèse conduit à quatre questions fondamentales à poser afin de planifier la manière d’atténuer les menaces potentielles. 

  1. Que pourrait voir ou faire un attaquant avec d’autres pods ayant accès à un pod ?
  2. Un attaquant peut-il accéder à d’autres services du cluster ?
  3. Quels secrets sont montés automatiquement ?
  4. Quelles autorisations ont été accordées au compte de service pod ?

Les réponses à ces questions exposent des risques qui pourraient être exploités si un attaquant accède à un pod au sein du cluster. L’atténuation des menaces de compromission des pods nécessite une approche à multiples facettes impliquant des options de configuration, un contrôle des privilèges et des restrictions au niveau du système. N’oubliez pas que plusieurs pods peuvent être déployés sur le même nœud (physique ou virtuel) et ainsi partager l’accès au système d’exploitation, généralement un système d’exploitation Linux.

Comment atténuer les menaces Pod
Kubernetes inclut une ressource de politique de sécurité de pod qui contrôle les aspects sensibles d'un pod. Il permet aux opérateurs de définir les conditions dans lesquelles un pod doit fonctionner pour être autorisé à entrer dans le système et applique une base de référence pour le contexte de sécurité du pod. Ne présumez jamais que les valeurs par défaut sont sécurisées. Mettez en œuvre des lignes de base sécurisées et vérifiez les attentes pour vous protéger contre les menaces des pods.

Les options spécifiques pour une politique de sécurité de pod doivent aborder les éléments suivants :

  • Évitez les conteneurs privilégiés
    • Recherchez le paramètre « —allow-privileged » sur kube-api et/ou kubelet
    • Recherchez « privileged : true » dans la spécification du pod.
    • Réduisez les risques de sécurité avec « --allow-privileged=false »
  • L'utilisateur par défaut du conteneur avec Docker est root
    • Évitez d’exécuter une charge de travail en tant que root
    • La politique de sécurité du pod peut utiliser « runAsUser », « runAsGroup » et « runAsNonRoot : true »
    • Des options similaires peuvent être définies dans un Dockerfile
  • Interdire l'escalade des privilèges au sein d'un conteneur
    • « allowPrivilegeEscalation : false »
  • Utiliser SELinux / AppArmor
    • SELinux utilisera la sécurité multi-catégories pour confiner les conteneurs les uns des autres
    • Laissez activé et travaillez sur les refus
    • La désactivation ou le passage en mode permissif réduit considérablement la sécurité
  • Prévenir les attaques par lien symbolique/point d'entrée
    • Les attaquants peuvent écraser le binaire du point d'entrée ou créer de mauvais liens symboliques
    • Évitez cela en définissant « readOnlyRootFilesystem : true »
  • Éviter les options de configuration de l'hôte*
    • Les attaquants ayant accès aux ressources de l'hôte sont plus susceptibles de poursuivre leur compromission dans l'hôte et/ou les conteneurs adjacents
    • Évitez les options telles que hostPID, hostIPC, hostNetwork, hostPorts
  • Montages hostPath en lecture seule
    • S’il est nécessaire de configurer la lecture/écriture dans l’hôte, soyez prudent avec le déploiement et n’en faites certainement pas une pratique par défaut
    • Utilisez « readOnly » sur tous les chemins d’hôte autorisés pour éviter les attaques
  • Profils Seccomp
    • Réduisez la surface de menace en limitant les appels système autorisés
    • Docker par défaut réduira certains mais il s'agit d'un profil générique
    • Les profils spécifiques aux application offriront le plus grand avantage en matière de sécurité

3. Etc.

Etcd est le magasin de configuration et de secrets. Une compromission ici peut permettre l’extraction de données sensibles ou l’injection de données malveillantes. Ni l'un ni l'autre n'est bon. Atténuer les menaces pesant sur etcd signifie contrôler l’accès. Le meilleur moyen d'y parvenir est d' appliquer mTLS . Les secrets sont stockés par Kubernetes dans etcd sous forme codée en base64. Envisagez l’utilisation d’une fonctionnalité alpha, « fournisseur de chiffrement » , pour des options plus puissantes lors du stockage de secrets sensibles ou envisagez d’utiliser HashiCorp Vault.