Vault - Une présentation - Partie 1/3

Dans cette suite de 3 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 premier article est dédié au fonctionnement de Vault avec un exemple d’utilisation de Vault avec le module Ansible.

Présentation de Vault d’Hashicorp

Général

Vault est une sorte de coffre fort. Celui-ci stocke des secrets sous forme d’arbre. Ceux-ci peuvent être un mot de passe, un token ou un compte MySQL selon le module utilisé.

Hashicorp propose deux versions entreprise. Elles ajoutent des fonctionnalités comme les namespaces et les réplicas en lecture seul.

Sur la copie d’écran suivante, vous pouvez voir que 4 types de secret ont été activés sur ma plateforme de test (pour plus de détails sur les éléments utilisés aws, cubbyhole, KV) :

  • aws : Permet de générer des access key.
  • cubbyhole : Stocke des secrets de type clé/valeur. les secrets sont supprimés automatiquement après un délai paramétrable.
  • kv et secret : Stocke des secrets de type clé/valeur (KV). La différence de ces 2 racines concerne la version du moteur KV utilisé.

Vous remarquerez qu’à chaque module correspond une branche particulière.

Dans la branche “kv”, des sections apparaissent :

Celles-ci peuvent contenir des sous-sections ou des secrets. Dans la section “client2”, deux données apparaissent : “password” et “user”. Un détail lié au module utilisé, KV v2 supporte le versionning des mots de passe..

Les secrets de Vault sont aussi accessible en ligne de commande, par exemple voici la commande pour récupérer un secret

En ligne de commande, pour obtenir le secret client2 :

  • Dans un premier temps, je définie l’url du serveur et je m’identifie

#On indique l’IP du serveur vault
[root@vault ~]# export VAULT_ADDR=http://192.168.43.241:8200     

#Identification via un token        
[root@vault ~]# vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key                  Value
---                  -----
token                s.44q5rRCXSjFZtr8MuXV8vhsJ
token_accessor       axsslxXVxNDDt9wwaM1Ft62p
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]
  • Puis je lance la commande vault kv get chemin_du_secret
#Lecture d’un secret du moteur kv v2 (valeur/secret) de Vault
[root@vault ~]# vault kv get kv/Client1
====== Metadata ======
Key          	Value
---          	-----
created_time 	2019-03-25T15:40:25.400183483Z
deletion_time	n/a
destroyed    	false
version      	2                  # La version du mot de passe actuelle
====== Data ======
Key     	Value
---     	-----
password	La grande question sur la vie, l'univers et le reste
user    	            ippon

# La modification de “client2”
[root@vault ~]# vault kv put kv/client2 user="un test"
Key          	Value
---          	-----
created_time 	2019-06-14T14:24:58.384187271Z
deletion_time	n/a
destroyed    	false
version      	3                     # Nouvelle version

En utilisant le même moteur, voici l’écran de création d’un secret

de même cette action est disponible en ligne de commande:


# Ecriture d’un secret du moteur kv v2 (valeur/secret) de Vault
[root@vault ~]# vault kv put kv/Client4 passcode=my-long-passcode
Key              Value
---              -----
created_time     2019-10-21T12:26:22.381178929Z
deletion_time    n/a
destroyed        false
version          1

Toutes les commandes de Vault sont accessibles par :

  • API
  • Interface WEB (ne dispose pas de toute les fonctionnalités)
  • Ligne de commande

Lorsque Vault démarre, celui-ci se trouve dans un état dit sealed, l’application n’autorise pas l’accès à ses données. Il faut lui communiquer 3 clés (par défaut) pour le passer dans l’état unsealed. Elles sont générées uniquement lors de l’installation et ne peuvent pas être récupérées par la suite. Cette action peut être accomplie manuellement ou automatiquement via des outils comme AWS KVM (Key Management Service). Voici le lien vers le cas d’usage.

Exemple d’utilisation: Module Ansible

Le but de cet exemple est de cacher des mots de passe utilisés dans Ansible et Puppet.Le playbook Ansible est le suivant (la documentation Ansible du module utilisé ici)

---
- hosts: all
  tasks:
  - name: "Test_Ansible"
    debug:
    msg: "{{ lookup('hashi_vault', 'secret=kv/data/Client1:password token=s.44q5rRCXSjFZtr8MuXV8vhsJ url=http://192.168.10.189:8200')}}"     	
  • hashi_vault: Nom du module Ansible utilisé
  • secret: la requête passer au serveur Vault. Dans mon exemple nous avons:
    • kv/data/Client1:password: Le chemin du secret à récupérer dans Vault
    • token: Le token pour l’identification auprès de Vault
    • url: l’URL du serveur vault

Retourne le résultat suivant :

PLAY [all] 
********************************************************************
TASK [Gathering Facts]
********************************************************************
ok: [127.0.0.1]
TASK [Test_Ansible] 
********************************************************************
ok: [127.0.0.1] => {
"msg": "La grande question sur la vie, l'univers et le reste"
}
PLAY RECAP
********************************************************************
127.0.0.1: ok=2	changed=0	unreachable=0	failed=0

On peut remplacer l'identification par token par un autre si besoin, LDAP par exemple. Le token utilisé peut être limité dans le temps ou en nombre d’utilisations. Voici un exemple.

#Création du token
[root@vault ~]# vault token create -policy=client1 -use-limit=3
Key                  Value
---                  -----
token                s.MIUbxJ2ySWZADUH9j3EKETng
token_accessor       KJ4OBx42EPxx3MHz2tVgW3WM
token_duration       768h
token_renewable      true
token_policies       ["client1" "default"]
identity_policies    []
policies             ["client1" "default"]

# Le token est copié dans le playbook
#Premier appel du playbook
[root@client ansible]# ansible-playbook -i 192.168.69.180, tasks/vault.yml
PLAY [all] 
******************************************************************
TASK [Gathering Facts] 
******************************************************************
ok: [192.168.69.180]
TASK [Test_Ansible] 
******************************************************************
ok: [192.168.69.180] => {
"msg": "La grande question sur la vie, l'univers et le reste"
}
PLAY RECAP 
******************************************************************
192.168.69.180         	: ok=2	changed=0	unreachable=0	failed=0   

#Deuxième appel
[root@client ansible]# ansible-playbook -i 192.168.69.180, tasks/vault.yml
PLAY [all] ******************************************************************
TASK [Gathering Facts] 
******************************************************************
ok: [192.168.69.180]
TASK [Test_Ansible] 
******************************************************************
fatal: [192.168.69.180]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'hashi_vault'. Error was a <class 'ansible.errors.AnsibleError'>, original message: Invalid Hashicorp Vault Token Specified for hashi_vault lookup"}
to retry, use: --limit @/etc/ansible/tasks/vault.retry
PLAY RECAP 
*****************************************************************
192.168.69.180: ok=1	changed=0	unreachable=0	failed=1   

J’ai mis le -use-limit à 3 car, dans mon exemple, le playbook se connecte 3 fois à Vault lors de chaque exécution. La commande vault token lookup permet d’examiner les paramètres liés au token.

Exemple de retour de la commande :

[root@vault ~]# VAULT_TOKEN=s.sbgRgsh6BqWHexR1S8smO8GS vault token lookup
Key                        	Value
---                        	-----
accessor                   	imVvTHsvzVPUwucCr9i169Pj
creation_time              	1557755106
creation_ttl               	768h
display_name                token
entity_id                  	92a009d0-470c-3f0c-48a3-b3514c475e8f
expire_time                	2019-06-14T15:45:06.199092974+02:00
explicit_max_ttl           	0s
external_namespace_policies	map[]
id                         	s.sbgRgsh6BqWHexR1S8smO8GS
identity_policies          	[default]
issue_time                 	2019-05-13T15:45:06.199092778+02:00
meta                       	<nil>
num_uses                	5     #Numbre d’utilisation autorisé
orphan                     	false
path                       	auth/token/create
policies                   	[client1 default]
renewable                  	true
ttl                        	767h59m32s
type                       	service

Un mot pour la fin

Le deuxième article de cette suite abordera les modules de Vault et vous proposera comme exemple d’utilisation le module SSH.