Ansible Vault: Je suis comme vous dites : paranoïaque !

Tout ce qu'il y'a à savoir sur la vérité absolue est là:
742d771748aea8bac6f2c682afd41dd8. Mais faudrait-il encore pouvoir le déchiffrer. En contre-partie de la modique somme de 20k€ payable en bitcoin à pipo@noskillbrain.fr je peux vous rêvéler le secret.

Dans l'article précédent je vous parlais d'Ansible autour d'un projet qui contient une partie simple de déploiement et création de comptes MySQL. Dans cette partie du projet, les mots de passe sont stockés en clair dans le fichier de variables, sur le git du projet, et encore pire, ce git est public.

Là, ça pue du cul, mais violent.

Nous allons donc voir comment chiffrer ces données pour qu'elles ne soient pas en clair sur notre git (attention, même chiffré vous n'allez pas mettre vos mots de passe sur votre git public, hein ? ;)). Et pour ça, nous allons nous servir d'Ansible-vault, qui permet de chiffrer nos données en AES256.

Nous allons travailler autour du fichier de variables hostdebian dans le dossier host_vars du projet de présentation d'Ansible de l'article précédent, dans sa première version le fichier est le suivant, avec les mots de passe des utilisateurs SQL en clair:

---
# fichier de variables de configuration pour le serveur hostdebian
# https://noskillbrain.fr/2017/10/18/ansible/

hostname: hostdebian
ip_address: 192.168.2.109

#
# DISCLAMER: les mots de passe sont définis en clair à titre d'exemple.
#            L'utilisation d'ansible Vault est largement recommendé dans ce type de cas.
#            Ansible vault: http://docs.ansible.com/ansible/latest/vault.html
#
mysql_user:
  noskillbrain1:
    password: i0eFuprAYZQQ
    databases: 
       - noskillbrain1_db_1
    privs:
       - noskillbrain1_db_1.*:ALL
  noskillbrain2:
    password: V17pPyOsUO6Q
    databases: 
       - noskillbrain2_db_1
       - noskillbrain2_db_2
    privs:
       - noskillbrain2_db_1.*:ALL
       - noskillbrain2_db_2.*:SELECT

L'objectif est de chiffrer les valeurs des variables password, nous allons même déplacer ces mots de passe dans un autre fichier nommé vault_hostdebian.
Pour manipuler les fichiers chiffrer d'Ansible nous utiliserons la cli ansible-vault.

Eh ben, on est pas sorti du sable !

La commande ansible-vault est utilisable avec les options create|decrypt|edit|encrypt|encrypt_string|rekey|view.

create

Nous utiliserons l'option create pour créer notre fichier chiffré vault_hostdebian.

# ansible-vault create host_vars/vault_hostdebian
New Vault password: 
Confirm New Vault password: 

À la création du fichier, vous devez renseigner un mot de passe et le confirmer, puis écrire le contenu et enregistrer le fichier.

Dans le cas de notre projet de présentation le contenu sera:

---

vault_noskillbrain1_password: i0eFuprAYZQQ
vault_noskillbrain2_password: V17pPyOsUO6Q

Quand le fichier est enregistré et l'éditeur fermé (techniquement, il se trouve temporairement dans le dossier tmp de votre configuration ansible, puis déplacé), le fichier est chiffré par ansible-vault. Le contenu de notre fichier dans cet exemple est:

$ANSIBLE_VAULT;1.1;AES256
38386136326639653234353335343063336636653761393831393735316635313964356235653565
3037303763633234653763656563616666346230386161320a376563363739616133333531653665
32666566366566303562323635343466323133343466356238663635636139633939373631376234
3438333638393563310a373664616462363161633665393631623236633539323139333237393566
34373037373631313665363065303261336236623932656234343861326661613533373265343039
65616235326663333535636665356336356161633764353664356237616137653337356361333863
36346262613962393861646365663637323937326562323063346663646664303063396561633863
63333862646530616138633337646435356430393831643637373036353665643433353831316630
6231

Ensuite revenons sur notre fichier host_vars/hostdebian pour remplacer la valeur des variables password par le nom des variables définies dans le fichier vault, ce qui donne:

  noskillbrain1:
    password: "{{vault_noskillbrain1_password}}"
[...]
  noskillbrain2:
    password: "{{vault_noskillbrain2_password}}"


Photo by MILKOVÍ / Unsplash

encrypt

Nous avons vu comment créer un nouveau fichier chiffré avec ansible-vault, on peut également chiffrer un fichier déjà existant avec l'option encrypt:

# echo "noskillbrain" > my_secret_file

# ansible-vault encrypt my_secret_file
New Vault password: 
Confirm New Vault password: 
Encryption successful

Contenu du fichier existant chiffré:

$ANSIBLE_VAULT;1.1;AES256
64363466316664646166393336363361653231636235393235306433313339653361616265386432
3934643936663337653030663262363530646239633063340a303666366165306636636166653062
61353762643265326262643762623061333838343964373965653338613963356561313562376136
6139363634353034630a393936306631376163323866393661353239313431613530663837653334
3161

view & edit

Nous avons créé notre fichier, avec les options view et edit nous pouvons visionner et éditer un contenu chiffré.

Les options create et encrypt nous ont demandé de taper un mot de passe à l'exécution des commandes, c'est ce même mot de passe que nous allons utiliser pour voir ou éditer le contenu du fichier. Pour pouvoir renseigner ce mot de passe nous allons ajouter l'option --ask-vault-pass


Un view sur le fichier my_secret_file chiffré avec l'option encrypt

#ansible-vault view my_secret_file  --ask-vault-pass
Vault password: 
noskillbrain

Pour éditer le fichier, on remplacera simplement l'option view par edit.

# ansible-vault edit my_secret_file  --ask-vault-pass

Modificaton du projet

Pour pouvoir utiliser notre fichier vault_hostdebian pour notre serveur hostdebian nous devons modifier un peu l'arboresence de notre projet.

Pour cela nous allons suivre une des Best Practice ansible: Variables and Vaults, et créer un répertoire hostdebian dans host_vars, dans lequel on va placer les fichiers de variables hostdebian et vault_hostdebian.

De cette façon, pour un déploiement sur le serveur hostdebian, Ansible ira chercher tous les fichiers de variables présents dans le répertoire hostdebian. Ce fonctionnement est également valide pour les group vars.

Notre arborescence host_vars se présente désormais de cette façon:

host_vars/
├── hostcentos
└── hostdebian
    ├── hostdebian
    └── vault_hostdebian

1 directory, 3 files

Nous avons désormais nos mots de passe qui sont protégés dans un fichier chiffré, notre arborescence permettant d'utiliser ce fichier, il nous reste à déployer notre projet Ansible sur le serveur hostdebian.

Photo by Tim Evans / Unsplash

Le déploiement se fait de la même façon que dans l'article précédent, mais en ajoutant l'option --ask-vault-pass ce qui nous permet de renseigner le mot de passe vault que nous avons utilisés pour chiffrer notre fichier.

Avant toute chose, il faut passer sur la branche git ansible_vault du projet:

# git checkout -b ansible_vault

Et on déploie avec la nouvelle option:

# ansible-playbook configuration.yml -i mon_inventaire -l hostdebian --ask-vault-pass

Le mot de passe utilisé pour le projet est: noskillbrain_vault

Toujours plus loin, toujours plus haut.

Depuis la version 2.4 d'Ansible, il est possible d'utiliser plusieurs identités et plusieurs mots de passe avec l'option --vault-id, pour l'utilisation assez simple et détaillée je vous redirige vers la doc: Vault Ids and Multiple Vault Passwords.

Nous avons vu comment utiliser la commande ansible-vault, avec à chaque fois, la nécessité de retaper le mot de passe. Il est également possible de stocker le mot de passe dans un fichier (par exemple .vault_pass) et d'utiliser l'option --vault-password-file .vault_pass. Pensez à ajouter ce fichier dans le fichier .gitignore de votre dépôt git.

Le format de sortie du chiffrement est en héxadécimal, vous pouvez retrouver la méthode de chiffrement sur la doc Ansible: Vault Payload Format 1.1

N'oubliez pas, je détiens la vérité absolue: 742d771748aea8bac6f2c682afd41dd8