Problème : "Je peux gérer toute la configuration de mon K8 dans git, sauf Secrets."
Solution : chiffrez votre secret dans un SealedSecret, qui peut être stocké en toute sécurité, même dans un référentiel public. Le SealedSecret ne peut être déchiffré que par le contrôleur exécuté dans le cluster cible et personne d'autre (pas même l'auteur d'origine) n'est en mesure d'obtenir le secret d'origine du SealedSecret.
Aperçu
SealedSecrets comme modèles de secrets
Clé publique / Certificat
Portées
Installation
Homebrew
MacPorts
Linux
Installation à partir des sources
Personnaliser
Tableau de barre
Contrôleur
Kubéseal
Mise à niveau
Usage
Gestion des secrets existants
Corriger les secrets existants
Mettre à jour les secrets existants
Mode brut (expérimental)
Valider un secret scellé
Rotation secrète
Renouvellement de la clé de scellement
Rotation du secret utilisateur
Renouvellement anticipé des clés
Idées fausses courantes sur le renouvellement des clés
Gestion manuelle des clés (avancé)
Rechiffrement (avancé)
Détails (avancé)
Cryptomonnaie
Développement
FAQ
Serez-vous toujours capable de décrypter si vous n'avez plus accès à votre cluster ?
Comment puis-je faire une sauvegarde de mes SealedSecrets ?
Puis-je décrypter mes secrets hors ligne avec une clé de sauvegarde ?
Quels drapeaux sont disponibles pour Kubeseal ?
Comment mettre à jour des parties d'un fichier JSON/YAML/TOML/.. chiffrées avec des secrets scellés ?
Puis-je apporter mes propres certificats (pré-générés) ?
Comment utiliser Kubeseal si le contrôleur ne s'exécute pas dans l'espace de noms kube-system
?
Comment vérifier les images ?
Comment utiliser un contrôleur pour un sous-ensemble d'espaces de noms
Puis-je configurer les tentatives de descellement du contrôleur
Communauté
Projets connexes
Sealed Secrets est composé de deux parties :
Un contrôleur/opérateur côté cluster
Un utilitaire côté client : kubeseal
L'utilitaire kubeseal
utilise un chiffrement asymétrique pour chiffrer les secrets que seul le contrôleur peut déchiffrer.
Ces secrets cryptés sont codés dans une ressource SealedSecret
, que vous pouvez considérer comme une recette pour créer un secret. Voici à quoi cela ressemble :
apiVersion : bitnami.com/v1alpha1kind : SealedSecretmetadata : nom : mysecret espace de noms : mynamespacespec :cryptedData : foo : AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Une fois descellé, cela produira un secret équivalent à celui-ci :
apiVersion : v1kind : Secretmetadata : nom : mysecret espace de noms : mynamespacedata : foo : YmFy # <- "bar" encodé en base64
Ce secret Kubernetes normal apparaîtra dans le cluster après quelques secondes, vous pourrez l'utiliser comme vous utiliseriez n'importe quel secret que vous auriez créé directement (par exemple, référencez-le à partir d'un Pod
).
Accédez à la section Installation pour être opérationnel.
La section Utilisation explore plus en détail la manière dont vous créez les ressources SealedSecret
.
L'exemple précédent se concentrait uniquement sur les éléments secrets chiffrés eux-mêmes, mais la relation entre une ressource personnalisée SealedSecret
et le Secret
dans lequel elle se descelle est similaire à bien des égards (mais pas dans tous) à la relation familière Deployment
vs Pod
.
En particulier, les annotations et les étiquettes d'une ressource SealedSecret
ne sont pas les mêmes que les annotations du Secret
qui en est généré.
Pour capturer cette distinction, l'objet SealedSecret
possède une section template
qui code tous les champs que vous souhaitez que le contrôleur mette dans le Secret
non scellé.
La bibliothèque de fonctions Sprig est disponible en plus des fonctions Go Text Template par défaut.
Le bloc metadata
est copié tel quel (le champ ownerReference
sera mis à jour sauf s'il est désactivé).
Les autres champs secrets sont traités individuellement. Les champs type
et immutable
sont copiés et le champ data
peut être utilisé pour modéliser des valeurs complexes sur le Secret
. Tous les autres champs sont actuellement ignorés.
apiVersion : bitnami.com/v1alpha1kind : SealedSecretmetadata : nom : espace de noms mysecret : annotations de mon espace de noms : "kubectl.kubernetes.io/last-applied-configuration" : ....spec : Données chiffrées : .dockerconfigjson : AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.... . template : tapez : kubernetes.io/dockerconfigjson immuable : true # ceci est un exemple d'étiquettes et d'annotations qui seront ajoutées aux métadonnées secrètes de sortie : labels : "jenkins.io/credentials-type": usernamePassword annotations : "jenkins. io/credentials-description » : informations d’identification de Kubernetes
Le contrôleur descellerait cela en quelque chose comme :
apiVersion : v1kind : Secretmetadata : nom : mysecret espace de noms : mynamespace étiquettes : "jenkins.io/credentials-type": usernamePassword annotations : "jenkins.io/credentials-description": informations d'identification du propriétaire de KubernetesRéférences : - apiVersion : bitnami.com/v1alpha1 contrôleur : vrai type : SealedSecret nom : mysecret uid : 5caff6a0-c9ac-11e9-881e-42010aac003etype : kubernetes.io/dockerconfigjsonimmutable : truedata : .dockerconfigjson : ewogICJjcmVk...
Comme vous pouvez le voir, la ressource Secret
générée est un « objet dépendant » de SealedSecret
et, en tant que telle, elle sera mise à jour et supprimée chaque fois que l'objet SealedSecret
sera mis à jour ou supprimé.
Le certificat de clé (partie de clé publique) est utilisé pour sceller les secrets et doit être disponible partout où kubeseal
sera utilisé. Le certificat n’est pas une information secrète, même si vous devez vous assurer que vous utilisez la bonne.
kubeseal
récupérera le certificat du contrôleur au moment de l'exécution (nécessite un accès sécurisé au serveur API Kubernetes), ce qui est pratique pour une utilisation interactive, mais il est connu pour être fragile lorsque les utilisateurs ont des clusters avec des configurations spéciales telles que des clusters GKE privés qui ont des pare-feu entre eux. plan de contrôle et nœuds.
Un flux de travail alternatif consiste à stocker le certificat quelque part (par exemple sur un disque local) avec kubeseal --fetch-cert >mycert.pem
et à l'utiliser hors ligne avec kubeseal --cert mycert.pem
. Le certificat est également imprimé dans le journal du contrôleur au démarrage.
Depuis la version 0.9.x, les certificats sont automatiquement renouvelés tous les 30 jours. Il est recommandé que vous et votre équipe mettiez régulièrement à jour votre certificat hors ligne. Pour vous aider, depuis la v0.9.2, kubeseal
accepte également les URL. Vous pouvez configurer votre automatisation interne pour publier des certificats dans un endroit de confiance.
kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert
Il reconnaît également la variable d'environnement SEALED_SECRETS_CERT
. (conseil de pro : voir aussi direnv).
REMARQUE : nous travaillons à fournir des mécanismes de gestion de clés qui déchargent le cryptage vers des modules basés sur HSM ou des solutions de cryptage cloud gérées telles que KMS.
Les SealedSecrets proviennent du POV d'un utilisateur final, un périphérique « en écriture seule ».
L'idée est que le SealedSecret ne peut être déchiffré que par le contrôleur exécuté dans le cluster cible et que personne d'autre (pas même l'auteur d'origine) ne peut obtenir le secret original du SealedSecret.
L'utilisateur peut ou non avoir un accès direct au cluster cible. Plus précisément, l'utilisateur peut avoir accès ou non au Secret descellé par le responsable du traitement.
Il existe de nombreuses façons de configurer RBAC sur les k8, mais il est assez courant d'interdire aux utilisateurs peu privilégiés de lire les secrets. Il est également courant de donner aux utilisateurs un ou plusieurs espaces de noms dans lesquels ils disposent de privilèges plus élevés, ce qui leur permettrait de créer et de lire des secrets (et/ou de créer des déploiements pouvant référencer ces secrets).
Les ressources cryptées SealedSecret
sont conçues pour pouvoir être consultées en toute sécurité sans avoir aucune connaissance des secrets qu'elles cachent. Cela implique que nous ne pouvons pas permettre aux utilisateurs de lire un SealedSecret destiné à un espace de noms auquel ils n'auraient pas accès et de simplement en placer une copie dans un espace de noms à partir duquel ils peuvent lire des secrets.
Sealed-secrets se comporte donc comme si chaque espace de noms avait sa propre clé de chiffrement indépendante et donc une fois que vous avez scellé un secret pour un espace de noms, il ne peut pas être déplacé dans un autre espace de noms et y être déchiffré.
Techniquement, nous n'utilisons pas de clé privée indépendante pour chaque espace de noms, mais nous incluons plutôt le nom de l'espace de noms pendant le processus de cryptage, obtenant ainsi le même résultat.
De plus, les espaces de noms ne sont pas le seul niveau auquel les configurations RBAC peuvent décider qui peut voir quel secret. En fait, il est possible que les utilisateurs puissent accéder à un secret appelé foo
dans un espace de noms donné mais pas à tout autre secret dans le même espace de noms. Nous ne pouvons donc pas, par défaut, laisser les utilisateurs renommer librement les ressources SealedSecret
sinon un utilisateur malveillant serait capable de déchiffrer n'importe quel SealedSecret pour cet espace de noms en le renommant simplement pour écraser le secret auquel l'utilisateur a accès. Nous utilisons le même mécanisme que celui utilisé pour inclure l'espace de noms dans la clé de chiffrement afin d'inclure également le nom secret.
Cela dit, il existe de nombreux scénarios dans lesquels ce niveau de protection ne vous intéresse peut-être pas. Par exemple, les seules personnes qui ont accès à vos clusters sont soit des administrateurs, soit elles ne peuvent lire aucune ressource Secret
. Vous pourriez avoir un cas d'utilisation pour déplacer un secret scellé vers d'autres espaces de noms (par exemple, vous ne connaissez peut-être pas le nom de l'espace de noms à l'avance), ou vous ne connaissez peut-être pas le nom du secret (par exemple, il pourrait contenir un suffixe unique basé sur le hachage du contenu, etc.).
Voici les portées possibles :
strict
(par défaut) : le secret doit être scellé avec exactement le même nom et le même espace de noms . Ces attributs font partie des données chiffrées et ainsi changer le nom et/ou l'espace de noms entraînerait une « erreur de décryptage ».
namespace-wide
: vous pouvez librement renommer le secret scellé dans un espace de noms donné.
cluster-wide
: le secret peut être descellé dans n'importe quel espace de noms et peut recevoir n'importe quel nom.
Contrairement aux restrictions de name et namespace , les éléments secrets (c'est-à-dire les clés d'objet JSON comme spec.encryptedData.my-key
) peuvent être renommés à volonté sans perdre la capacité de déchiffrer le secret scellé.
La portée est sélectionnée avec l'indicateur --scope
:
kubeseal --scope à l'échelle du clustersealed-secret.json
Il est également possible de demander une portée via des annotations dans le secret d'entrée que vous transmettez à kubeseal
:
sealedsecrets.bitnami.com/namespace-wide: "true"
-> pour namespace-wide
sealedsecrets.bitnami.com/cluster-wide: "true"
-> pour cluster-wide
L’absence de telles annotations signifie un mode strict
. Si les deux sont définis, cluster-wide
est prioritaire.
REMARQUE : la prochaine version consolidera cela en une seule annotation
sealedsecrets.bitnami.com/scope
.
Voir https://github.com/bitnami-labs/sealed-secrets/releases pour la dernière version et les instructions d'installation détaillées.
Notes et instructions spécifiques à la plateforme cloud :
GKE
Une fois que vous avez déployé le manifeste, il créera la ressource SealedSecret
et installera le contrôleur dans l'espace de noms kube-system
, créera un compte de service et les rôles RBAC nécessaires.
Après quelques instants, le contrôleur démarre, génère une paire de clés et est prêt à fonctionner. Si ce n'est pas le cas, vérifiez les journaux du contrôleur.
Le mécanisme d'installation officiel du manifeste du contrôleur n'est qu'un fichier YAML.
Dans certains cas, vous devrez peut-être appliquer vos propres personnalisations, comme définir un espace de noms personnalisé ou définir certaines variables d'environnement.
kubectl
a un support natif pour cela, voir kustomize.
Le graphique de barre Sealed Secrets est désormais officiellement pris en charge et hébergé dans ce dépôt GitHub.
le dépôt de barre ajoute des secrets scellés https://bitnami-labs.github.io/sealed-secrets
REMARQUE : Le schéma de version du graphique de barre diffère du schéma de version du projet de secrets scellés lui-même.
À l'origine, le graphique de barre était maintenu par la communauté et la première version adoptait une version majeure de 1 tandis que le projet de secrets scellés lui-même est toujours au niveau 0 majeur. Ce n'est pas grave car la version du graphique de barre lui-même n'est pas censée être nécessairement la version de l'application elle-même. Cependant, cela prête à confusion, donc notre règle de version actuelle est la suivante :
Le schéma de version du contrôleur SealedSecret
: 0.XY
Le schéma de version du diagramme de barre : 1.XY-rZ
Il peut ainsi y avoir plusieurs révisions du graphique de barre, avec des correctifs qui s'appliquent uniquement au graphique de barre sans affecter les manifestes YAML statiques ou l'image du contrôleur elle-même.
REMARQUE : Le fichier Lisez-moi du graphique de barre contient toujours un avis de dépréciation, mais il ne reflète plus la réalité et sera supprimé lors de la prochaine version.
REMARQUE : Le graphique de barre installe par défaut le contrôleur portant le nom
sealed-secrets
, tandis que l'interface de ligne de commande (CLI)kubeseal
tente d'accéder au contrôleur portant le nomsealed-secrets-controller
. Vous pouvez transmettre explicitement--controller-name
à la CLI :
kubeseal --nom-contrôleur scellé-secrets
Vous pouvez également définir fullnameOverride
lors de l’installation du graphique pour remplacer le nom. Notez également que kubeseal
suppose que le contrôleur est installé par défaut dans l'espace de noms kube-system
. Donc, si vous souhaitez utiliser la CLI kubeseal
sans avoir à transmettre le nom du contrôleur et l'espace de noms attendus, vous devez installer le Helm Chart comme ceci :
helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets
Dans certaines entreprises, vous pouvez avoir accès uniquement à un seul espace de noms, et non à un cluster complet.
L’un des environnements les plus restrictifs que vous puissiez rencontrer est :
Un namespace
vous a été attribué avec un service account
.
Vous n'avez pas accès au reste du cluster, pas même aux CRD du cluster.
Vous ne pourrez peut-être même pas créer d'autres comptes de service ou rôles dans votre espace de noms.
Vous devez inclure des limites de ressources dans tous vos déploiements.
Même avec ces restrictions, vous pouvez toujours installer le Helm Chart à secrets scellés, il n'y a qu'un seul pré-requis :
Le cluster doit déjà avoir les CRD de secrets scellés installés .
Une fois que vos administrateurs ont installé les CRD, s'ils n'y étaient pas déjà, vous pouvez installer le graphique en préparant un fichier de configuration YAML tel que celui-ci :
compte de service : créer : faux nom : {compte-de-service-alloué} rbac : créer : faux clusterRole : falseresources : limites : processeur : 150 m mémoire: 256Mi
Noter que:
Aucun compte de service n'est créé, mais celui qui vous est attribué sera utilisé.
{allocated-service-account}
est le nom du service account
qui vous a été attribué sur le cluster.
Aucun rôle RBAC n'est créé ni dans l'espace de noms ni dans le cluster.
Les limites des ressources doivent être précisées.
Les limites sont des exemples qui devraient fonctionner, mais vous souhaiterez peut-être les examiner dans votre configuration particulière.
Une fois que ce fichier est prêt, si vous l'avez nommé config.yaml
vous pouvez maintenant installer les secrets scellés Helm Chart comme ceci :
helm install scellé-secrets -n {espace de noms alloué} scellé-secrets/sealed-secrets --skip-crds -f config.yaml
Où {allocated-namespace}
est le nom de l' namespace
qui vous a été alloué dans le cluster.
Le client kubeseal
est également disponible sur homebrew :
infuser installer Kubeseal
Le client kubeseal
est également disponible sur MacPorts :
installation du port kubeseal
Le client kubeseal
est également disponible sur Nixpkgs : ( AVIS DE NON-RESPONSABILITÉ : Non maintenu par bitnami-labs)
nix-env -iA nixpkgs.kubeseal
Le client kubeseal
peut être installé sous Linux à l'aide des commandes ci-dessous :
KUBESEAL_VERSION='' # Définissez ceci sur, par exemple, KUBESEAL_VERSION='0.23.0'curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?} /kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
Si curl
et jq
sont installés sur votre machine, vous pouvez obtenir la version dynamiquement de cette façon. Cela peut être utile pour les environnements utilisés dans l'automatisation et autres.
# Fetch the latest sealed-secrets version using GitHub API KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-) # Check if the version was fetched successfully if [ -z "$KUBESEAL_VERSION" ]; then echo "Failed to fetch the latest KUBESEAL_VERSION" exit 1 fi curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz" tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
où KUBESEAL_VERSION
est la balise de version de la version de Kubeseal que vous souhaitez utiliser. Par exemple : v0.18.0
.
Si vous souhaitez simplement le dernier outil client, il peut être installé dans $GOPATH/bin
avec :
allez installer github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main
Vous pouvez spécifier une balise de version ou un commit SHA au lieu de main
.
La commande go install
placera le binaire kubeseal
à $GOPATH/bin
:
$(aller env GOPATH)/bin/kubeseal
N'oubliez pas de consulter les notes de version pour obtenir des conseils sur d'éventuelles modifications avec rupture lorsque vous mettez à niveau l'outil client et/ou le contrôleur.
Actuellement, seule la dernière version de Sealed Secrets est prise en charge pour les environnements de production.
Le contrôleur Sealed Secrets assure la compatibilité avec les différentes versions de Kubernetes en s'appuyant sur une API Kubernetes stable. En règle générale, les versions de Kubernetes supérieures à 1.16 sont considérées comme compatibles. Cependant, nous prenons officiellement en charge les versions Kubernetes actuellement recommandées. De plus, les versions supérieures à 1.24 sont soumises à une vérification approfondie via notre processus CI à chaque version.
# Créez d'une manière ou d'une autre un secret codé en json/yaml :# (notez l'utilisation de `--dry-run` - ce n'est qu'un fichier local !)echo -n bar | kubectl crée un secret générique mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json# C'est le bit important :kubeseal -f mysecret.json -w mysealedsecret.json# À ce stade, mysealedsecret.json peut être téléchargé en toute sécurité sur Github, # publier sur Twitter, etc. # Finalement : kubectl create -f mysealedsecret.json# Profit ! Kubectl obtient le secret mysecret
Notez que SealedSecret
et Secret
doivent avoir le même espace de noms et le même nom . Il s'agit d'une fonctionnalité permettant d'empêcher d'autres utilisateurs du même cluster de réutiliser vos secrets scellés. Voir la section Portées pour plus d'informations.
kubeseal
lit l'espace de noms à partir du secret d'entrée, accepte un argument --namespace
explicite et utilise l'espace de noms par défaut kubectl
(dans cet ordre). Toutes les étiquettes, annotations, etc. sur le Secret
d'origine sont conservées, mais ne sont pas automatiquement reflétées dans le SealedSecret
.
De par sa conception, ce schéma n'authentifie pas l'utilisateur . En d’autres termes, n’importe qui peut créer un SealedSecret
contenant n’importe quel Secret
de son choix (à condition que l’espace de noms/le nom correspondent). Il appartient à votre flux de travail de gestion de configuration existant, aux règles RBAC du cluster, etc. de garantir que seul le SealedSecret
prévu est téléchargé sur le cluster. Le seul changement par rapport à Kubernetes existant est que le contenu du Secret
est désormais masqué en dehors du cluster.
Si vous souhaitez que le contrôleur Sealed Secrets gère un Secret
existant, vous pouvez annoter votre Secret
avec l'annotation sealedsecrets.bitnami.com/managed: "true"
. Le Secret
existant sera écrasé lors de la descellement d'un SealedSecret
portant le même nom et le même espace de noms, et le SealedSecret
deviendra propriétaire du Secret
(de sorte que lorsque le SealedSecret
sera supprimé, le Secret
sera également supprimé).
Nouveau dans la v0.23.0
Il existe certains cas d'utilisation dans lesquels vous ne souhaitez pas remplacer l'intégralité Secret
mais simplement ajouter ou modifier certaines clés du Secret
existant. Pour cela, vous pouvez annoter votre Secret
avec sealedsecrets.bitnami.com/patch: "true"
. L'utilisation de cette annotation garantira que les clés secrètes, les étiquettes et les annotations du Secret
qui ne sont pas présentes dans le SealedSecret
ne seront pas supprimées, et que celles présentes dans le SealedSecret
seront ajoutées au Secret
(les clés secrètes, les étiquettes et les annotations qui existent à la fois dans le Secret
et dans le SealedSecret
seront modifiés par le SealedSecret
).
Cette annotation n'oblige pas SealedSecret
à s'approprier le Secret
. Vous pouvez ajouter à la fois le patch
et les annotations managed
pour obtenir le comportement de correctif tout en devenant également propriétaire du Secret
.
Si vous voulez que SealedSecret
et le Secret
soient indépendants, ce qui signifie que lorsque vous supprimez le SealedSecret
le Secret
ne disparaîtra pas avec lui, alors vous devez annoter ce Secret avec l'annotation sealedsecrets.bitnami.com/skip-set-owner-references: "true"
avant d'appliquer les étapes d'utilisation. Vous pouvez toujours ajouter sealedsecrets.bitnami.com/managed: "true"
à votre Secret
afin que votre secret soit mis à jour lorsque SealedSecret
est mis à jour.
Si vous souhaitez ajouter ou mettre à jour des secrets scellés existants sans avoir le texte en clair pour les autres éléments, vous pouvez simplement copier et coller les nouveaux éléments de données cryptés et les fusionner dans un secret scellé existant.
Vous devez veiller à sceller les éléments mis à jour avec un nom et un espace de noms compatibles (voir la note sur les étendues ci-dessus).
Vous pouvez utiliser la commande --merge-into
pour mettre à jour un secret scellé existant si vous ne souhaitez pas copier-coller :
echo -n barre | kubectl crée un secret générique mysecret --dry-run=client --from-file=foo=/dev/stdin -o json | kubeseal > mysealedsecret.jsonecho -n baz | kubectl crée un secret générique mysecret --dry-run=client --from-file=bar=/dev/stdin -o json | kubeseal --merge-into mysealedsecret.json
Créer un secret temporaire avec la commande kubectl
, pour ensuite le jeter une fois transmis à kubeseal
peut être une expérience utilisateur assez peu conviviale. Nous travaillons sur une refonte de l'expérience CLI. En attendant, nous proposons un mode alternatif dans lequel Kubeseal se soucie uniquement de chiffrer une valeur sur stdout, et il est de votre responsabilité de la placer dans une ressource SealedSecret
(un peu comme les autres ressources k8s).
Il peut également être utile comme élément de base pour les intégrations éditeur/IDE.
L’inconvénient est qu’il faut faire attention à être cohérent avec la portée du scellement, l’espace de noms et le nom.
Voir les étendues
portée strict
(par défaut) :
$ echo -n foo | kubeseal --raw --namespace bar --name mysecretAgBChHUWLMx...
portée namespace-wide
:
$ echo -n foo | kubeseal --raw --namespace bar --scope namespace-wideAgAbbFNkM54...
Incluez l'annotation sealedsecrets.bitnami.com/namespace-wide
dans SealedSecret
métadonnées : annotations : scellésecrets.bitnami.com/namespace-wide : "true"
portée cluster-wide
:
$ echo -n foo | kubeseal --raw --scope cluster-wideAgAjLKpIYV+...
Incluez l'annotation sealedsecrets.bitnami.com/cluster-wide
dans SealedSecret
métadonnées : annotations : scellésecrets.bitnami.com/cluster-wide : "true"
Si vous souhaitez valider un secret scellé existant, kubeseal
a l'indicateur --validate
pour vous aider.
Donner un fichier nommé sealed-secrets.yaml
contenant le secret scellé suivant :
apiVersion : bitnami.com/v1alpha1kind : SealedSecretmetadata : nom : mysecret espace de noms : mynamespacespec :cryptedData : foo : AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Vous pouvez valider si le secret scellé a été correctement créé ou non :
$ chat scellé-secrets.yaml | kubeseal --valider
En cas de secret scellé invalide, kubeseal
affichera :
$ chat scellé-secrets.yaml | kubeseal --validateerror : impossible de déchiffrer le secret scellé
Vous devriez toujours alterner vos secrets. Mais comme vos secrets sont chiffrés avec un autre secret, vous devez comprendre le lien entre ces deux couches pour prendre les bonnes décisions.
TL;DR :
Si une clé privée de scellement est compromise, vous devez suivre les instructions ci-dessous dans la section « Renouvellement anticipé de la clé » avant de procéder à la rotation de l'une de vos valeurs secrètes réelles.
Les fonctionnalités de renouvellement et de rechiffrement des clés SealedSecret ne remplacent pas la rotation périodique de vos valeurs secrètes réelles.
Les clés de plombage sont automatiquement renouvelées tous les 30 jours. Cela signifie qu'une nouvelle clé de scellement est créée et ajoutée à l'ensemble de clés de scellement actives que le contrôleur peut utiliser pour desceller les ressources SealedSecret
.
La clé de scellement la plus récemment créée est celle utilisée pour sceller les nouveaux secrets lorsque vous utilisez kubeseal
et c'est celle dont le certificat est téléchargé lorsque vous utilisez kubeseal --fetch-cert
.
Le délai de renouvellement de 30 jours est une valeur par défaut raisonnable, mais il peut être modifié si nécessaire avec l'indicateur --key-renew-period=
pour la commande dans le modèle de pod du contrôleur SealedSecret
. Le champ value
peut être donné sous forme d'indicateur de durée Golang (par exemple : 720h30m
). En supposant que vous avez installé Sealed Secrets dans l'espace de noms kube-system
, utilisez la commande suivante pour modifier le contrôleur de déploiement et ajoutez le paramètre --key-renew-period
. Une fois que vous fermez votre éditeur de texte et que le contrôleur de déploiement a été modifié, un nouveau Pod sera automatiquement créé pour remplacer l'ancien Pod.
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
Une valeur de 0
désactivera le renouvellement automatique de la clé. Bien sûr, vous pouvez avoir un cas d'utilisation valable pour désactiver le renouvellement automatique des clés de scellement, mais l'expérience a montré que les nouveaux utilisateurs ont souvent tendance à conclure hâtivement qu'ils veulent contrôler le renouvellement des clés, avant de comprendre pleinement comment fonctionnent les secrets scellés. Apprenez-en davantage à ce sujet dans la section sur les idées fausses courantes ci-dessous.
Malheureusement, vous ne pouvez pas utiliser par exemple "d" comme unité pendant des jours car cela n'est pas pris en charge par Go stdlib. Au lieu de vous frapper le visage avec la paume de la main, profitez-en pour méditer sur les mensonges que les programmeurs croient à propos du temps.
Un malentendu courant est que le renouvellement de clé est souvent considéré comme une forme de rotation de clé, où l'ancienne clé est non seulement obsolète mais en réalité mauvaise et que vous souhaitez donc vous en débarrasser. Le fait que cette fonctionnalité ait été historiquement appelée « rotation des clés », ce qui peut ajouter à la confusion, n'aide pas.
Les secrets scellés ne sont pas automatiquement alternés et les anciennes clés ne sont pas supprimées lorsque de nouvelles clés sont générées. Les anciennes ressources SealedSecret
peuvent toujours être déchiffrées (car les anciennes clés de scellement ne sont pas supprimées).
Le renouvellement de la clé de scellement et la rotation SealedSecret ne remplacent pas la rotation de vos secrets réels.
Une proposition de valeur fondamentale de cet outil est :
Chiffrez votre secret dans un SealedSecret, qui peut être stocké en toute sécurité, même dans un référentiel public.
Si vous stockez quoi que ce soit dans un stockage de contrôle de version, et dans un stockage public en particulier, vous devez supposer que vous ne pourrez jamais supprimer ces informations.
Si une clé de scellement s'échappe du cluster, vous devez considérer toutes vos ressources SealedSecret
chiffrées avec cette clé comme compromises. Aucune rotation des clés de scellement dans le cluster ni même le rechiffrement des fichiers SealedSecrets existants ne peuvent changer cela.
La meilleure pratique consiste à alterner périodiquement tous vos secrets réels (par exemple, changer le mot de passe) et à créer de nouvelles ressources SealedSecret
avec ces nouveaux secrets.
Mais si le contrôleur SealedSecret
ne renouvelait pas la clé de scellement, cette rotation serait sans objet, puisque l'attaquant pourrait également simplement déchiffrer les nouveaux secrets. Ainsi, vous devez faire les deux : renouveler périodiquement la clé de scellement et faire pivoter vos secrets actuels !
Si vous savez ou soupçonnez qu'une clé de scellement a été compromise, vous devez la renouveler dès que possible avant de commencer à sceller vos nouveaux secrets en rotation, sinon vous donnerez également aux attaquants l'accès à vos nouveaux secrets.
Une clé peut être générée tôt en transmettant l'horodatage actuel au contrôleur dans un indicateur appelé --key-cutoff-time
ou une variable d'environnement appelée SEALED_SECRETS_KEY_CUTOFF_TIME
. Le format attendu est RFC1123, vous pouvez le générer avec la commande unix date -R
.
Les clés de scellement des secrets scellés ne sont pas des clés de contrôle d'accès (par exemple un mot de passe). Ils ressemblent davantage à la clé GPG que vous pourriez utiliser pour lire le courrier crypté qui vous est envoyé. Continuons un peu avec l'analogie avec le courrier électronique :
Imaginez que vous ayez des raisons de croire que votre clé privée GPG a pu être compromise. Vous auriez plus à perdre qu'à gagner si la première chose à faire était simplement de supprimer votre clé privée. Tous les e-mails précédents envoyés avec cette clé ne vous sont plus accessibles (sauf si vous disposez d'une copie déchiffrée de ces e-mails), pas plus que les nouveaux e-mails envoyés par vos amis à qui vous n'avez pas encore réussi à dire d'utiliser la nouvelle clé.
Bien sûr, le contenu de ces e-mails cryptés n'est pas sécurisé, car un attaquant pourrait désormais les déchiffrer, mais ce qui est fait est fait. Votre perte soudaine de la capacité de lire ces e-mails ne répare sûrement pas les dégâts. Au contraire, c'est pire parce que vous ne savez plus avec certitude quel secret l'attaquant a appris. Ce que vous voulez vraiment faire, c'est vous assurer que votre ami cesse d'utiliser votre ancienne clé et qu'à partir de maintenant, toutes les communications ultérieures sont cryptées avec une nouvelle paire de clés (c'est-à-dire que votre ami doit connaître cette nouvelle clé).
La même logique s’applique à SealedSecrets. Le but ultime est de sécuriser vos véritables secrets « d'utilisateur ». Les secrets de « scellement » ne sont qu’un mécanisme, une « enveloppe ». Si un secret est divulgué, il n'y a pas de retour possible, ce qui est fait est fait.
Vous devez d'abord vous assurer que les nouveaux secrets ne sont pas chiffrés avec cette ancienne clé compromise (dans l'analogie du courrier électronique ci-dessus : créez une nouvelle paire de clés et donnez à tous vos amis votre nouvelle clé publique).
La deuxième étape logique consiste à neutraliser les dégâts, qui dépendent de la nature du secret. Un exemple simple est un mot de passe de base de données : si vous divulguez accidentellement le mot de passe de votre base de données, la chose que vous êtes censé faire est simplement de changer votre mot de passe de base de données (sur la base de données ; et de révoquer l'ancien !) et de mettre à jour la ressource SealedSecret
avec le nouveau mot de passe (c'est-à-dire exécuter à nouveau kubeseal
).
Les deux étapes sont décrites dans les sections précédentes, quoique de manière moins verbeuse. Il n’y a aucune honte à les relire, maintenant que vous avez une compréhension plus approfondie de la logique sous-jacente.
Le contrôleur SealedSecret
et le flux de travail associé sont conçus pour conserver les anciennes clés de scellement et en ajouter périodiquement de nouvelles. Vous ne devez pas supprimer les anciennes clés à moins de savoir ce que vous faites.
Cela dit, si vous le souhaitez, vous pouvez gérer manuellement (créer, déplacer, supprimer) les clés de scellement . Ce ne sont que des secrets k8 normaux vivant dans le même espace de noms où réside le contrôleur SealedSecret
(généralement kube-system
, mais il est configurable).
Il existe des cas d'utilisation avancés que vous pouvez résoudre par une gestion créative des clés de scellement. Par exemple, vous pouvez partager la même clé de scellement entre quelques clusters afin de pouvoir appliquer exactement le même secret scellé dans plusieurs clusters. Étant donné que les clés de scellement ne sont que des secrets k8 normaux, vous pouvez même utiliser les secrets scellés eux-mêmes et utiliser un workflow GitOps pour gérer vos clés de scellement (utile lorsque vous souhaitez partager la même clé entre différents clusters) !
L'étiquetage d'une clé de scellement secrète avec autre chose active
supprime effectivement la clé du contrôleur SealedSecret
, mais elle est toujours disponible dans les k8 pour un cryptage/déchiffrement manuel si nécessaire.
REMARQUE Le contrôleur SealedSecret
ne récupère pas automatiquement les clés de scellement créées manuellement, supprimées ou réétiquetées. Un administrateur doit redémarrer le contrôleur avant que l'effet ne s'applique.
Avant de pouvoir vous débarrasser de certaines anciennes clés de scellement, vous devez chiffrer à nouveau vos SealedSecrets avec la dernière clé privée.
kubeseal --re-encrypttmp.json && mv tmp.json my_sealed_secret.json
L'invocation ci-dessus produira un nouveau fichier secret scellé fraîchement chiffré avec la dernière clé, sans que les secrets ne quittent le cluster pour le client. Vous pouvez ensuite enregistrer ce fichier dans votre système de contrôle de version ( kubeseal --re-encrypt
ne met pas à jour l'objet du cluster).
Actuellement, les anciennes clés ne sont pas automatiquement récupérées.
C'est une bonne idée de recrypter périodiquement vos SealedSecrets. Mais comme mentionné ci-dessus, ne vous laissez pas berner par un faux sentiment de sécurité : vous devez supposer que l'ancienne version de la ressource SealedSecret
(celle chiffrée avec une clé que vous considérez comme morte) est toujours potentiellement disponible et accessible aux attaquants. Autrement dit, le recryptage ne remplace pas la rotation périodique de vos secrets réels.
Ce contrôleur ajoute une nouvelle ressource personnalisée SealedSecret
. La partie intéressante d’un SealedSecret
est un Secret
crypté asymétriquement codé en base64.
Le contrôleur conserve un ensemble de paires de clés privées/publiques en tant que secrets Kubernetes. Les clés sont étiquetées avec sealedsecrets.bitnami.com/sealed-secrets-key
et identifiées sur l'étiquette comme étant active
ou compromised
. Au démarrage, le contrôleur de secrets scellés va...
Recherchez ces clés et ajoutez-les à son magasin local si elles sont étiquetées comme actives.
Créer une nouvelle clé
Démarrer le cycle de rotation des clés
Plus de détails sur la crypto peuvent être trouvés ici.
L'élaboration de directives peut être trouvée dans le guide du développeur.
Oui, vous pouvez ! Déposez autant de secrets que vous le souhaitez dans un seul fichier. Assurez-vous de les séparer via ---
pour YAML et en tant qu'objets uniques supplémentaires dans JSON.
Non, les clés privées ne sont stockées que dans le secret géré par le contrôleur (sauf si vous avez une autre sauvegarde de vos objets K8S). Il n'y a pas de déchets - sans cette clé privée utilisée pour crypter un scelledsecrets donné, vous ne pouvez pas le déchiffrer. Si vous ne pouvez pas accéder aux secrets avec les clés de cryptage, et que vous ne pouvez pas non plus accéder aux versions déchiffrées de vos secrets vivent dans le cluster, vous devrez régénérer de nouveaux mots de passe pour tout, sceller à nouveau avec un nouveau clé d'étanchéité, etc.
Si vous souhaitez faire une sauvegarde des clés privées de chiffrement, il est facile à faire à partir d'un compte avec un accès approprié:
Kubectl Get Secret -n Kube-System -l scelledsecrets.bitnami.com/sealed-secrets-key -o yaml> main.keyecho "---" >> main.key Kubectl Get Secret -N Kube-System scellé-secrets-key -o yaml >> main.key
Remarque: vous avez besoin de la deuxième instruction uniquement si vous avez déjà installé des secrets scellés plus anciens que la version 0.9.x sur votre cluster.
Remarque: Ce fichier contiendra les clés publiques + privés du contrôleur et doit être conservé OMG-SAFE!
Remarque: Après avoir scellé le renouvellement clé, vous devez recréer votre sauvegarde. Sinon, votre sauvegarde ne pourra pas déchiffrer de nouveaux secrets scellés.
Pour restaurer une sauvegarde après une catastrophe, il suffit de remettre ces secrets avant de démarrer le contrôleur - ou si le contrôleur a déjà été démarré, remplacez les secrets nouvellement créés et redémarrez le contrôleur:
Pour le déploiement de la barre:
kubectl appliquer -f main.key kubectl delete pod -n kube-system -l app.kubernetes.io/name=seled-secrets
Pour le déploiement via controller.yaml
Manifest
kubectl appliquer -f main.key kubectl delete pod -n kube-system -l name = scelled-secrets-contrôleur
Bien que le traitement des secrets scellés comme le système de stockage à long terme pour les secrets ne soit pas le cas d'utilisation recommandé, certaines personnes ont une exigence légitime pour pouvoir récupérer des secrets lorsque le cluster K8S est en panne et rétablit une sauvegarde dans un nouveau déploiement de contrôleur SealedSecret
n'est pas pratique.
Si vous avez sauvegardé une ou plusieurs de vos clés privées (voir la question précédente), vous pouvez utiliser le kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...
Commande pour décrypter un Fichier de secrets scellés.
Vous pouvez vérifier les drapeaux disponibles à l'aide kubeseal --help
.
Une ressource Secret
Kubernetes contient plusieurs éléments, essentiellement une carte plate des paires de clés / valeur. ScelledSecrets fonctionne à ce niveau et ne se soucie pas de ce que vous mettez dans les valeurs. En d'autres termes, il ne peut pas comprendre aucun fichier de configuration structuré que vous pourriez avoir mis en secret et ne peut donc pas vous aider à mettre à jour les champs individuels.
Étant donné qu'il s'agit d'un problème courant, en particulier lorsque vous traitez des applications héritées, nous offrons un exemple de solution de contournement possible.
Oui, vous pouvez fournir au contrôleur vos propres certificats, et il les consommera. Veuillez vérifier ici une solution de contournement.
kube-system
? Si vous avez installé le contrôleur dans un espace de noms différent de celui du kube-system
par défaut, vous devez fournir cet espace de noms à l'outil de ligne de commande kubeseal
. Il y a deux options:
Vous pouvez spécifier l'espace de noms via l'option de ligne de commande --controller-namespace
:
Kubeseeal - Controller-namespace scelled-secretsmysearedsecret.json
Via la variable d'environnement SEALED_SECRETS_CONTROLLER_NAMESPACE
:
exportation scelled_secrets_controller_namespace = scelled-secrets kubeseealmysearedsecret.json
Nos images sont signées à l'aide de cosign. Les signatures ont été enregistrées dans notre registre de conteneurs GitHub.
Les images jusqu'à et y compris V0.20.2 ont été signées à l'aide de Cosign V1. Les images plus récentes sont signées avec Cosign v2.
Il est assez simple de vérifier les images:
# Exporter le cosign_variable Configuration du GitHub Container Registry Signs pathExport cosign_repository = ghcr.io / bitnami-labs / scelled-secrets-contrôleur / signes # Vérifiez l'image téléchargée dans ghcrcosign vérifie -. IO / Bitnami-labs / scelled-secrets-contrôleur: le dernier # Vérifiez l'image téléchargée dans dockerhubcosign vérifiez --key .github / workflows / cosign.pub docker.io/bitnami/seled-secrets-controller:llatest
Si vous souhaitez utiliser un contrôleur pour plus d'un espace de noms, mais pas tous les espaces de noms, vous pouvez fournir des espaces de noms supplémentaires à l'aide de la ligne de commande Flag --additional-namespaces=
. Assurez-vous de fournir des rôles et des lieux de rôle appropriés dans les espaces de noms cibles, afin que le contrôleur puisse y gérer les secrets.
La réponse est oui, vous pouvez configurer le nombre de tentatives dans votre contrôleur à l'aide de l'indicateur --max-unseal-retries
. Cet drapeau vous permet de configurer le nombre de tentatives maximales pour uncellir vos secrets scellés.
# scellé-secrets sur Kubernetes Slack
Cliquez ici pour vous inscrire à l'organisation Kubernetes Slack.
kubeseal-convert
: https://github.com/eladleev/kubeseal-convert
Visual Studio Code Extension: https://marketplace.visualstudio.com/items?itemname=codecontemplator.kubeseal
WebSeAl: Génére des secrets dans le navigateur: https://socialgouv.github.io/webseal
Hybridencrypt TypeScript Implémentation: https://github.com/socialgouv/aes-gcm-rsa-oaep
[Dépracée] Opérateur de secrets scellés: https://github.com/disposab1e/sealed-secrets-opérator-helm