Aller au contenu

Les sealed secrets Kubernetes avec Kubeseal

Mise à jour :

logo kubeseal

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 :

  1. Le secret chiffré : il est généré par kubeseal à partir d’un secret Kubernetes standard.
  2. La clé publique du cluster : utilisée pour chiffrer le secret, elle est disponible publiquement.
  3. 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 :

  1. Un cluster Kubernetes fonctionnel :
    • Un cluster déjà existant.
    • Un cluster local avec Minikube
  2. 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 :

Terminal window
brew install kubeseal

Avec asdf-vm

Si vous utilisez asdf-vm, vous pouvez installer kubeseal avec le plugin kubeseal :

Terminal window
asdf plugin add kubeseal
asdf install kubeseal latest
asdf 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 :

Terminal window
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é) :

Terminal window
helm repo add bitnami https://charts.bitnami.com/bitnami
helm 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 :

Terminal window
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 :

Terminal window
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 :

Terminal window
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: v1
data:
password: U3VwZXJTZWNyZXQxMjM=
username: YWRtaW4=
kind: Secret
metadata:
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.

Terminal window
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/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: monsecret
namespace: default
spec:
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 :

Terminal window
kubectl apply -f monsealedsecret.yaml
sealedsecret.bitnami.com/monsecret created

Vérifions qu’il a bien été pris en charge :

Terminal window
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 :

Terminal window
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 :

Terminal window
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 :

Terminal window
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 :

Terminal window
kubeseal --format=yaml < monsecret.yaml > monsealedsecret.yaml

Étape 3 : Appliquer le nouveau SealedSecret :

On applique enfin la nouvelle version dans Kubernetes :

Terminal window
kubectl apply -f monsealedsecret.yaml
Terminal window
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 :

Terminal window
kubectl delete sealedsecret monsecret

Étape 2 : Supprimer également le Secret déchiffré :

Terminal window
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.

Terminal window
git rm monsealedsecret.yaml
git 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.

Plus de ressources