Aller au contenu
Conteneurs & Orchestration medium

Les sealed secrets Kubernetes avec Kubeseal

11 min de lecture

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 ?

Section intitulée « 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.

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.

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.

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 :

    Fenêtre de terminal
    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 :
  • Fenêtre de terminal
    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 :

    Fenêtre de terminal
    kubeseal --scope cluster-wide -f secret.yaml -o sealedsecret.yaml

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.

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.

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.

L’outil kubeseal est un binaire en ligne de commande qui permet de chiffrer les secrets. Il doit être installé sur votre machine locale.

Pour les utilisateurs de macOS, la méthode la plus simple est d’utiliser Homebrew :

Fenêtre de terminal
brew install kubeseal

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

Fenêtre de terminal
asdf plugin add kubeseal
asdf install kubeseal latest
asdf set --home kubeseal latest

Téléchargez le binaire depuis GitHub, puis renommez-le en kubeseal.exe et ajoutez-le à votre PATH.

Vérifiez l’installation avec :

Fenêtre de terminal
kubeseal --version
kubeseal version: 0.28.0

Installation du contrôleur SealedSecrets dans Kubernetes

Section intitulée « 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é) :

Fenêtre de terminal
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 :

Fenêtre de terminal
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

Section intitulée « 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 :

Fenêtre de terminal
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

Section intitulée « 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.

Dans un premier temps, créons un Secret de manière classique avec kubectl :

Fenêtre de terminal
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.

Nous allons maintenant chiffrer ce Secret en utilisant Kubeseal.

Fenêtre de terminal
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.

Appliquons maintenant ce Sealed Secret dans notre cluster :

Fenêtre de terminal
kubectl apply -f monsealedsecret.yaml
sealedsecret.bitnami.com/monsecret created

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

Fenêtre de terminal
kubectl get sealedsecrets

Le SealedSecrets Controller va automatiquement convertir ce Sealed Secret en Secret Kubernetes standard.

Pour confirmer que le Secret est bien accessible aux pods, on peut le décoder :

Fenêtre de terminal
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 :

Fenêtre de terminal
kubectl get secret monsecret -o jsonpath="{.data.password}" | base64 --decode

Résultat : SuperSecret123

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.

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 :

Fenêtre de terminal
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 :

Fenêtre de terminal
kubeseal --format=yaml < monsecret.yaml > monsealedsecret.yaml

Étape 3 : Appliquer le nouveau SealedSecret :

On applique enfin la nouvelle version dans Kubernetes :

Fenêtre de terminal
kubectl apply -f monsealedsecret.yaml
Fenêtre de terminal
kubectl delete pod -l app=monapplication

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 :

Fenêtre de terminal
kubectl delete sealedsecret monsecret

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

Fenêtre de terminal
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.

Fenêtre de terminal
git rm monsealedsecret.yaml
git commit -m "Suppression du SealedSecret monsecret"
git push origin main

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.