Meilleures pratiques pour la gestion des secrets Kubernetes

Centraliser la gestion des secrets pour éviter leur dispersion

La dispersion des secrets dans des fichiers de configuration, des dépôts Git et des fichiers YAML augmente les risques de sécurité. La centralisation de la gestion des secrets en un seul emplacement sécurisé facilite leur utilisation pour toute l’organisation tout en garantissant une gestion adéquate de l’autorisation, de la surveillance et de la journalisation des accès. [1]

Meilleures pratiques pour la gestion des secrets kubernetes
Meilleures pratiques pour la gestion des secrets Kubernetes 2

Chiffrer les données en transit et au repos

Kubernetes ne stocke ni ne transmet les secrets de manière sécurisée par défaut. Par conséquent, il est crucial de mettre en place une structure qui chiffre les secrets en transit avec un chiffrement TLS de bout en bout et une solution qui stocke les secrets sous une forme chiffrée.

Utiliser la rotation automatique des secrets

La rotation régulière des secrets est une bonne pratique de sécurité pour limiter l’exposition en cas d’attaques. Les services de gestion des secrets cloud et les solutions externes offrent généralement une rotation automatique des secrets, ce qui permet de les faire tourner aussi souvent qu’horaires, selon la sensibilité des données.

Mettre en place des journaux d’audit pour suivre l’activité des secrets

Les journaux d’audit permettent de suivre les activités liées aux secrets. En cas d’incident, les journaux d’audit offrent une visibilité et aident à évaluer l’incident, y compris s’il s’agissait d’une atteinte intentionnelle, les zones affectées et les autres mesures d’enquête.

Mettre en place des règles anti-affinité pour contrôler la distribution des secrets

La solution de gestion des secrets doit être un processus unique sur un nombre limité de VM ou de machines hôtes désignées. Si elle est exécutée sous forme de microservice sur Kubernetes, ce processus sera en cours d’exécution dans une pod dédiée. Pour spécifier les nœuds sur lesquels les pods doivent être exécutés, vous pouvez mettre en place une règle anti-affinité pour contrôler la distribution des pods sur les nœuds qui sont configurés pour exécuter une solution de gestion des secrets.

Utiliser des secrets dynamiques avec une durée de vie limitée

Les secrets dynamiques sont des secrets éphémères générés à la demande avec une durée de vie limitée. Même si un attaquant accède à un secret via des moyens tels que des codes d’application divulgués ou des journaux de débogage, le secret aura été modifié dans un court laps de temps, limitant ainsi l’exposition et protégeant l’application. Les secrets dynamiques peuvent également faciliter la détermination de la période pendant laquelle un secret a été découvert par un attaquant et accélérer les enquêtes.

Utiliser une autorité de certification personnalisée pour implémenter la défense en profondeur

L’utilisation d’une autorité de certification personnalisée (CA) peut être utilisée pour mettre en œuvre le chiffrement TLS de bout en bout dans le cadre d’une approche de défense en profondeur. Les organisations peuvent choisir de signer leurs certificats avec leur propre CA, ce qui signifie que le certificat signé par l’organisation doit être présenté pour accéder à un service.

Secrets stockage dans la mémoire du conteneur

Stocker les secrets en mémoire rendra plus difficile pour les attaquants de trouver les secrets lors d’une violation de sécurité. Chaque fois qu’une application conteneurisée reçoit un secret, au lieu de stocker le secret sur un disque ou dans le volume disponible dans l’hôte, il doit être en mémoire.

Protéger le Secret Zero

Le chiffrement d’enveloppe est souvent adopté par de nombreuses solutions de gestion de secrets, où les clés de chiffrement des données (DEK) sont protégées par une clé de chiffrement de clé (KEK). Ici, la KEK est considérée comme le secret zéro, la clé maître ultime. Si la KEK est compromise, les attaquants peuvent décrypter la DEK, et par conséquent, les données chiffrées par la DEK.

Pour protéger le secret zéro, utilisez le cadre de gestion d’identité et d’accès (IAM) de votre fournisseur de services cloud choisi en conjonction avec des serveurs de gestion de clés (KMS). Notez que l’IAM et le KMS auraient leur propre secret zéro dans la chaîne de confiance, qui devrait également être considéré comme des données sensibles.

Conclusion:

Lorsqu’il s’agit de protéger des données sensibles, la méthode la plus efficace consiste à adopter un modèle de confiance zéro, à supposer la compromission et à mettre en place des mesures pour atténuer les risques. Les approches et les meilleures pratiques recommandées dans cet article posent les bases d’une gestion des secrets sécurisée.

Les ressources supplémentaires suivantes peuvent également être utiles pour ceux qui cherchent à approfondir leur compréhension de la gestion des secrets :

  • Le livre blanc « Gestion des secrets pour les charges de travail en conteneurs et de cloud natif » (en anglais) de HashiCorp fournit une introduction complète à la gestion des secrets dans les environnements de conteneurs et de cloud natif.
  • La documentation de Kubernetes sur la gestion des secrets fournit des informations sur la création et la gestion des secrets Kubernetes.
  • L’ebook « Kubernetes security and observability: A holistic approach to securing containers and cloud native applications » (en anglais) fournit une approche holistique de la sécurité
  • La documentation de Kubernetes sur la gestion des secrets fournit des informations sur la création et la gestion des secrets Kubernetes.
  • L’ebook « Kubernetes security and observability: A holistic approach to securing containers and cloud native applications » (en anglais) fournit une approche holistique de la sécurité

Utilisation de secrets dans un environnement Kubernetes on-premise avec une application WordPress utilisant une base de données. Zéro to petit héro ?

Voici un exemple simple d’utilisation de secrets dans un environnement Kubernetes on-premise avec une application WordPress utilisant une base de données.

  1. Créez un secret pour stocker les informations de connexion de la base de données :
apiVersion: v1
kind: Secret
metadata:
name: wordpress-db-creds
type: Opaque
data:
username: dXNlcm5hbWU=
password: cGFzc3dvcmQ=

Dans cet exemple, le secret contient le nom d’utilisateur et le mot de passe de la base de données encodés en base64. Bien sûr, il est important de choisir des noms d’utilisateur et des mots de passe forts et de stocker ces informations de manière sécurisée. C’est totalement insuffisant on y revient ensuite.

  1. Déployez l’application WordPress :
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:latest
env:
- name: WORDPRESS_DB_HOST
value: db
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: wordpress-db-creds
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db-creds
key: password
ports:
- containerPort: 80
imagePullSecrets:
- name: regcred

Dans cet exemple, nous avons créé un déploiement pour notre application WordPress. Le conteneur WordPress a besoin des informations de connexion à la base de données pour fonctionner, nous les récupérons donc à partir du secret wordpress-db-creds que nous avons créé précédemment. Nous avons également créé une référence au secret regcred, qui contient les informations d’authentification pour accéder au registre de conteneurs.

  1. Déployez la base de données :
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-creds
key: password
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-creds
key: username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-creds
key: password
ports:
- containerPort: 3306

Dans cet exemple, nous avons créé un déploiement pour notre base de données MySQL. Les informations d’authentification pour l’utilisateur de la base de données sont stockées dans le secret mysql-creds et le mot de passe du super-utilisateur est stocké dans le secret mysql-root-creds.

Cet exemple montre comment utiliser des secrets pour stocker des informations sensibles dans un environnement Kubernetes on-premise. En utilisant des secrets pour stocker des informations sensibles, nous pouvons protéger ces informations de manière efficace, ce qui est essentiel pour la sécurité de l’application. Grâce à la configuration des secrets, les informations d’authentification de la base de données ne sont pas stockées directement dans le déploiement de l’application ou de la base de données, mais plutôt stockées dans des secrets Kubernetes sécurisés et accessibles uniquement par des entités autorisées.

De plus, en utilisant des secrets, nous pouvons facilement gérer les informations sensibles pour toutes les applications et bases de données de notre environnement Kubernetes. Si les informations d’authentification doivent être mises à jour, il suffit de mettre à jour le secret correspondant.

Il est important de noter que la gestion des secrets est un élément essentiel de la sécurité des applications Kubernetes, mais elle n’est pas suffisante en soi. Pour une sécurité renforcée, il est également recommandé de mettre en place d’autres mesures de sécurité, telles que le chiffrement de bout en bout, la gestion des accès, la surveillance des journaux, etc.

Sécuriser le point 1 connexion à la base de données

la solution proposée dans le point 1, qui consiste à encoder en base64 les informations de connexion et à les stocker dans un objet Secret Kubernetes, n’est pas considérée comme sécurisée, car la base64 est facilement décodable. De plus, les objets Secret Kubernetes sont stockés en clair sur les nœuds du cluster, ce qui peut les rendre vulnérables à des attaques.

Une meilleure solution pour stocker les informations sensibles dans Kubernetes est d’utiliser des solutions de gestion des secrets telles que HashiCorp Vault, CyberArk Conjur ou Azure Key Vault. Ces solutions offrent un stockage sécurisé des secrets, ainsi que des fonctionnalités avancées telles que la rotation automatique des secrets et l’audit des accès.

Avec HashiCorp Vault, par exemple, vous pouvez stocker vos secrets dans Vault et utiliser un agent d’authentification Kubernetes pour récupérer les secrets en temps réel et les injecter dans vos pods. De cette manière, les secrets ne sont jamais stockés en clair sur les nœuds du cluster.

Voici un exemple de création et d’utilisation d’un secret avec HashiCorp Vault dans Kubernetes :

  1. Création d’un secret dans Vault :
bashCopy code$ vault kv put secret/wordpress-db-creds username=wordpress password=12345

Dans cet exemple, nous avons créé un secret Vault nommé wordpress-db-creds contenant un nom d’utilisateur et un mot de passe pour la base de données.

  1. Configuration de l’agent d’authentification Kubernetes pour Vault :
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp
automountServiceAccountToken: true
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
serviceAccountName: myapp
containers:
- name: myapp
image: myapp:latest
env:
- name: VAULT_ADDR
value: http://vault:8200
- name: VAULT_ROLE
value: myapp
- name: WORDPRESS_DB_USERNAME
valueFrom:
secretKeyRef:
name: myapp-vault-secrets
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: myapp-vault-secrets
key: password

Dans cet exemple, nous avons configuré un agent d’authentification Kubernetes pour Vault en créant un compte de service et en spécifiant son nom dans le déploiement de notre application. Les informations de connexion à Vault sont stockées dans les variables d’environnement VAULT_ADDR et VAULT_ROLE. Les informations de connexion à la base de données sont récupérées en temps réel à partir du secret myapp-vault-secrets créé dans Vault et injectées dans les variables d’environnement du conteneur.

Conclusion

En utilisant des solutions de gestion des secrets telles que HashiCorp Vault, vous pouvez stocker vos secrets de manière sécurisée et récupérer les informations de connexion en temps réel pour vos applications. Cela réduit considérablement le risque de compromission des informations sensibles dans votre environnement Kubernetes.

Pour en savoir plus sur la gestion des secrets dans Kubernetes, vous pouvez consulter les ressources suivantes :