Comment sécuriser un cluster Kubernetes

Publié le


Do not index
Do not index
Primary Keyword
Lié à Analyse sémantique (Articles liés) 1
Lié à Analyse sémantique (Articles liés)
Statut rédaction
A optimiser SEO
Lié à Analyse sémantique (Articles liés) 2

Introduction

Une récente étude réalisée par les chercheurs de Shadowserver Foundation ont récemment découvert que plus de 380 000 API de serveur Kubernetes étaient ouvert sur le monde. Ouvrir l’API Kubernetes sur le monde est une faille de sécurité majeur qui peut à termes se transformer en source d’attaque. Dans le cas d’une brèche de sécurite, l’attaquant peut prendre le contrôle complet du cluster Kubernetes.
Avec cette étude, nous pouvons mettre en évidence l’importance absolue de la sécurisation de son cluster Kubernetes.
Dans cet article, nous allons présenter de bonnes pratiques lorsque l’on déploie un cluster Kubernetes.
Cet article ne comprendra pas les bonnes pratiques liées au déploiement de docker, de comment créer une image docker sécurirsée etc … Ces sujets étant très vaste, nous déciderons de ne pas les aborder ici.

Ne pas exposter l’API Kubernetes

La première bonne pratique que nous allons aborder est évidente au vue de l’étude réalisée, mais celle ci est très importante. N’exposez pas l’API Kubernetes au monde. En effet, il existe plusieurs méthode pour éviter cela, à utiliser selon vos besoins :
  • Si vous souhaiter réaliser des appels API sur votre cluster (par exemple pour réaliser des déploiements depuis votre pipeline de CI/CD) : Vous pouvez restreindre l’accès réseau à l’API uniquement depuis des ip sources connus (votre réseau privé, votre serveur de CI/CD etc ..)
  • Si vous souhaiter réaliser des déploiements avec un système dis “pull” (c’est à dire que c’est l’élément dans le cluster qui va récupérer des informations) telle que ArgoCD : Vous restreindre complètement l’accès réseau arrivant sur l’API Kubernetes.
 
Cette bonne pratique fonctionne aussi pour les autres éléments du coeur de Kubernetes tel que le backend etcd. Avoir accès en écriture à ce backend revient à avoir accès en root sur l’ensemble du cluster. Il est donc primordial de le protéger

Mettre à jour votre cluster

Une deuxième pratique évidente est de mettre à jour sont cluster Kubernetes afin de pouvoir avoir accès à l’ensemble des derniers patchs de sécurité. Il faut tout de même se renseigner lors des changements de versions de Kubernetes, certaines peuvent apporter des changements qui peuvent “casser” (breaking changes) vos applications. Il est fortement recommandé d’avoir un cluster par environnement et de mettre à jour ceux-ci en commençant par le cluster de développement afin d’anticiper ces erreurs.

Utiliser Kubernetes Role-Based Access Control (RBAC)

Kubernetes supporte plusieurs systèmes d’authentifications pour son API. La plus sécurisée est RBAC (Role based access control). Avec RBAC, vous allez pouvoir définir des rôles regroupant un ensemble d’action possibles sur les API de Kubernetes. Ainsi vous pouvez créer des rôles personalisés pour répondre à vos besoin métiers. Par exemple, imaginons que vous souhaitez créer deux rôles :
  • reader : Ce rôle permet d’avoir accès en lecture à l’ensemble des pods dans le namespace application
  • writer : Ce rôle permet d’avoir des accès en lecture et écriture sur l’ensemble des pods dans le namespace application
Nous pourrions les implémenter comme ceux-ci :
# Role reader
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: application
  name: reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
# Role writer
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: application
  name: writer
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["*"]
Enfin, la dernière chose à réaliser est de mapper “bind” ces rôles aux utilisateurs en utilisant des RoleBinding :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-services
  namespace: application
roleRef:
  kind: Role
  name: reader
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: Group
    name: reader-group
 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-services
  namespace: application
roleRef:
  kind: Role
  name: writer
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: Group
    name: writer-group
Il est existe un second type de role qui s’appelle ClusterRole. À la différence du Role, le ClusterRole permet de donner accès à des utilisateurs sur le cluster entier (pas seulement un namespace comme le Role). Pour mapper un utilisateur à un ClusterRole, il faut utiliser un ClusterRoleBinding

Utiliser un third party d’authentification OIDC

Par défaut, Kubernetes n’inclue aucun système d’authentification sofistiqué. Il est donc important de pouvoir trouver un moyen simple de pouvoir gérer les accès des utilisateurs à votre cluster Kubernetes. Pour cela, il est commun d’utiliser un “third party” pour l’authentification de vos utilisateurs.
 
À chaque fois qu’un nouvel utilisateur va vouloir réaliser une action dans le cluster (via la CLI kubectl par exemple), le cluster Kubernetes demandera à l’utilisateur de s’authentifier avec un certificat. Si cet utilisateur n’a pas de certificat, celui-ci sera redirigé vers le third party de confiance configuré (cela peut être Github, AWS etc …). Après que l’utilisateur se soient authentifié , il aura accès à un certificat. Bien sur, avec l’utilisation de RBAC (Role-based Access Control), l’utilisateur aura seulement les droits d’accès qu’il aura besoin (les droits RBAC sont “mappés” à des permissions dans le cluster).
Le protocol expliqué ci-dessus s’appelle OpenID Connect.
Vous pouvez retrouver un schéma détaillant ce système avec le third party Okta ci-dessous :
 
notion image
 

Sécuriser les connexions à etcd

Etcd est un des éléments centrals d’un cluster Kubernetes. Il héberge l’état entier de votre cluster. C’est pour cela qu’il doit être protégé autant que possible. Pour cela il est nécessaire de protéger chaque connexion entrante à l’aide de TLS.
On peut configurer TLS client ⇒ server comme ceci :
  • cert-file= : Certificat utilisé pour la connexion avec etcd
  • --key-file= : Clé du certificat utilisé
  • --client-cert-auth : Configure etcd pour vérifier que les requêtes entrantes sont signé par un CA connu
  • --trusted-ca-file=<chemin> : le certificat d’autorité (CA)
  • --auto-tls : Utilise des certificats auto-signés pour les connexions clientes
 
On peut configurer TLS server ⇒ server comme ceci :
  • --peer-cert-file=<chemin> : Certificat utilisé pour les connexions entre peer
  • --peer-key-file=<chemin> : Clé de certificat utilisé
  • --peer-client-cert-auth= : Configure etcd pour vérifier que les requêtes entrantes sont signé par un CA connu
  • --peer-trusted-ca-file=<chemin> : e certificat d’autorité (CA)
  • --peer-auto-tls : Utilise des certificats auto-signés pour les connexions clientes

Activer les logs d’audit

Il est important de monitorer les actions réalisées dans un cluster Kubernetes. Vous pouvez réaliser cela en activant le système de log d’audit dans Kubernetes.
Comme tout objet dans un cluster Kubernetes, le logging se configure à l’aide d’un manifeste yaml. Voici un exemple :
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: RequestResponse
    resources:
    - group: ""
      resources: ["pods"]
 
Chaque policy a :
  • Un level : Définis quel niveau de log vous voulez pour la resource. Il existe 4 niveaux de logs :
    • None : Pas de log
    • Metadata : Les requêtes de métadata sont loggés
    • Request : Les requêtes de métadata et le contenu des requêtes sont loggés (mais pas la réponse)
    • RequestResponse : Les requêtes de métadata, le contenu des requêtes et les réponses sont loggés.
  • Des resources :
    • group : Groupe d’API kubernetes
    • resources : Les resources dont on souhaite définir la policy de log
    •  
Chaque évènement sera loggés sous forme d’un JSON. Ainsi une entrée de log pourrait ressembler à :
{
  "kind": "Event",
  "apiVersion": "audit.k8s.io/v1",
  "level": "RequestResponse",
  "auditID": "fbc474df-2466-4612-ae36-69af2c927f9d",
  "stage": "ResponseComplete",
  "requestURI": "/api/v1/namespaces/default/pods/nginx",
  "verb": "get",
  "user": {
    "username": "system:node:minikube",
    "groups": [
      "system:nodes",
      "system:authenticated"
    ]
  },
  "sourceIPs": [
    "192.168.07.2"
  ],
  "userAgent": "kubelet/v1.21.2 (linux/amd64) kubernetes/092fbfb",
  "objectRef": {
    "resource": "pods",
    "namespace": "default",
    "name": "nginx",
    "apiVersion": "v1"
  },
  "responseStatus": {
    "metadata": {},
    "code": 200
  },
  "responseObject": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {...},
    "spec": {...},
    "status": {...}
  },
  "requestReceivedTimestamp": "2022-07-15T11:53:64.944663Z",
  "stageTimestamp": "2022-07-15T11:53:64.968543Z",
  "annotations": {
    "authorization.k8s.io/decision": "allow",
    "authorization.k8s.io/reason": ""
  }
}

Auditer votre cluster régulièrement

Afin de toujours respecter vos standards de sécurité, il est intéressant d’auditer régulièrement votre cluster Kubernetes. Cela peut être fait de manière automatique en utilisant des outils tels que kube-bench.
Kube-bench est un outil développé par la société aquasecurity qui implémente une grande partie du benchmark définis dans le standard de sécurité CIS (Center for Internet Security).
Il peut être lancé à l’intérieur d’un pod et examiner l’ensemble des configurations du cluster Kubernetes dans lequel il est. Enfin un rapport entier est réalisé comme ceux-ci :
notion image

Conclusion

Il est primodial de sécuriser son cluster Kubernetes afin d’éviter de créer des brèches de sécurité dans son système d’information. Cette sécurisation regroupe plusieurs domaines tels que le réseau, la gestions des utilisateurs, le logging etc …
Il est intéressant de noter que les services clouds de Kubernetes (EKS, GKE, AKS pour respectivement AWS, GCP et Azure) , implémente une grande partie des bonnes pratiques d’installation de cluster kubernetes.
 

S'inscrire à la newsletter DevSecOps Keltio

Pour recevoir tous les mois des articles d'expertise du domaine

S'inscrire