Meilleures pratiques essentielles de RBAC pour sécuriser vos clusters Kubernetes

Apprenez les meilleures pratiques RBAC Kubernetes, des exemples de rôles à moindre privilège, le cadrage des comptes de service et les vérifications d'audit pour des clusters plus sûrs.

Meilleures pratiques RBAC essentielles pour sécuriser vos clusters Kubernetes

Le RBAC Kubernetes décide qui peut faire quoi dans votre cluster. Une seule liaison large peut permettre à un compte compromis de lire les secrets, de modifier les charges de travail ou de prendre le contrôle des ressources du cluster.

Ce guide explique les objets RBAC fondamentaux, montre des exemples concrets et vous donne des habitudes de révision qui empêchent les accès de dériver avec le temps.

Comprendre les fondamentaux du RBAC Kubernetes

Le RBAC dans Kubernetes est un mécanisme d'autorisation qui régule l'accès aux ressources Kubernetes en fonction des rôles des utilisateurs individuels ou des comptes de service. C'est une couche de défense cruciale, garantissant que seules les entités autorisées peuvent effectuer des actions spécifiques sur des ressources spécifiques.

À la base, le RBAC repose sur quatre types principaux d'objets Kubernetes :

  • Role : Un Role est un ensemble de permissions qui s'applique dans un espace de noms spécifique. Il définit quelles actions (verbes comme get, list, create, update, delete) peuvent être effectuées sur quelles ressources (comme pods, deployments, services, secrets). Par exemple, un Role pourrait accorder la permission de lire les pods et les deployments dans l'espace de noms development.
  • ClusterRole : Similaire à un Role, mais un ClusterRole définit des permissions qui s'appliquent à l'échelle du cluster ou à des ressources non nommées (par exemple, nodes, persistentvolumes). Un ClusterRole peut également définir des permissions pour des ressources nommées dans tous les espaces de noms. Par exemple, un ClusterRole pourrait permettre de lister tous les nodes du cluster.
  • RoleBinding : Un RoleBinding accorde les permissions définies dans un Role (ou un ClusterRole appliqué à un espace de noms) à un utilisateur, un groupe ou un compte de service. Il opère toujours dans un espace de noms spécifique.
  • ClusterRoleBinding : Un ClusterRoleBinding accorde les permissions définies dans un ClusterRole à un utilisateur, un groupe ou un compte de service, en appliquant ces permissions à l'ensemble du cluster.

Ensemble, ces objets permettent aux administrateurs de construire un système de contrôle d'accès robuste et granulaire. Lorsqu'un utilisateur ou une application (représenté par un compte de service) tente d'effectuer une action, Kubernetes évalue les RoleBindings et ClusterRoleBindings existants pour déterminer si l'action demandée est autorisée.

Mise en œuvre du principe de moindre privilège avec RBAC

Un principe central de la sécurité de l'information est le principe de moindre privilège. Un utilisateur, un programme ou un processus ne doit recevoir que les permissions nécessaires pour effectuer son travail. Dans Kubernetes, des rôles trop permissifs sont un moyen courant pour qu'une petite compromission devienne un problème à l'échelle du cluster.

Définir des permissions granulaires

Lors de la création de politiques RBAC, réfléchissez aux actions et ressources précises nécessaires :

  • Verbes : Au lieu d'accorder * (tous les verbes), spécifiez exactement les actions nécessaires (get, list, watch, create, update, delete, patch, exec).
  • Ressources : Soyez précis sur les ressources (pods, deployments, secrets, configmaps). Évitez d'accorder l'accès à * pour les ressources, sauf en cas d'absolue nécessité et pour des rôles administratifs bien justifiés.
  • Noms de ressources : Pour les ressources très sensibles comme les secrets, vous pouvez restreindre certains verbes, comme get, à des resourceNames spécifiques dans un type de ressource. Ne vous fiez pas aux resourceNames pour un accès de type liste, car list et watch ne sont pas limités à un seul objet nommé de la même manière.
  • Groupes d'API : La plupart des ressources Kubernetes appartiennent à un groupe d'API (par exemple, apps, rbac.authorization.k8s.io, "" pour les ressources de base). Spécifiez le groupe d'API correct pour affiner davantage la portée.

Délimitation des espaces de noms

Pour la plupart des applications et des équipes de développement, les permissions doivent être confinées à des espaces de noms spécifiques. Cette ségrégation garantit qu'une compromission dans l'environnement d'une application ou d'une équipe n'entraîne pas automatiquement un accès à l'échelle du cluster. Préférez toujours Role et RoleBinding à ClusterRole et ClusterRoleBinding lorsque c'est possible.

Mise en œuvre pratique du RBAC : exemples

Parcourons quelques exemples pratiques de création et de liaison de politiques RBAC.

Exemple 1 : Accès développeur à un espace de noms spécifique

Imaginez qu'un développeur doit gérer les déploiements et voir les journaux dans son espace de noms dédié, dev-team-a. Il ne doit pas avoir accès à d'autres espaces de noms ou à des ressources à l'échelle du cluster.

Tout d'abord, définissez un Role pour le développeur dans l'espace de noms dev-team-a :

# dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-team-a
  name: dev-deployer
rules:
- apiGroups: ["apps"] # Pour les déploiements
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
- apiGroups: [""] # Groupe d'API de base pour les pods et les journaux de pods
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

Appliquez ce rôle :

kubectl apply -f dev-role.yaml

Ensuite, liez ce Role à un utilisateur spécifique (par exemple, [email protected] via un fournisseur d'identité externe) ou à un compte de service dans l'espace de noms dev-team-a :

# dev-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: dev-team-a
  name: john-dev-deployer-binding
subjects:
- kind: User
  name: [email protected] # Le nom est sensible à la casse
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: dev-deployer
  apiGroup: rbac.authorization.k8s.io

Appliquez cette liaison :

kubectl apply -f dev-role-binding.yaml

Maintenant, [email protected] ne peut gérer que les déploiements et voir les journaux dans l'espace de noms dev-team-a. Il ne peut pas, par exemple, créer des secrets dans kube-system ou lister tous les nœuds.

Exemple 2 : Compte de service d'application accédant aux secrets

Une application s'exécutant en tant que ServiceAccount doit lire un secret spécifique dans son propre espace de noms.

Tout d'abord, assurez-vous que le compte de service existe ou créez-en un :

# app-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: my-app-namespace
  name: my-app-service-account

Appliquez ce compte de service :

kubectl apply -f app-sa.yaml

Ensuite, définissez un Role qui permet de lire un secret spécifique :

# secret-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: my-app-namespace
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["my-app-db-credentials"]
  verbs: ["get"]

Appliquez ce rôle :

kubectl apply -f secret-reader-role.yaml

Enfin, liez ce Role au my-app-service-account :

# app-secret-reader-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: my-app-namespace
  name: my-app-secret-reader-binding
subjects:
- kind: ServiceAccount
  name: my-app-service-account
  namespace: my-app-namespace
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Appliquez cette liaison :

kubectl apply -f app-secret-reader-binding.yaml

L'application ne pourra désormais lire que le secret spécifié et rien d'autre.

Exemple 3 : Rôle d'administrateur de cluster (avec prudence)

Les rôles administratifs à l'échelle du cluster doivent être accordés avec une extrême parcimonie. Voici un exemple de ClusterRole pour lister tous les nœuds, ce qui pourrait être nécessaire pour un outil de surveillance.

# node-viewer-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-viewer
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

Appliquez ce ClusterRole :

kubectl apply -f node-viewer-clusterrole.yaml

Ensuite, liez-le à un compte de service de surveillance à l'aide d'un ClusterRoleBinding :

# monitoring-node-viewer-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitoring-node-viewer-binding
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: node-viewer
  apiGroup: rbac.authorization.k8s.io

Appliquez cette liaison :

kubectl apply -f monitoring-node-viewer-binding.yaml

Avertissement : Soyez extrêmement prudent avec ClusterRole et ClusterRoleBinding pour les utilisateurs humains. Limitez leur utilisation aux véritables administrateurs de cluster et aux comptes de service d'infrastructure spécifiques.

Meilleures pratiques RBAC essentielles

Le respect de ces meilleures pratiques améliorera considérablement la posture de sécurité de votre cluster :

  1. Appliquer le principe de moindre privilège (PoLP) :

    • Accordez uniquement les permissions minimales nécessaires. Examinez chaque permission attentivement.
    • Évitez les caractères génériques (*) pour resources et verbs autant que possible. Si utilisés, justifiez-les et essayez de les limiter au maximum.
    • Restreignez l'accès aux ressources sensibles (comme les secrets) en utilisant resourceNames dans les rôles.
  2. Utiliser les espaces de noms pour la ségrégation :

    • Organisez vos applications et équipes dans des espaces de noms distincts.
    • Par défaut, utilisez Role et RoleBinding pour accorder des permissions dans ces espaces de noms.
  3. Préférer les rôles aux ClusterRoles :

    • N'utilisez ClusterRole et ClusterRoleBinding que lorsque les permissions doivent vraiment être à l'échelle du cluster (par exemple, gestion des nœuds, définitions de ressources personnalisées, agents de surveillance spécifiques).
    • La plupart des permissions spécifiques aux applications doivent être limitées à un espace de noms.
  4. Auditer et réviser régulièrement les politiques RBAC :

    • Les politiques RBAC peuvent dériver avec le temps. Révisez périodiquement qui a quel accès.
    • Utilisez des outils comme kubectl auth can-i pour tester les permissions pour des utilisateurs/comptes de service spécifiques.
    # Vérifier si '[email protected]' peut obtenir des pods dans 'dev-team-a'
    kubectl auth can-i get pods --namespace=dev-team-a [email protected]
    
    # Vérifier si 'monitoring-sa' peut lister les nœuds (à l'échelle du cluster)
    kubectl auth can-i list nodes --as=system:serviceaccount:monitoring:monitoring-sa
    
    • Envisagez des outils tiers ou des scripts personnalisés pour un audit RBAC complet.
  5. Séparer les rôles administratifs :

    • Ne donnez jamais aux développeurs ou aux comptes de service d'application les privilèges cluster-admin.
    • Créez des ClusterRoles administratifs spécifiques avec uniquement les permissions élevées nécessaires (par exemple, cluster-reader, node-reader).
  6. Tirer parti des comptes de service pour les applications :

    • Les applications s'exécutant dans le cluster doivent utiliser des ServiceAccounts pour interagir avec l'API Kubernetes.
    • Chaque application ou microservice devrait idéalement avoir son propre ServiceAccount dédié avec des permissions minimales.
    • Définissez automountServiceAccountToken: false pour les pods qui n'ont pas besoin d'accès à l'API Kubernetes, soit sur le pod, soit sur le compte de service.
  7. Intégrer avec la gestion d'identité externe :

    • Pour les utilisateurs humains, intégrez Kubernetes à un fournisseur d'identité externe (par exemple, OIDC, LDAP, Active Directory) pour l'authentification et la gestion des groupes.
    • Mappez les groupes externes aux RoleBindings ou ClusterRoleBindings Kubernetes pour une gestion plus facile.
  8. Automatiser la gestion RBAC avec GitOps :

    • Traitez vos politiques RBAC comme du code. Stockez-les dans un dépôt versionné (Git).
    • Utilisez les principes GitOps pour gérer et déployer les configurations RBAC, garantissant la cohérence, la traçabilité et des retours en arrière plus faciles.
  9. Surveiller les événements RBAC via les journaux d'audit :

    • Activez et configurez la journalisation d'audit Kubernetes pour suivre les requêtes API, y compris qui a effectué quelle action et quand.
    • Révisez régulièrement les journaux d'audit pour détecter les tentatives d'accès non autorisées ou les activités suspectes liées au RBAC.
  10. Mettre à jour régulièrement Kubernetes :

    • Restez à jour avec les versions de Kubernetes pour bénéficier des correctifs de sécurité et des améliorations, y compris les améliorations RBAC.

Pièges courants et comment les éviter

  • Caractères génériques trop permissifs : Accorder apiGroups: ["*"], resources: ["*"] ou verbs: ["*"] est un risque de sécurité majeur. Soyez toujours explicite.
  • Utilisation par défaut de cluster-admin : N'utilisez pas le groupe system:masters ou le ClusterRole cluster-admin pour les opérations quotidiennes et ne les attribuez pas à des utilisateurs non administrateurs. L'un ou l'autre donne un contrôle étendu sur le cluster.
  • Ignorer automountServiceAccountToken : Dans de nombreux clusters, les pods reçoivent un jeton de compte de service sauf si vous désactivez le montage automatique. Si un pod n'a pas besoin d'interagir avec l'API Kubernetes, définissez automountServiceAccountToken: false dans la spécification du pod ou la définition du compte de service pour réduire sa surface d'attaque.
  • Manque d'audit : Sans révision régulière, les politiques RBAC peuvent devenir obsolètes ou trop permissives à mesure que les besoins du cluster évoluent. Mettez en place un processus de révision.
  • Confusion entre Role et ClusterRole : Une mauvaise compréhension de la portée peut conduire à accorder un accès à l'échelle du cluster alors qu'un accès limité à un espace de noms était prévu.

À retenir

Le RBAC fonctionne mieux lorsque vous le gardez simple et spécifique : des rôles limités aux espaces de noms pour les équipes d'application, des permissions de compte de service étroites, pas de caractères génériques sans révision, et des vérifications régulières avec kubectl auth can-i. Traitez chaque liaison comme du code de production, car dans un cluster Kubernetes, c'est effectivement le cas.