Vault - Une présentation - Partie 3/3

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/).