Dans cette suite de trois articles, je vous présente Vault d’Hashicorp afin de vous donner une vision sur les possibilités qu’offre cet outil pour vos différents projets. La phase d’installation est volontairement omise (le lien vers l’installation de Vault : ici). Cette suite d’article s'appuie sur mon expérience liée à l'utilisation de Vault dans le SI d’Ippon Technologies pour la gestion des secrets dans Ansible et Puppet.
Ce dernier article décrit trois exemples d’utilisations (PKI, base de données et AWS) et aborde les services secret as a service de Vault et les tokens.
Les services de Vault
Vault propose de stocker et gérer les accès à des secrets. Ce service concerne uniquement les secrets statiques comme des mots de passe.
Il peut aller plus loin. Vault peut fonctionner en tant que secret as a service. Dans ce cas là, les secrets ne sont plus statiques mais dynamiques. Vault s’occupe de créer le secret, de vérifier les accès et de le supprimer. Par exemple, pour le module AWS, Vault va être capable de générer des access key d’AWS et de les supprimer à la fin d’un délai. Tout cela sans intervention humaine.
Il peut aussi fonctionner en tant que service de chiffrement grâce au module transit. Avec ce module, Vault chiffre, signe et vérifie des données sans les stocker. Un cas d’utilisation est présent dans la documentation (ici)
Un autre service possible est le response wrapping. Ce service permet de séparer les privilèges dans la récupération des secrets. Dans ce mode, un producteur génère un accès au secret et le ou les clients utilisent cet accès pour récupérer le secret. Le producteur peut ne pas avoir d’autorisation sur le secret ni en avoir la connaissance. Une illustration de ce principe dans la documentation (ici) avec le module cubbyhole. Dans ce module, l’accès et la durée de vie des secrets de type clés/valeurs sont liés à un token :
- Seul le token permet d’accéder aux secrets liés à celui-ci. Il n’y a aucune association avec des policies possible.
- La fin de vie du token entraîne la suppression des secrets associés.
Les tokens
Une des notions des plus importantes de Vault concerne les tokens. Ils sont la base de l’identification et des accès de Vault.
# Voici la création d’un token
[root@vault ~]# vault token create -policy="client1"
Key Value
--- -----
token s.pVIzLsyIo7tnrP6qQnMjQtqW
token_accessor jsHvGeR4t1bgOBoALPozFzgP
token_duration 768h
token_renewable true
token_policies ["client1" "default"]
identity_policies []
policies ["client1" "default"]
# Les paramètres du token
[root@vault ~]# vault token lookup s.pVIzLsyIo7tnrP6qQnMjQtqW
Key Value
--- -----
accessor jsHvGeR4t1bgOBoALPozFzgP
creation_time 1560766565
creation_ttl 768h
display_name token
entity_id n/a
expire_time 2019-07-19T12:16:05.431431635+02:00
explicit_max_ttl 0s
id s.pVIzLsyIo7tnrP6qQnMjQtqW
issue_time 2019-06-17T12:16:05.431431458+02:00
meta <nil>
num_uses 0
orphan false
path auth/token/create
policies [client1 default]
renewable true
ttl 767h29m39s
type service
Ils sont utilisés de deux façons :
- directement : un token est utilisé directement pour s’identifier.
- indirectement : tous les modules d’authentifications associent un token à chaque session validée.
Chaque token est lié à une ou plusieurs policies et un lease. Un lease est un ensemble de données comprenant entre autres : l’ID, un accessors, le Time to live (TTL) et la durée maximum de renouvellement. A l’expiration de son TTL, le token est supprimé ou révoqué par Vault. Un TTL peut être étendu tant que celui-ci est encore valide ou que la durée maximum de renouvellement n’est pas dépassée.
Point important, il n’existe pas de commande permettant de récupérer l’identifiant des tokens. La gestion des tokens passe obligatoirement par leurs accessors. Ceux-ci sont récupérables et permettent de :
- lister les informations du token
- récupérer le module du token (dans le path)
- révoquer le token
#liste tous les accessors
[root@vault ~]# vault list auth/token/accessors
Keys
----
1JIEX84fT6F2c2CFE0kZ86iX
5plodCfa9f0i3kIe8I4du408
79giyHKmMc3mSYbUHoioB6cu
eDPEFDtbVVqJ1UbmnWG74H3s
...
#Affiche les paramètres d’un token
#A noter l’ID du token n'apparaît pas
[root@vault ~]# vault token lookup -accessor eDPEFDtbVVqJ1UbmnWG74H3s
Key Value
--- -----
accessor eDPEFDtbVVqJ1UbmnWG74H3s
creation_time 1558367629
creation_ttl 768h
display_name userpass-bob
entity_id 9912d75c-d7c6-5816-b007-52b8202f7e15
expire_time 2019-06-21T17:53:49.297074601+02:00
explicit_max_ttl 0s
id n/a
issue_time 2019-05-20T17:53:49.29707441+02:00
meta map[username:bob]
num_uses 0
orphan true
path auth/userpass/login/bob
policies [default test]
renewable true
ttl 101h15m3s
type service
# Le token est révoqué
[root@vault ~]# vault token revoke -accessor eDPEFDtbVVqJ1UbmnWG74H3s
Success! Revoked token (if it existed)
Sur la révocation je souhaite préciser quelques points:
- Celle-ci peut être faite via l’API, l'interface web ou comme dans mon exemple en ligne de commande.
- Les tokens sont liés entre eux sous forme d’arbre. Sauf exception, les tokens sont obligatoirement associés à un token père. La révocation du token père révoque automatiquement ses fils.
- Le fait que les accessors permettent la révocation des tokens, ils doivent être vu comme une donnée sensible même s’ils ne permettent pas une authentification.
Lors de l’installation de Vault, le premier token est un root token. Les root tokens possèdent un accès complet à Vault et ils sont les seuls n’ayant pas de TTL. Dans les environnements de production, Hashicorp conseille fortement d’utiliser ce type de token uniquement au besoin et de les supprimer dès que possible.
Il existe aussi des tokens dits periodic tokens. Ce sont des tokens avec une période de renouvellement sans limite. Ils sont surtout à destination des applications pour un usage de longue durée.
Pour aller plus loin dans les tokens : ici
Exemples d’utilisation
Module PKI (Certificat SSL)
Vault possède un moteur PKI. Il est capable d'importer ou de générer lui-même le certificat CA racine. La documentation officielle conseille l’utilisation d’un certificat CA racine à l’extérieur de Vault et de passer par un certificat CA intermédiaire.
Après la configuration du moteur, la génération de certificat peut se faire via l’IHM ou en ligne de commande. Voici un exemple extrait de la documentation afin de générer un certificat SSL :
$ vault write pki/issue/my-role common_name=www.my-website.com
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----...
issuing_ca -----BEGIN CERTIFICATE-----...
private_key -----BEGIN RSA PRIVATE KEY-----...
private_key_type rsa
serial_number 1d:2e:c6:06:45:18:60:0e:23:d6:c5:17:43:c0:fe:46:ed:d1:50:be
Module Base de données
Vault supporte une dizaine de bases de données différentes comme MySQL/MariaDB, PostgreSQL et Cassandra. Il crée des utilisateurs de bases de données à la demande à partir d’une requête SQL. Ces utilisateurs seront automatiquement supprimés à la fin de leur TTL.
La configuration de Vault se fait en 2 temps. Dans un premier temps, on indique à Vault les paramètres de connexion à la base de données. Ensuite, on crée un rôle qui porte les requêtes SQL pour la création et la révocation des utilisateurs de la base. Le nombre de rôles n’est pas limité.
Par exemple (repris de la documentation officielle) pour MySQL:
# Configuration de la connexion à la base de donnée
vault write database/config/my-mysql-database \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
allowed_roles="my-role" \
username="root" \
password="mysql"
# Modèle de la requête SQL pour la gestion des utilisateurs
# my-role correspond au champ allowedroles de la commande précédente
vault write database/roles/my-role \
# my-mysql-database correspond au chemin database/config/my-mysql-database de la commande précédente
db_name=my-mysql-database \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT ON *.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
#On peut rajouter le champ evocation_statements pour définir la requête SQL de suppression des utilisateurs
Coté client, la création d’un compte se fait via le processus suivant:
[root@vault ~]# vault read mysql/creds/my-role
Key Value
--- -----
lease_id mysql/creds/my-role/hv0SKIMsDkjoOddHBzZQZlH1
lease_duration 1h
lease_renewable true
password A1a-NqfElhVN1vEG5b2N
username v-root-my-role-JQ6sTjecaJLxVE7lu4
#Résultat dans Mysql
MariaDB [mysql]> select User,Password from user where User="v-root-my-role-JQ6sTjecaJLxVE7lu4";
+----------------------------------+-------------------------------------------+
| User | Password |
+----------------------------------+-------------------------------------------+
| v-root-my-role-JQ6sTjecaJLxVE7lu4 | *3AFB061BF01FE1052A8F56063061B9D0200B0522 | +----------------------------------+-------------------------------------------+
#Une heure plus tard, Vault a supprimé le compte v-root-my-role-JQ6sTjecaJLxVE7lu4
MariaDB [mysql]> select User,Password from user where User="v-root-my-role-JQ6sTjecaJLxVE7lu4";
Empty set (0.001 sec)
Vault gère la rotation de ces identifiants sur la base de données.
vault write -f mysql/rotate-root/test
Success! Data written to: mysql/rotate-root/test
Module AWS
Plusieurs méthodes d’identification existent :
- STS AssumeRole
- STS Federation Tokens
- IAM USer
Je vous présenterai la dernière méthode. Celle-ci demande la création d’un utilisateur IAM pour Vault (la documentation officielle propose une policy ici). Ensuite, on définit une policy AWS dans un rôle Vault. Les comptes IAM créés avec ce rôle sont automatiquement associés à la policy du rôle. Vault s'occupera aussi d’effacer les identifiants IAM créés à la fin de leur TTL.
#Lié Vault avec son compte IAM
root@vault ~]# vault write aws/config/root \
access_key=AKIAZPX3XVC3FZBDEIM7 \
secret_key=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 \
region=eu-west-3
#Création d’un rôle
[root@vault ~]# vault write aws/roles/my-role \
#On peut aussi associé avec une policy déjà existant
# policy_arns=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}]
}
EOF
root@vault ~]# Génération d’un identifiant IAM
vault read aws/creds/my-role
Key Value
--- -----
lease_id aws/creds/my-role/WqENsbkUcXwUXluW4Zjxxook
lease_duration 768h
lease_renewable true
access_key AKIAZPX3XVC3BBOZN2OZ
secret_key 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
security_token <nil>
Voici le résultat au niveau de la console d’AWS :
Comme pour le module sur les bases de données, Vault est capable de faire une rotation de ces identifiants IAM via la commande :
[root@vault ~]# vault write -f aws/config/rotate-root
Key Value
--- -----
access_key AKIAZPX3XVC3NCZLTCNF
Sur l’interface web, il est possible de visualiser les utilisateurs créés et de les révoquer.
La phrase de la fin
J’espère que les éléments présentés dans cette suite d'articles vous donneront envie de découvrir Vault. Je ne peux que vous conseiller de lire la documentation officielle de Vault (ici). Hashicorp propose des TPs de découverte avec des scénarios d’utilisation (https://learn.hashicorp.com/vault/).