HashiCorp Vault
Vault est un outil qui permet de stocker en toute sécurité vos secrets. Mais qu'est-ce qu'un secret ? Des secrets, ce sont toutes vos données dont vous souhaitez pouvoir contrôler étroitement leur accès en lecture, comme les clés d'API, les mots de passe, les certificats, etc.
Introduction
Vault fournit une interface permettant d'accéder à n'importe quel secret, tout en assurant un contrôle d'accès strict et en enregistrant un journal d'audit détaillé.
Qu'apporte Vault
Vault n'est pas qu'un simple stockage, il gère l'ensemble du cycle de vie de vos secrets :
Stockage sécurisé de secret : les secrets de clé/valeur peuvent être stockés dans Vault. Vault crypte ces secrets avant de les écrire dans le stockage persistant, donc accéder au stockage brut ne suffit pas pour accéder à vos secrets.
Secrets dynamiques : Vault peut générer des secrets à la demande pour certains systèmes, tels que les bases de données. Par exemple, Vault peut générer et révoquer également automatiquement vos certificats.
Chiffrement des données : Vault peut chiffrer et déchiffrer les données sans les stocker.
Location et renouvellement : tous les secrets de Vault sont associés à un bail. À la fin du bail, Vault révoquera automatiquement ces secrets.
Le concept de Vault
Hashicorp présente le concept de son produit vault avec une image sous la forme d'un triangle. On retrouve au sommet de ce triangle les clients ayant besoin d'accéder aux secrets et à la base les composants clés de vault. Parmi ces composants Vault on retrouve : les moteurs de secrets, les méthodes d'authentification et les policies.
Vault est livré avec un bon paquet de moteurs de secrets et de méthodes d'authentification.
Parmi les moteurs de secrets, on retrouve les secrets de type clés/valeurs, des PKI, des clés ssh, des bases de données, ....
Tester Vault
Si vous souhaitez tester Vault pas besoin de mettre en place tout une infra. Une simple machine Linux suffira. Il faut avant tout installer la dernièr versions de la cli Vault.
Installation de la CLI Vault
HashiCorp fournit des repos pour la plupart des distributions Linux. Pour installer la CLI il suffit d'ajouter le dépôt de package avec machine linux.
Sur une Debian Family
Ouvrez un terminal et tapez les commandes suivantes :
sudo apt update && sudo apt install gpg
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install vault
Sur des Red Hat
- Pour Centos/RHEL :
wget -O- https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo | sudo tee /etc/yum.repos.d/hashicorp.repo
- Pour Fedora :
wget -O- https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo | sudo tee /etc/yum.repos.d/hashicorp.repo
- Pour amazon Linux :
wget -O- https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo | sudo tee /etc/yum.repos.d/hashicorp.repo
Installation du package vault :
sudo yum install vault
Sur MacOS
brew tap hashicorp/tap
brew tap-info hashicorp/tap --json | jq -r '.[]|(.formula_names[],.cask_tokens[])'
brew install hashicorp/tap/vault
Vérification de l'installation de Vault
Il suffit de taper la commannde suivante :
vault --version
Vault v1.15.2 (cf1b5cafa047bc8e4a3f93444fcb4011593b92cb), built 2023-11-06T11:33:28Z
Lancer votre premier serveur Vault
Dans une fenêtre terminal tapez la commande suivante :
vault server -dev
==> Vault server configuration:
Administrative Namespace:
Api Address: http://127.0.0.1:8200
Cgo: disabled
Cluster Address: https://127.0.0.1:8201
Environment Variables: ASDF_DIR, BROWSER, COLORTERM, DBUS_SESSION_BUS_ADDRESS, GIT_ASKPASS, GODEBUG, HOME, INFISICAL_API_URL, LANG, LC_ALL, LESS, LOGNAME, LSCOLORS, LS_COLORS, MOTD_SHOWN, NVM_DIR, OLDPWD, P9K_SSH, P9K_TTY, PAGER, PATH, PWD, PYENV_ROOT, PYENV_SHELL, PYENV_VIRTUALENV_INIT, SHELL, SHLVL, SPOTTER_PASSWORD, SPOTTER_USERNAME, SSH_CLIENT, SSH_CONNECTION, TERM, TERM_PROGRAM, TERM_PROGRAM_VERSION, USER, USER_ZDOTDIR, VSCODE_GIT_ASKPASS_EXTRA_ARGS, VSCODE_GIT_ASKPASS_MAIN, VSCODE_GIT_ASKPASS_NODE, VSCODE_GIT_IPC_HANDLE, VSCODE_INJECTION, VSCODE_IPC_HOOK_CLI, VSCODE_NONCE, XDG_RUNTIME_DIR, XDG_SESSION_CLASS, XDG_SESSION_ID, XDG_SESSION_TYPE, ZDOTDIR, ZSH, _P9K_SSH_TTY, _P9K_TTY
Go Version: go1.21.3
Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
Log Level:
Mlock: supported: true, enabled: false
Recovery Mode: false
Storage: inmem
Version: Vault v1.15.2, built 2023-11-06T11:33:28Z
Version Sha: cf1b5cafa047bc8e4a3f93444fcb4011593b92cb
==> Vault server started! Log data will stream in below:
2023-11-16T09:34:52.552+0100 [INFO] proxy environment: http_proxy="" https_proxy="" no_proxy=""
2023-11-16T09:34:52.553+0100 [INFO] incrementing seal generation: generation=1
2023-11-16T09:34:52.553+0100 [WARN] no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set
2023-11-16T09:34:52.556+0100 [INFO] core: Initializing version history cache for core
2023-11-16T09:34:52.556+0100 [INFO] events: Starting event system
2023-11-16T09:34:52.557+0100 [INFO] core: security barrier not initialized
2023-11-16T09:34:52.557+0100 [INFO] core: security barrier initialized: stored=1 shares=1 threshold=1
2023-11-16T09:34:52.559+0100 [INFO] core: post-unseal setup starting
2023-11-16T09:34:52.563+0100 [INFO] core: loaded wrapping token key
2023-11-16T09:34:52.563+0100 [INFO] core: successfully setup plugin runtime catalog
2023-11-16T09:34:52.563+0100 [INFO] core: successfully setup plugin catalog: plugin-directory=""
2023-11-16T09:34:52.564+0100 [INFO] core: no mounts; adding default mount table
2023-11-16T09:34:52.565+0100 [INFO] core: successfully mounted: type=cubbyhole version="v1.15.2+builtin.vault" path=cubbyhole/ namespace="ID: root. Path: "
2023-11-16T09:34:52.568+0100 [INFO] core: successfully mounted: type=system version="v1.15.2+builtin.vault" path=sys/ namespace="ID: root. Path: "
2023-11-16T09:34:52.570+0100 [INFO] core: successfully mounted: type=identity version="v1.15.2+builtin.vault" path=identity/ namespace="ID: root. Path: "
2023-11-16T09:34:52.573+0100 [INFO] core: successfully mounted: type=token version="v1.15.2+builtin.vault" path=token/ namespace="ID: root. Path: "
2023-11-16T09:34:52.574+0100 [INFO] rollback: Starting the rollback manager with 256 workers
2023-11-16T09:34:52.574+0100 [INFO] rollback: starting rollback manager
2023-11-16T09:34:52.574+0100 [INFO] core: restoring leases
2023-11-16T09:34:52.575+0100 [INFO] expiration: lease restore complete
2023-11-16T09:34:52.575+0100 [INFO] identity: entities restored
2023-11-16T09:34:52.575+0100 [INFO] identity: groups restored
2023-11-16T09:34:52.576+0100 [INFO] core: Recorded vault version: vault version=1.15.2 upgrade time="2023-11-16 08:34:52.576096319 +0000 UTC" build date=2023-11-06T11:33:28Z
2023-11-16T09:34:52.726+0100 [INFO] core: post-unseal setup complete
2023-11-16T09:34:52.726+0100 [INFO] core: root token generated
2023-11-16T09:34:52.726+0100 [INFO] core: pre-seal teardown starting
2023-11-16T09:34:52.727+0100 [INFO] rollback: stopping rollback manager
2023-11-16T09:34:52.727+0100 [INFO] core: pre-seal teardown complete
2023-11-16T09:34:52.727+0100 [INFO] core.cluster-listener.tcp: starting listener: listener_address=127.0.0.1:8201
2023-11-16T09:34:52.727+0100 [INFO] core.cluster-listener: serving cluster requests: cluster_listen_address=127.0.0.1:8201
2023-11-16T09:34:52.728+0100 [INFO] core: post-unseal setup starting
2023-11-16T09:34:52.728+0100 [INFO] core: loaded wrapping token key
2023-11-16T09:34:52.728+0100 [INFO] core: successfully setup plugin runtime catalog
2023-11-16T09:34:52.728+0100 [INFO] core: successfully setup plugin catalog: plugin-directory=""
2023-11-16T09:34:52.728+0100 [INFO] core: successfully mounted: type=system version="v1.15.2+builtin.vault" path=sys/ namespace="ID: root. Path: "
2023-11-16T09:34:52.729+0100 [INFO] core: successfully mounted: type=identity version="v1.15.2+builtin.vault" path=identity/ namespace="ID: root. Path: "
2023-11-16T09:34:52.729+0100 [INFO] core: successfully mounted: type=cubbyhole version="v1.15.2+builtin.vault" path=cubbyhole/ namespace="ID: root. Path: "
2023-11-16T09:34:52.730+0100 [INFO] core: successfully mounted: type=token version="v1.15.2+builtin.vault" path=token/ namespace="ID: root. Path: "
2023-11-16T09:34:52.730+0100 [INFO] rollback: Starting the rollback manager with 256 workers
2023-11-16T09:34:52.730+0100 [INFO] rollback: starting rollback manager
2023-11-16T09:34:52.730+0100 [INFO] core: restoring leases
2023-11-16T09:34:52.730+0100 [INFO] identity: entities restored
2023-11-16T09:34:52.730+0100 [INFO] identity: groups restored
2023-11-16T09:34:52.730+0100 [INFO] expiration: lease restore complete
2023-11-16T09:34:52.730+0100 [INFO] core: post-unseal setup complete
2023-11-16T09:34:52.730+0100 [INFO] core: vault is unsealed
2023-11-16T09:34:52.733+0100 [INFO] core: successful mount: namespace="" path=secret/ type=kv version=""
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.
You may need to set the following environment variables:
$ export VAULT_ADDR='http://127.0.0.1:8200'
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: X8Y1YegGxATEiMji+Jydr9zNLg+Y5fNqK6nXZ0cK8XQ=
Root Token: hvs.T9hGPTSQ0uMxbi2Yt9onYPX3
Development mode should NOT be used in production installations!
Félicitations votre serveur Vault est opérationnel 👍
Gérer vos secrets avec Vault
La version dev du serveur Vault permet de saisir tout de suite des clés Valeurs dans le coffre-fort. Il suffit dans une autre fenêtre de Terminal d'exporter la variable indiquant à la CLI Vault où se trouve le serveur :
export VAULT_ADDR='http://127.0.0.1:8200'
Il faut lui donner aussi le Token d'accès qui a été retourné lors du lancement du serveur. Le token se trouve dans les dernières lignes :
export VAULT_TOKEN='hvs.T9hGPTSQ0uMxbi2Yt9onYPX3'
Pour vérifier que vous y avez accès :
vault status 09:55:36
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.15.2
Build Date 2023-11-06T11:33:28Z
Storage Type inmem
Cluster Name vault-cluster-24e4e195
Cluster ID b9a088a4-e194-cc50-5714-38774aad3963
HA Enabled false
Tout est prêt 👍
La commande kv de la CLI Vault
Lors de l'exécution de Vault en mode développement, le moteur de secrets
Key/Value v2 est activé avec le path secret/
. Le moteur de secrets est un
magasin clé-valeur générique utilisé pour stocker des secrets arbitraires dans
le stockage physique configuré pour Vault. Les secrets écrits dans Vault sont
chiffrés, puis écrits dans le stockage principal. Par conséquent, le mécanisme
de stockage back-end ne voit jamais la valeur non chiffrée et ne dispose pas des
moyens nécessaires pour la déchiffrer sans Vault.
Pour gérer les secrets avec la CLI de Vault, il faut utiliser la commande suivante :
vault kv <subcommand> [options] [args]
Pour obtenir de l'aide avec cette commande :
kv enable-versioning --help 09:59:02
Usage: vault kv enable-versioning [options] KEY
This command turns on versioning for the backend at the provided path.
$ vault kv enable-versioning secret
Additional flags and more advanced use cases are detailed below.
...
Subcommands:
delete Deletes versions in the KV store
destroy Permanently removes one or more versions in the KV store
enable-versioning Turns on versioning for a KV store
get Retrieves data from the KV store
list List data or secrets
metadata Interact with Vault's Key-Value storage
patch Sets or updates data in the KV store without overwriting
put Sets or updates data in the KV store
rollback Rolls back to a previous version of data
undelete Undeletes versions in the KV store
Stockage de clés/valeurs
Créons notre premier secret :
vault kv put -mount=secret foo bar=baz
= Secret Path =
secret/data/foo
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T08:36:35.501700726Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
Il est possible de créer plusieurs secrets avec une seule commande put
:
vault kv put -mount=secret hello foo=world excited=yes 10:13:18
== Secret Path ==
secret/data/hello
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T09:13:27.223229803Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
Lecture d'un secret
La commande get
permet de récupérer un secret :
vault kv get -mount=secret hello 10:13:27
== Secret Path ==
secret/data/hello
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T09:13:27.223229803Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
===== Data =====
Key Value
--- -----
excited yes
foo world
Effacer un secret
Pour supprimer une valeur, on utilise la commande delete
:
vault kv delete -mount=secret hello 10:13:37
Success! Data deleted (if it existed) at: secret/data/hello
On contrôle que le secret a bien été détruit :
vault kv get -mount=secret hello
== Secret Path ==
secret/data/hello
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T09:13:27.223229803Z
custom_metadata <nil>
deletion_time 2023-11-16T09:14:44.217933975Z
destroyed false
version 1
La sortie affiche uniquement les métadonnées dont deletion_time
. Il n'affiche
pas les données elles-mêmes une fois supprimées.
Restauration d'un secret
Comme vous le voyez l'effacement est une opération réversible. On peut restaurer un secret :
vault kv undelete -mount=secret -versions=1 hello 10:16:06
Success! Data written to: secret/undelete/hello
On contrôle :
vault kv get -mount=secret hello 10:19:51
== Secret Path ==
secret/data/hello
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T09:13:27.223229803Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
===== Data =====
Key Value
--- -----
excited yes
Destruction
Si vous souhaitez supprimer définitivement les métadonnées sous-jacentes, vous
devrez utiliser la commande destroy
:
vault kv destroy -mount=secret -versions=1 hello 10:21:16
Success! Data written to: secret/destroy/hello
On contrôle :
vault kv get -mount=secret hello 10:21:37
== Secret Path ==
secret/data/hello
======= Metadata =======
Key Value
--- -----
created_time 2023-11-16T09:13:27.223229803Z
custom_metadata <nil>
deletion_time n/a
destroyed true
version 1
Cette fois le flag destroyed
est bien à true
!
Conclusion
J'espère qu'à travers cette petite introduction, vous aurez compris toute la puissance de Vault pour stocker des secrets en toute sécurité. La gestion des secrets n'est pas la seule fonctionnalité de Vault, nous verrons les autres dans les chapitres suivants.