Civil & Structural Engineering
Managing Docker Container Secrets with Hashicorp Vault
Table of Contents
Comprendre la nécessité d'une gestion secrète sécurisée à Docker
Les conteneurs ont transformé le déploiement d'applications en offrant des environnements légers et portables. Cependant, ce changement a amplifié le défi de gérer des données sensibles comme les clés API, les identifiants de base de données et les certificats TLS. Les secrets de codage dur dans les images Docker, les engageant à contrôler les versions, ou les faisant passer comme variables d'environnement simple introduit des risques de sécurité importants.
Qu'est-ce que la faille HashiCorp ?
HashiCorp Vault est un outil open-source conçu pour stocker et contrôler l'accès aux jetons, mots de passe, certificats et clés de chiffrement de manière sécurisée. Il offre une interface unifiée pour la gestion des secrets, le cryptage en tant que service et l'accès à base d'identité.
- Secrets dynamiques :[ Générer des références courtes et de portée sur demande (p. ex., un utilisateur de base de données avec un bail de 24 heures).
- Leasing and Renewal:[ Chaque secret a une durée de location; les demandes doivent renouveler ou réauthentifier, réduisant le rayon de blason d'un compromis.
- Révocation: Invalider instantanément les secrets si une application ou un utilisateur est compromis.
- Audit Logging: Consigner toutes les demandes d'accès, en fournissant une chaîne de garde claire.
- Encryptage comme service:[ Encrypter et déchiffrer les données sans exposer les clés aux applications.
Vault prend en charge plusieurs moteurs sécrétants[ (valeur clé, bases de données, ICP, transit, etc.) et méthodes d'authentification (jetons, AppRole, Kubernetes, LDAP, etc.), ce qui le rend adaptable à presque n'importe quelle infrastructure.
Pourquoi utiliser Vault avec Docker ?
L'intégration de la Vault avec les récipients Docker apporte plusieurs avantages par rapport aux méthodes d'injection secrète traditionnelles:
- Runtime Retrieval:[ Les secrets sont récupérés lorsque le conteneur commence ou sur demande, jamais cuit dans l'image. Cela élimine le risque de fuite de secrets par le biais des registres d'images.
- Gestion centralisée: Un seul cluster Vault gère les secrets de tous les services conteneurisés, réduisant la dérive de configuration et simplifiant la rotation.
- Les pouvoirs dynamiques:[ Chaque instance de conteneur peut recevoir des pouvoirs uniques et limités dans le temps.
- Straights de vérification:[ Chaque accès secret est enregistré, ce qui aide à satisfaire aux exigences de conformité (SOC 2, HIPAA, PCI DSS).
- Accès par politique: Les LCA à grain fin assurent que chaque conteneur ne voit que les secrets dont il a besoin (le moindre privilège).
Architecture de la faille HashiCorp pour les charges de travail de conteneurs
Avant de plonger dans l'intégration, il est utile de comprendre l'architecture de déploiement de Vault. Vault fonctionne comme un démon serveur avec un backend de stockage de valeurs-clés (Consul, etcd, Raft stockage intégré, ou stockage basé sur le cloud). Il expose une API HTTP RESTful.
Pour les environnements de conteneurs, Vault est souvent déployé de deux façons :
- Cluster serveur par défaut[ (production): Une commande de cluster hautement disponible, scellée/non scellée à partir de conteneurs multiples. Utilisez le stockage intégré Raft pour la simplicité ou Consul pour les déploiements plus importants.
- Vault Dev Server (développement): Une instance unique, in-memory avec auto-unseal. Idéal pour les tests locaux mais jamais pour la production.
Les conteneurs interagissent avec Vault par l'intermédiaire du Vault CLI, de l'API HTTP ou d'un agent de sidecar (Vault Agent) qui gère l'authentification et la récupération secrète automatiquement.
Intégration de la variole avec Docker: les motifs de base
Il existe plusieurs modèles éprouvés pour injecter des secrets de la faille dans des conteneurs Docker. Le choix dépend de votre couche d'orchestration et de la maturité opérationnelle.
1. Utilisation de la Vault CLI dans les scripts d'entrée
C'est le motif le plus simple. L'image du conteneur inclut le CLI Vault, et un script shell point d'entrée authentifie Vault, récupère les secrets et les injecte dans l'application comme variables d'environnement ou fichiers.
# Dockerfile
FROM alpine:latest
RUN apk add --no-cache vault ca-certificates
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# entrypoint.sh
#!/bin/sh
export VAULT_ADDR="http://vault.example.com:8200"
vault login -method=approle role_id="$ROLE_ID" secret_id="$SECRET_ID"
API_KEY=$(vault kv get -field=api_key secret/myapp)
export API_KEY
exec myapp
Le conteneur reçoit et comme variables d'environnement (ou via des fichiers montés).Cette approche exige que le conteneur ait un accès réseau à Vault et au binaire Vault complet, ce qui augmente la taille de l'image.
2. Sidecar de l'agent de la faute
Vault Agent est un démon qui peut authentifier, récupérer des secrets et les rendre dans des fichiers ou des modèles. Il prend en charge un sidecar pattern où l'agent court à côté du conteneur primaire dans le même pod (Kubernetes) ou Docker Compose service. L'agent renouvelle automatiquement les baux et gère la rotation secrète.
# config.hcl for Vault Agent
vault {
address = "http://vault.example.com:8200"
}
auto_auth {
method "approle" {
mount_path = "auth/approle"
config = {
role_id_file_path = "/tmp/role-id"
secret_id_file_path = "/tmp/secret-id"
}
}
}
template {
source = "/tmp/secrets.ctmpl"
destination = "/etc/secrets/app.env"
}
L'agent surveille le modèle pour les modifications et re-rend la sortie lorsque les secrets sont renouvelés. Cela découple la récupération secrète du code d'application.
Docker Swarm a un système secret intégré, mais le stockage des secrets dans les journaux de Swarm Raft peut ne pas répondre aux besoins de conformité. Un pilote secret de Vault tiers peut être utilisé pour router les demandes secrètes de Swarm vers Vault. Ceci est moins commun mais utile pour les organisations déjà investies dans Swarm.
4. Intégration de Kubernetes avec le pilote CSI
Pour les utilisateurs de Kubernetes, le Vault CSI Provider permet aux pods de monter des secrets Vault en volumes. Cela utilise l'interface de stockage de conteneurs (CSI) pour monter des secrets sans aucune modification d'application.
Méthodes d'authentification des conteneurs
Le choix de la bonne méthode d'authentification est essentiel pour la sécurité et l'automatisation.
- AppRole: Idéal pour l'automatisation. Le conteneur reçoit un et un (ce dernier peut être un jeton emballé ou un autre secret). Le conteneur échange ces deux éléments contre un jeton Vault.
- Kubernetes Auth: Lorsque vous utilisez Kubernetes, Vault peut authentifier les pods en vérifiant les jetons de compte de service. Aucune identificateur explicite ne doit être distribué.
- JWT/OIDC: Convient aux environnements de cloud-native où les conteneurs ont des jetons JWT d'un fournisseur d'identité de confiance.
- Token: Simple mais moins sûr. Les jetons peuvent être préconfigurés dans des pipelines CI/CD ou injectés par orchestration.
Les secrets dynamiques : le vrai pouvoir
L'une des caractéristiques les plus fortes de Vault , pour les charges de travail Docker, est les secrets dynamiques. Plutôt que de stocker des identifiants statiques dans le magasin de valeurs clés de Vault , Vault peut se connecter à une base de données (PostgreSQL, MySQL, MongoDB) et créer un utilisateur temporaire à la volée.
# Example: Enable PostgreSQL secrets engine
vault secrets enable database
vault write database/config/my-postgres-database \
plugin_name=postgresql-database-plugin \
allowed_roles="my-role" \
connection_url="postgresql://{{username}}:{{password}}@postgres.example.com:5432/myapp" \
username="vault_admin" \
password="super_secret"
vault write database/roles/my-role \
db_name=my-postgres-database \
creation_statements="CREATE USER \"{{name}}\" WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
Le conteneur demande alors un justificatif d'identité : . Cela renvoie un nom d'utilisateur/mot de passe unique valide pendant une heure. Aucune identification statique n'est stockée nulle part.
Meilleures pratiques pour Docker + Vault
- N'utilisez jamais de secrets de code dur dans les images. Utilisez l'injection d'exécution exclusivement.
- Chaque conteneur ou service ne devrait pouvoir lire que ses propres secrets et chemins.
- Préférence d'agent de défaillance ou de sidecars[ sur l'intégration de la Vault CLI dans les images. Il simplifie la gestion du cycle de vie et réduit la taille de l'image.
- ][[FLT]][[FLT]][FLT][FLT][FLT][FLT][FLT][FLT][FLT]][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][FLT][F][FLT][F][F]
- Activer l'enregistrement de vérification[ dans la faille et expédier les journaux vers un SIEM central.
- Secure Vault elle-même:[ Utiliser TLS pour toute communication, se déserrer via auto-unseal (KMS, cloud HSM), et restreindre l'accès réseau à Vault à seulement orchestres et conteneurs.
- Renouveau secret à la main gracieusement. Les applications devraient pouvoir rafraîchir les identifiants sans redémarrer.
- Test pour les scénarios de défaillance:[ Simuler les temps d'arrêt de la faille, les partitions réseau et l'expiration des jetons pour assurer que les applications se dégradent gracieusement.
- Utiliser des TTLs courts pour des secrets dynamiques et des jetons pour limiter l'exposition si un contenant est compromis.
- Considérer une couche de cache secrète[ (p. ex., cache Vault Agent) pour réduire la charge sur Vault et améliorer les performances pour les environnements à haute hauteur.
Comparaison avec les solutions de remplacement
Bien que Vault soit une solution de premier plan, il vaut la peine de comprendre comment il se compare à d'autres approches:
- Docker Native Secrets (Swarm): Simple mais limité à des secrets statiques, aucune génération dynamique, piste de vérification ou politiques à grain fin. Entreposé dans des journaux de Raft, qui ne peuvent pas satisfaire à une stricte conformité.
- Kubernetes Secrets: Les secrets statiques de base64 codés dans etcd. Sans chiffrement au repos (qui nécessite une configuration supplémentaire), ils peuvent être incertains. Aucune gestion centrale entre les clusters.
- Cloud Provider Secret Managers (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager): Bonne intégration avec leurs écosystèmes mais verrouillage.
- CyberArk Conjur[: Entreprise-axée, forte sur la gestion d'accès privilégié, mais plus complexe et coûteux que Vault pour les cas d'utilisation de conteneurs.
Vault établit un équilibre entre la flexibilité open-source, la richesse des fonctionnalités et le large support de la plateforme, ce qui en fait un choix populaire pour les déploiements multi-cloud et hybrides Docker.
Mise en place d'une faille de production pour Docker
- Déployer un cluster de faille hautement disponible : Utilisez le graphique officiel de Vault Helm sur Kubernetes, ou exécutez Vault en mode manuel HA avec stockage Raft. Assurez-vous qu'au moins trois nœuds.
- Configurer Auto-Unseal: Utilisez un cloud KMS (AWS KMS, Azure Key Vault, GCP Cloud KMS) ou HSM. Ne jamais stocker les clés de désenclavement dans le même cluster que Vault.
- Mécanismes de vérification : Envoyez des journaux de vérification à stdout et un magasin externe sécurisé.
- Set Up Politiques and Roles[: Créer des politiques pour chaque service (p. ex. ). Relier ces politiques à AppRole rôles ou Kubernetes comptes de service.
- Intégrer avec l'orchestration: Dans Kubernetes, installer le fournisseur de Vault CSI ou l'injecteur de Vault (s webhook de modification).
- Test Dynamic Secrets: Activez le moteur de secrets de base de données et créez des rôles. Vérifiez que les conteneurs peuvent demander et utiliser des identifiants temporaires.
- Intégration CI/CD d'application[: Dans votre pipeline, utilisez l'API Vault="s pour fournir des jetons temporaires pour chaque étape de construction, en évitant les identifiants statiques.
Considérations de sécurité au-delà du stockage secret
L'utilisation de Vault réduit le risque d'exposition secrète, mais n'élimine pas tous les vecteurs d'attaque :
- Sécurité du réseau[: Assurez-vous que la faille n'est pas exposée à l'Internet public.
- Provenance de l'image: Vérifiez que les images de base et les paquets tirés sont des registres de confiance. Une image compromise pourrait exfiltrer des secrets avant l'injection de Vault.
- Surveillance des temps d'arrêt: Utilisez des outils de sécurité de conteneurs (Falco, Tracee, AppArmor) pour détecter les exécutions inattendues de processus ou les accès de fichiers.
- Secret sprawl[: Même avec Vault, les développeurs peuvent toujours coder des secrets dans les fichiers d'environnement pour les tests locaux.
- Gestion des congés[ : Les demandes qui ne renouvellent pas les baux peuvent perdre l'accès à des moments critiques.
Cas d'utilisation réelle dans le monde: Microservices avec des lettres de créances de base de données
Considérez une plateforme de commerce électronique avec 20 microservices, chacun se connectant à une base de données spécifique PostgreSQL. Sans Vault, chaque service dispose d'un utilisateur/mot de passe de base de données codé en dur dans son manifeste de déploiement ou son image.
- Chaque service authentifie par AppRole ou Kubernetes auth.
- Tous les services demandent des identifiants de base de données dynamiques au démarrage.
- Les lettres de créances sont valables 1 heure et automatiquement renouvelées par Vault Agent.
- Si un service est compromis, l'exploitant annule tous ses baux actifs dans une seule commande.
- Les journaux de vérification des bases de données montrent des utilisateurs temporaires créés, réduisant le rayon de souffle de tout titre volé.
Ce modèle réduit les frais généraux opérationnels et améliore considérablement la posture de sécurité.
Pièges courants et comment les éviter
- Éviter de sceller/de sceller la faille:[ En production, Vault commence à sceller. Le déballage automatisé (par l'intermédiaire d'un scellement automatique) est essentiel.
- Exposer les jetons de la faille dans les journaux :[ Utiliser l'encart de réponse ou l'agent de la faille pour éviter les jetons apparaissant dans les journaux de conteneurs.
- Mixant des secrets statiques et dynamiques:[ Évitez de stocker des secrets statiques de longue durée dans le magasin KV Vault. Utilisez des secrets dynamiques lorsque c'est possible.
- Ne planifie pas les temps d'arrêt de la faille:[ Cache secrets avec cache TTL-aware, ou utiliser des sidecars qui peuvent servir des secrets inexistants temporairement.
- Une politique trop permissive :[ Une politique accordant à un conteneur frontend pourrait exposer les mots de passe de la base de données backend. Appliquer le moins de privilèges strictement.
Conclusion
L'intégration de HashiCorp Vault avec les conteneurs Docker est une pratique optimale pour toute organisation sérieuse en matière de sécurité, de conformité et d'efficacité opérationnelle. En passant des secrets statiques, codés en dur à un cycle de vie secret dynamique et géré centralement, vous réduisez les risques, simplifiez les rotations et obtenez une pleine auditabilité. Que vous utilisiez des sidecars d'agent, des scripts Kubernetes CSI ou des scripts d'entrée personnalisés, Vault fournit une base solide pour la gestion secrète dans les environnements conteneurisés.
Pour plus de détails, consulter la documentation officielle sur les failles[, la vue d'ensemble sur les secrets de la chasse et le guide sur les fournisseurs de services de police de la chasse.