Les sealed secrets Kubernetes avec Kubeseal
Mise à jour :
Dans Kubernetes, la gestion des secrets est essentielle pour sécuriser les informations sensibles, comme les identifiants, les certificats ou les clés API. Cependant, les Secrets Kubernetes classiques présentent une faiblesse : ils sont stockés dans les manifests en base64, ce qui les rend vulnérables aux attaques et aux fuites d’informations.
Quelle solution pour sécuriser les secrets Kubernetes ?
Pour sécuriser ces secrets dans un dépôt Git, nous pouvons utiliser Sealed Secrets, une solution qui permet de chiffrer les secrets avant de les stocker. Cette approche offre plusieurs avantages :
- Stocker des secrets chiffrés en toute sécurité dans un dépôt Git, sans les exposer en clair.
- Appliquer les principes GitOps aux Secrets Kubernetes en versionnant et automatisant leur déploiement.
Qu’est-ce que Kubeseal ?
Kubeseal est un outil en ligne de commande qui fonctionne avec le contrôleur SealedSecrets déployé dans un cluster Kubernetes. Il permet de transformer un Secret Kubernetes classique en un SealedSecret, un objet Kubernetes chiffré qui ne peut être déchiffré que par le cluster lui-même.
Ce mécanisme repose sur une clé privée stockée dans le cluster et une clé publique utilisée pour chiffrer les secrets. Ainsi, même si un SealedSecret est exposé dans un dépôt Git, personne ne pourra le lire sans accéder à la clé privée du cluster.
Comment fonctionne un SealedSecret ?
Un SealedSecret est une ressource Kubernetes spéciale qui contient un secret chiffré. Il est composé de trois éléments principaux :
- Le secret chiffré : il est généré par kubeseal à partir d’un secret Kubernetes standard.
- La clé publique du cluster : utilisée pour chiffrer le secret, elle est disponible publiquement.
- Le contrôleur SealedSecrets : installé dans le cluster, il est responsable du déchiffrement des SealedSecrets et de leur conversion en Secrets Kubernetes utilisables par les pods.
Qu’est ce qu’un scope
Les scopes définissent où et comment un Sealed Secret peut être déchiffré dans Kubernetes. Il en existe trois :
1. Strict (par défaut) :
-
Le secret est lié à un nom et un namespace spécifiques.
-
Utilisation : Sécurité maximale, empêche tout déplacement ou renommage.
-
Commande :
Terminal window kubeseal --scope strict -f secret.yaml -o sealedsecret.yaml
2. Namespace-wide :
- Le secret peut être renommé mais reste limité à un namespace.
- Utilisation : Permet plus de flexibilité sans compromettre la séparation des espaces.
- Commande :
-
Terminal window kubeseal --scope namespace-wide -f secret.yaml -o sealedsecret.yaml
3. Cluster-wide :
-
Le secret peut être déchiffré dans tout le cluster, sans restriction de namespace.
-
Utilisation : Flexibilité maximale, mais sécurité réduite.
-
Commande :
Terminal window kubeseal --scope cluster-wide -f secret.yaml -o sealedsecret.yaml
Choisir le bon scope
Bien configurer le scope garantit une gestion sécurisée et efficace des secrets dans Kubernetes.
- Strict → Sécurité maximale, recommandé par défaut.
- Namespace-wide → Équilibre entre flexibilité et sécurité.
- Cluster-wide → À éviter sauf si nécessaire.
Comment installer Kubeseal ?
Avant de pouvoir utiliser Kubeseal et lex Sealed Secrets, il est nécessaire d’installer à la fois l’outil kubeseal sur votre machine et le contrôleur SealedSecrets dans votre cluster Kubernetes.
Prérequis
Avant de commencer, assurez-vous d’avoir les éléments suivants :
- Un cluster Kubernetes fonctionnel :
- Un cluster déjà existant.
- Un cluster local avec Minikube
- L’outil
kubectl
pour interagir avec le cluster :kubectl
est l’outil en ligne de commande qui permet de gérer un cluster Kubernetes.
Installation de l’outil kubeseal
L’outil kubeseal est un binaire en ligne de commande qui permet de chiffrer les secrets. Il doit être installé sur votre machine locale.
Avec Homebrew
Pour les utilisateurs de macOS, la méthode la plus simple est d’utiliser Homebrew :
brew install kubeseal
Avec asdf-vm
Si vous utilisez asdf-vm
, vous pouvez
installer kubeseal avec le plugin kubeseal
:
asdf plugin add kubesealasdf install kubeseal latestasdf set --home kubeseal latest
Sur Windows
Téléchargez le binaire depuis
GitHub ↗, puis
renommez-le en kubeseal.exe
et ajoutez-le à votre PATH.
Vérification de l’installation
Vérifiez l’installation avec :
kubeseal --version
kubeseal version: 0.28.0
Installation du contrôleur SealedSecrets dans Kubernetes
Le SealedSecrets Controller est un composant déployé dans Kubernetes. Il est responsable du déchiffrement automatique des Sealed Secrets en Secrets Kubernetes utilisables par vos applications.
Déployez le contrôleur avec Helm (recommandé) :
helm repo add bitnami https://charts.bitnami.com/bitnamihelm install sealed-secrets bitnami/sealed-secrets --namespace kube-system
Une fois l’installation terminée, vérifiez que le SealedSecrets Controller est bien en cours d’exécution :
kubectl get pods -n kube-system | grep sealed-secrets
sealed-secrets-7c69fdd76f-9zzkn 1/1 Running 0 12s
Vous devriez voir un pod sealed-secrets-controller
en statut Running comme
ci-dessus.
Vérification et récupération de la clé publique
Pour chiffrer les secrets, Kubeseal utilise une clé publique propre à votre cluster. Vous pouvez l’obtenir avec la commande suivante :
kubeseal --fetch-cert --controller-name=sealed-secrets --controller-namespace=kube-system > sealed-secrets.pem
Cette clé sera utilisée pour chiffrer les secrets et garantir qu’ils ne peuvent être déchiffrés que par le cluster.
Création et chiffrement d’un secret avec Kubeseal
Maintenant que Kubeseal et le SealedSecrets Controller sont installés, nous allons voir comment créer et chiffrer un Secret Kubernetes de manière sécurisée.
L’objectif est de générer un SealedSecret, qui pourra être stocké en toute sécurité dans un dépôt Git sans risquer d’exposer des données sensibles.
Création d’un Secret Kubernetes classique
Dans un premier temps, créons un Secret de manière classique avec kubectl
:
kubectl create secret generic monsecret \ --from-literal=username=admin \ --from-literal=password=SuperSecret123 \ -o yaml --dry-run=client > monsecret.yaml
Si vous ouvrez le fichier monsecret.yaml
, vous verrez quelque chose comme ceci
:
apiVersion: v1data: password: U3VwZXJTZWNyZXQxMjM= username: YWRtaW4=kind: Secretmetadata: creationTimestamp: null name: monsecret
Problème : Ce fichier YAML ne doit jamais être stocké en clair dans un dépôt Git, car n’importe qui pourrait décoder les valeurs Base64.
Chiffrement du Secret avec Kubeseal
Nous allons maintenant chiffrer ce Secret en utilisant Kubeseal.
kubeseal --controller-name=sealed-secrets --controller-namespace=kube-system --format=yaml < monsecret.yaml > monsealedsecret.yaml
Le fichier monsealedsecret.yaml
généré ressemblera à ceci :
---apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: creationTimestamp: null name: monsecret namespace: defaultspec: encryptedData: password: AgCOl5M++XUXQECHEdK7dCzpyZKZcohMHW9BGMpm4kLURx5Va7r6xY515hJkFPiNT/m9Wm9um5JgqSFWML2ETrceY8sfuRJwJtjwTgBQTTEj1qQpdeOfZ1aNxYyW7gZ8+kroQE4CH1uDLg7dYwSU1ujabqtX0tau0HIjjjAptMQG4iGP9YElSINkTEH2RPZ5dshSpLSIYl5liNtq9y4QPJX3Zp4MxPS0lSHwOdSxAznPr28rIwQxU3lHQOtD4GyhtPBNyz5gud9HVx23TQV8yPnAUqRd1+IiY0VDw0A7TQEUPArsjI5yLm4DeHFaGMi0H8V060SkLa9fKKbFx97Gng5+wx43b+ZoX4HtAKpnEz3LoBKSLzpGBU0gl0YFqxKeytGDuIlZwjgwVR44WPmeMr92CWYdOns/OuGLwaPyapMRlv2TT0I01du1sHq2yv+Ipp62Ttlls9OmLyCZBAnTuu4mW008FAeHiJeFMMINM0nRETowme8XAE1AoBESAvWmd9pUp71HYfO7BKxOZryJPWj47vAt/e2V54IYbwYiLKsRRMtpTv/zCxCwsJw/o+D/uDFmWp1zUe/uxA/fJoLGOdTHnrqxtqgC3CxQWajI9j6Dc6QBCjXvdwYX0YizOI7yxOiLNlGcaxqjt7q0cgIKtcwb2Sab7uUCf5tsSeqyoEITDroDKmAn88soEKvjxQU7XsxKfTuA1cdu+o3eipWcDw== username: AgA3OWGpwrAJC/v2ow/6OTyqMdqSBd9S0Jd8po7ZwIECPwD7kBnLkjg70xQmwAbhmpKPRQIe9KKX2x3o5Zj7vkeDxQ0G1sCHvFz8bEilxyf1Rkdc+r4pw8NZYzylXi3wCXQKh8EZcMygrvZSxIZyGAefgRhbtq6YhZirGcsPFUA/mGHLRv2nFoiW4pmNhE0jH6y73aQkJ1i1IdLUJPCZWTa4hXvHOX3lkTFsLRCExraB9znHNh2ZF1ZHSuxAiTRXplKs5epe3DPJnuS+kxOnCnMQr9KqnkU3m22NHpBl2ZwYaodemGnpo7f21JXwqeDB77oBP7/Gnmue4ZOtfsXJkxw4aGWAQAiGVCorxcmrGYrSA65tAWUUprHWqsoMdTa1mqWA2uPNOTwsKrUakLoiTOPWBPojSn4Smprihy9y4DtuIxHPKsS7rY3TcbrAOrDVWe4fkl3juqkfHviWrFK1cEM9/mdmL0pKsaAotfFOErO8UuwHKMp2d/wDtRTjBbOp9flQrnbR6FxAwx36NiXZErZV0+xjUvHhAny3ox3MJCF/Zomhup6q7rXH29shMuQpgmox6AigGvxousyy5jDQ43kwJQwhD83B8YeKsmjNJDM959BHlqZHQev9pLGG406SdhbdWtjd3khPLYri+++zlCvwI1wmzQYQIgiUP4j6ewy8PGvUfq0nZ1xqnG/iujHisEFYsPGM6g== template: metadata: creationTimestamp: null name: monsecret namespace: default
Avantage : Même si ce fichier est stocké dans un dépôt Git, il est totalement sécurisé, car seul le cluster Kubernetes qui possède la clé privée pourra le déchiffrer.
Déploiement du Sealed Secret dans Kubernetes
Appliquons maintenant ce Sealed Secret dans notre cluster :
kubectl apply -f monsealedsecret.yamlsealedsecret.bitnami.com/monsecret created
Vérifions qu’il a bien été pris en charge :
kubectl get sealedsecrets
Le SealedSecrets Controller va automatiquement convertir ce Sealed Secret en Secret Kubernetes standard.
Vérification et utilisation du Secret
Pour confirmer que le Secret est bien accessible aux pods, on peut le décoder :
kubectl get secret monsecret -o jsonpath="{.data.username}" | base64 --decode
Vous devriez voir admin
s’afficher. Faites de même avec le mot de passe :
kubectl get secret monsecret -o jsonpath="{.data.password}" | base64 --decode
Résultat : SuperSecret123
Gestion et mise à jour des SealedSecrets
Une fois un SealedSecret créé et déployé, il peut être nécessaire de le mettre à jour, de modifier ses valeurs ou encore de gérer la rotation des clés. Contrairement aux Secrets Kubernetes classiques, un SealedSecret ne peut pas être modifié directement dans le cluster. Toute modification requiert un chiffrement avec kubeseal avant d’être appliquée.
Modification d’un SealedSecret
Si tu veux modifier un SealedSecret (exemple : changer un mot de passe ou ajouter une nouvelle clé), il faut générer un nouveau SealedSecret en répétant le processus de chiffrement.
Étape 1 : Modifier le Secret en clair :
On commence par recréer le Secret Kubernetes en y ajoutant ou modifiant une valeur :
kubectl create secret generic monsecret \ --from-literal=username=admin \ --from-literal=password=NouveauMotDePasse2024 \ -o yaml --dry-run=client > monsecret.yaml
Étape 2 : Chiffrer à nouveau avec Kubeseal :
On chiffre ensuite le nouveau secret avec kubeseal :
kubeseal --format=yaml < monsecret.yaml > monsealedsecret.yaml
Étape 3 : Appliquer le nouveau SealedSecret :
On applique enfin la nouvelle version dans Kubernetes :
kubectl apply -f monsealedsecret.yaml
kubectl delete pod -l app=monapplication
Suppression sécurisée d’un SealedSecret
Si un SealedSecret n’est plus utilisé, il faut s’assurer de le supprimer proprement du cluster et du dépôt Git.
Étape 1 : Supprimer le SealedSecret dans Kubernetes :
kubectl delete sealedsecret monsecret
Étape 2 : Supprimer également le Secret déchiffré :
kubectl delete secret monsecret
Étape 3 : Nettoyer le dépôt Git :
Il est recommandé de supprimer également le SealedSecret du dépôt Git pour éviter toute confusion.
git rm monsealedsecret.yamlgit commit -m "Suppression du SealedSecret monsecret"git push origin main
Conclusion
La gestion des secrets est un élément fondamental de la sécurité dans Kubernetes. Grâce à Kubeseal et aux Sealed Secrets, nous pouvons stocker nos secrets chiffrés en toute sécurité dans un dépôt Git, tout en assurant qu’ils restent utilisables par nos applications Kubernetes.