Ansible vault, tu me fais chier !
Salut à toi camarade, ça baboule du devops ?
Je viens partager ma frustration avec toi au sujet de mon grand pote Ansible vault !
Alors si tu débarques et que tu ne connais pas Ansible, c’est un outil super rigolo pour faire de l’installation et de la configuration de serveur.
Le bon pote Ansible sait aussi chiffrer et déchiffrer des fichiers, c’est très pratique pour protéger et versionner des secrets.
Par contre comme il transforme tout en bouillies, à chaque action de chiffrement, créant des révisions sur les fichiers de secrets même si le contenu du fichier n’a pas changé.
Moi ça m’énerve ! mais tu sais bien que je suis un rageux constructif, je vais te partager ici mes idées pour éviter de trop en chier :)
Tu as oublié de relancer ansible-vault encrypt Harry !
Le fond du problème
Voici un fichier de secret Ansible “en clair”
|
|
voici le même fichier chiffré par Ansible vault
|
|
voici le même fichier chiffré, déchiffré, rechiffré par Ansible vault
|
|
Voici un diff Gitlab, à vous de me dire si le fichier chiffré en question a changé de contenu en clair ou pas :) Bonne chance avec ça !
Le même contenu, si si, je te jure, au caractère près, aucun changement, mais un nouveau blob complètement différent du précédent. La seule façon de s’en assurer c’est de prendre les deux fichiers, de les déchiffrer et de faire un diff manuellement. Autant dire que dans git c’est très loin d’être pratique et que tu vas y passer un temps de dingues avec des opérations manuelles reloues et un risque non négligeable de te planter !
Ansible vault c’est bien, mais c’est une merde sans nom à debugger et à auditer.
Il te fait de gros fichiers bien opaques, et pour savoir si une variable est présente ou pas, il faut déchiffrer le fichier à chaque fois.
Ce que je vous propose c’est de rendre le système un peu moins sécurisé, mais un peu plus facile à auditer 😁
Après tout, sécurité contre praticité est un débat très ancien, mais qui continue de faire parler 🙈
Sortez-moi vos meilleurs arguments pour me dire si c’est une bonne idée ou si je devrai être purement et simplement interdit de clavier à vie !
Cette astuce incroyable de grand-mère qui énerve les experts en sécurité
Ce qu’on va mettre en place c’est un truc qui j’avais déjà un peu fait avec le cron d’audit des secrets Gitlab.
On va faire une lecture de nos fichiers de secrets et faire un dictionnaire de secrets hashé en sha256.
C’est important de bien hacher sinon la soupe n’est pas bonne !
Ce qui va nous permettre de lister l’ensemble des secrets et de savoir à chaque moment si un secret a changé ou pas, mais aussi d’avoir une idée des secrets qui sont identiques entre nos envs ou qui sont un peu pétés (genre le mot de passe est le nom de mon utilisateur)
Les conséquences de ça, c’est que si on s’empare du repo, on pourra pas forcément déchiffrer le contenu des secrets, mais on pourra deviner certains trucs si vous avez fait des mauvaises pratiques 😜
Mais je te connais, tu ne laisses pas les mots de passe par défaut et ta base de données en accès public sur internet hein 😉
Pour se décharger mentalement, on va faire le versionning du fichier de hash dans gitlab-ci. Tout le toutim sera autocommis avec le tag [SKIP CI], pour éviter d’avoir une shitloop de CI/CD. ( Une CI à déclenchement récursif sans condition d’arrêt)
Également, comme on sait qu’à chaque chiffrement et déchiffrement le fichier chiffré est changé, on veut plutôt isoler le déchiffrement, rechiffrement et éviter de commiter des fichiers rechiffrées qui n’ont pas changés pour éviter de polluer inutilement l’historique.
hash_secrets.py
|
|
Alors que fait le code ?
On boucle sur le dossier env_vars Pour chaque dossier on récupère les fichiers yaml qui n’ont pas “hash” dans leur nom (pour éviter une récursivité de création de fichiers ensuite) pour chaque clef de nos fichiers yaml on fait un hash sha256 de la valeur du secret. et on dump nos petits amis dans un fichier du même nom avec le suffixe hash.yml.
On met tout ça dans un gitlab-ci un peu crados qu’on vas expliquer ensuite :)
|
|
- on écrit le fichier secret de vault (qu’on a bien rangé au chaud dans une variable gitlab)
- on installe Ansible et dépendances
- on set les variables d’identification de git pour que notre “robot” puisse commiter
- on déchiffre chaque fichier secret et on fait un check de la syntaxe yaml (c’est ce que fait le one liner python)
- on lance le script de hash
- on commit tous les fichiers de hash
- la variable GITLAB_AUTH_STRING contient une authentification Gitlab sous cette forme nom_du_token:token_gitlab
Et donc à partir de maintenant, à chaque réel changement sur les fichiers secrets, on va avoir un nouveau autocommit et un changement sur les fichiers de hash avec un indice sur ce qui a changé.
On voit d’un coup d’œil dans l’historique des commits à quel moment un changement dans les secrets a été fait.
et notre audit est facilité juste en regardant le diff
|
|
On voit d’un coup d’œil rapide que le secret env_mongodb_coucou a changé de valeur et avec un coup de grep on retrouve très facilement ou il est utilisé dans le code. Bonus on sait avec précision le nom des secrets vaultés, ça nous permet de contrôler le nom des secrets et éventuellement des erreurs.
Mets-moi ton plus beau crochet du droit
Dernier petite astuce pour avoir des casseroles qui brille et les yeux qui pétilles, on peut mettre en place un git Hook pour re chiffrer le vault avant le commit.
On s’enlève encore un peu de charge mentale, on évite de commiter les fichiers de secrets en clair.
|
|
ce que fait le script:
- peu importe ou je suis dans l’arborescence du repo, je cd jusqu’à la racine de repo.
- boucles sur les dossiers dans env_vars
- pour chacun des fichiers dans les dossiers env_vars, je lance ansible-vault encrypt et je veux un résultat d’exécution .
- le script s’exécute avant le push et permet de faire un commit amend si on à oublié de rechiffrer les secrets.
- ce qui nous donne une exécution comme celle-ci.
|
|
mon arborescence de fichier ressemble à ça
|
|
Conspiration
Cette astuce est probablement à éviter dans un contexte de repo sensible, la dernière chose qu’on veut, c’est de fragiliser nos secrets face à une attaque extérieure.
Mais quand on jardine du Ansible, et qu’on essaye de bosser un peu proprement et de manière sécurisée, ansible vault est un incontournable, C’est dommage de s’en passer, parce qu’il est plutôt simple à mettre en place. Le fait d’exposer un peu plus le contenu de notre vault réduit la sécurité, mais permet aussi d’enforcer des bonnes pratiques.
- on veut éviter d’avoir les mêmes mots de passe entre nos environnements
- on veut éviter d’oublier des variables et d’être obligé d’exposer des tâches sensibles pour débugguer
- on veut éviter de perdre du temps et mettre de la confusion en chiffrant déchiffrant les fichiers vaultés sans changement.
- on veut savoir quand un secret a été changé sans en exposer le contenu et savoir quel commit a provoqué le changement.
Solution imparfaite, parce que on peut encore committer des fichiers dévaulté en clair, si ont fait pas gaffe, et ça ne fonctionne que dans le contexte d'Ansible.
Si vous avez d’autres trucs à chiffrer en dehors d’Ansible, pensez à git-crypt :)
Bisous