{"id":4213,"date":"2020-08-21T09:00:00","date_gmt":"2020-08-21T07:00:00","guid":{"rendered":"https:\/\/www.unicoda.com\/?p=4213"},"modified":"2020-08-17T18:29:02","modified_gmt":"2020-08-17T16:29:02","slug":"migration-vers-ansible-vault","status":"publish","type":"post","link":"https:\/\/www.unicoda.com\/?p=4213","title":{"rendered":"Migration vers Ansible Vault"},"content":{"rendered":"\n<p>Je l&rsquo;avais \u00e9voqu\u00e9 plusieurs fois dans quelques articles, j&rsquo;utilise ansible pour g\u00e9rer l&rsquo;installation automatique des services que j&rsquo;auto-h\u00e9berge. J&rsquo;\u00e9tais jusqu&rsquo;\u00e0 pr\u00e9sent rest\u00e9 dans une gestion simple des mots de passe li\u00e9s aux services (comprendre \u00ab\u00a0expos\u00e9 en clair dans les fichiers\u00a0\u00bb). Vraiment pas terrible du point de vue s\u00e9curit\u00e9, mais permettant de me concentrer sur la partie (r\u00e9-)installation automatique, l\u00e0 o\u00f9 r\u00e9side le vrai gain de temps. Disposant de quelques jours de cong\u00e9s, je me suis donc attel\u00e9 \u00e0 ce sujet longtemps repouss\u00e9 qu&rsquo;est la migration des secrets vers le vault ansible.<\/p>\n\n\n\n<p>Un vault ansible, en quelques mots, est un fichier chiffr\u00e9 contenant des pairs cl\u00e9\/valeur permettant de r\u00e9f\u00e9rencer un secret dans un script ansible.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Configuration<\/h4>\n\n\n\n<p>C\u00f4t\u00e9 impl\u00e9mentation, j&rsquo;ai choisi de stocker mon vault dans le dossier <code>group_vars\/all\/<\/code> et j&rsquo;ai commenc\u00e9 en cr\u00e9ant deux fichiers <code>all.yml<\/code> et <code>vault_all.yml<\/code>. Dans <code>vault_all.yml<\/code>, je stocke l&rsquo;ensemble de mes secrets associ\u00e9s \u00e0 un identifiant, par exemple, le mot de passe <code>secretpassword<\/code> associ\u00e9 \u00e0 la cl\u00e9 <code>vault_test_user_password<\/code> donnera le fichier suivant :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---\nvault_test_user_password: secretpassword<\/pre>\n\n\n\n<p>Ensuite, dans <code>all.yml<\/code>, je r\u00e9f\u00e9rence la variable du vault et l&rsquo;expose dans une nouvelle variable. Cette \u00e9tape n&rsquo;est pas forc\u00e9ment n\u00e9cessaire, il est tout \u00e0 fait possible d&rsquo;utiliser directement l&rsquo;identifiant pr\u00e9sent dans le vault. L&rsquo;int\u00e9r\u00eat de cette m\u00e9thode quelque peu r\u00e9p\u00e9titive au moment de la mise en place, r\u00e9side dans le fait que l&rsquo;on dispose d&rsquo;un inventaire des variables stock\u00e9es dans notre fichier vault, sans avoir besoin de d\u00e9chiffrer le fichier vault pour parcourir son contenu. Voici donc, en reprenant l&rsquo;exemple ci-dessus, le contenu de notre fichier de r\u00e9f\u00e9rence :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">---\ntest_user_password: \"{{ vault_test_user_password }}\"<\/pre>\n\n\n\n<p>Maintenant que je dispose de mon dictionnaire de secrets, je peux passer \u00e0 l&rsquo;op\u00e9ration de chiffrement de ce dernier. Par d\u00e9faut, ansible demandera le mot de passe \u00e0 utiliser \u00e0 chaque op\u00e9ration de chiffrement\/d\u00e9chiffrement du fichier, ce qui se r\u00e9v\u00e8le vite r\u00e9barbatif. Heureusement, il est possible de cr\u00e9er un fichier <code>.vault_pass<\/code> pour y stocker le mot de passe du vault. \u00c9videmment, on prendra soin de l&rsquo;ajouter \u00e0 notre <code>.gitignore<\/code>, afin de ne pas commit cette information dans notre d\u00e9p\u00f4t git. Derni\u00e8re \u00e9tape, r\u00e9f\u00e9rencer l&#8217;emplacement du mot de passe dans la configuration ansible, soit dans <code>ansible.cfg<\/code>, par ajout de la ligne :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[defaults]<br>vault_password_file = .vault_pass<\/pre>\n\n\n\n<p>Maintenant que tout est pr\u00eat, il convient de chiffrer le fichier vault. Pour effectuer cette op\u00e9ration, on utilisera la commande :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ansible-vault encrypt group_vars\/all\/vault_all.yml<\/pre>\n\n\n\n<p>Le fichier vault \u00e9tant d\u00e9sormais chiffr\u00e9, l&rsquo;\u00e9dition s&rsquo;effectuera d\u00e9sormais avec :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ansible-vault edit group_vars\/all\/vault_all.yml<\/pre>\n\n\n\n<p>Parmi les autres op\u00e9rations de la commande <code>ansible-vault<\/code>, on notera en particulier <code>decrypt<\/code>, <code>view<\/code> et <code>rekey<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Utilisation<\/h4>\n\n\n\n<p>Maintenant que tout est configur\u00e9, je peux donc remplacer les r\u00e9f\u00e9rences directes au mot de passe pr\u00e9sent dans mes playbooks, par les nouvelles variables cr\u00e9\u00e9es. Toujours avec l&rsquo;exemple pr\u00e9c\u00e9dent, on passera de l&rsquo;extrait de playbook suivant : <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">password: secretpassword<\/pre>\n\n\n\n<p>au nouveau contenu \u00ab\u00a0s\u00e9curis\u00e9\u00a0\u00bb:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">password: \"{{ test_user_password }}\"<\/pre>\n\n\n\n<p>Il ne reste plus qu&rsquo;\u00e0 d\u00e9clencher l&rsquo;ex\u00e9cution de l&rsquo;un des playbooks afin de v\u00e9rifier que tout a \u00e9t\u00e9 configur\u00e9 correctement. Je pourrais m&rsquo;arr\u00eater l\u00e0; les secrets de mes playbooks sont maintenant chiffr\u00e9s dans un fichier d\u00e9di\u00e9, tout va pour le mieux, mais un dernier point de faiblesse subsiste, le mot de passe du vault stock\u00e9 en clair dans notre fichier <code>.vault_pass<\/code>. \u00c9videmment, si un attaquant devait mettre la main sur ce fichier, il y a fort \u00e0 parier que ce serait le cadet de mes soucis, mais voyons tout de m\u00eame si je peux am\u00e9liorer les choses.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">S\u00e9curisation du mot de passe Vault<\/h4>\n\n\n\n<p>En parcourant la documentation ansible li\u00e9e au concept de vault, j&rsquo;ai d\u00e9couvert que le param\u00e8tre de configuration <code>vault_password_file<\/code> est susceptible de prendre un fichier de script ex\u00e9cutable en entr\u00e9e. Seule condition, le script doit renvoyer le mot de passe \u00e0 utiliser. \u00c9tant donn\u00e9 que j&rsquo;utilise d\u00e9j\u00e0 <a rel=\"noreferrer noopener\" href=\"https:\/\/www.passwordstore.org\/\" target=\"_blank\">password-store<\/a> en ligne de commande pour la gestion de mes mots de passe, j&rsquo;y ai vu une occasion parfaite d&rsquo;augmenter encore la s\u00e9curit\u00e9 en stockant le mot de passe du vault dans une entr\u00e9e de mon password-store. Quelques recherches plus tard, j&rsquo;obtiens donc le script suivant; script charg\u00e9 de retourner le contenu de l&rsquo;entr\u00e9e <code>ansible-vault<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>#!\/bin\/bash\n\n<\/strong>###################################\n## Get password from password store\n# Inspired by https:\/\/github.com\/paulRbr\/ansible-makefile\/blob\/master\/pass.sh\n###################################\n\nif (command -v pass &gt;\/dev\/null 2&gt;&amp;1)\nthen\n    existingVault=$(pass \"ansible-vault\" || true)\n\n    if [ -n \"${existingVault}\" ]\n    then\n        &gt;&amp;2 echo \"Using passphrase found at 'ansible-vault' in your password store.\"\n        echo \"${existingVault}\"\n    else\n        &gt;&amp;2 echo \"No passphrase found at 'ansible-vault' in your password store.\"\n        exit 0\n    fi\nfi<\/pre>\n\n\n\n<p>Ma configuration ansible devient donc (Ne pas oublier de rendre le fichier de script ex\u00e9cutable):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[defaults]\nvault_password_file = .\/get-vault-pass.sh<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Autres am\u00e9liorations<\/h4>\n\n\n\n<p>Il est possible d&rsquo;avoir plusieurs vaults dans un projet ansible. Dans l&rsquo;exemple pr\u00e9c\u00e9dent, toutes les entr\u00e9es du vault sont partag\u00e9es avec l&rsquo;ensemble des playbooks, du fait d&rsquo;appartenir au groupe all. Pour simplifier l&rsquo;organisation, j&rsquo;ai dans mon cas d\u00e9plac\u00e9 tous les secrets li\u00e9s \u00e0 unicoda et \u00e0 son playbook de d\u00e9ploiement dans le dossier group_vars\/unicoda\/ et son vault d\u00e9di\u00e9. De la m\u00eame fa\u00e7on, on peut alors envisager d&rsquo;am\u00e9liorer le script pour utiliser un mot de passe diff\u00e9rent pour chaque vault, chacun des mots de passe \u00e9tant alors stock\u00e9 de fa\u00e7on chiffr\u00e9e dans password-store.<\/p>\n\n\n\n<p>Par ailleurs, j&rsquo;ai d\u00e9couvert pendant la mise en place de vault, qu&rsquo;il existe <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.ansible.com\/ansible\/latest\/plugins\/lookup\/passwordstore.html\" target=\"_blank\">un plugin ansible<\/a> maintenu par la communaut\u00e9 et qui permet d&rsquo;aller chercher directement le contenu d&rsquo;un mot de passe dans password-store. Je n&rsquo;ai pas pouss\u00e9 plus avant l\u2019exp\u00e9rimentation, mais l&rsquo;utilisation de ce plugin pourrait \u00eatre une alternative valable \u00e0 l&rsquo;utilisation de vault.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p>Gr\u00e2ce \u00e0 cette derni\u00e8re am\u00e9lioration, mes secrets ansible sont d\u00e9sormais stock\u00e9s en lieu s\u00fbr et ne sont plus accessible au premier venu. C&rsquo;est un \u00e9l\u00e9ment de s\u00e9curit\u00e9 que j&rsquo;encourage \u00e0 mettre en place imm\u00e9diatement, d\u00e8s que le premier secret appara\u00eet dans le  d\u00e9p\u00f4t de code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sources<\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/vault.html\">Ansible Vault<\/a><\/li><li><a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/playbooks_vault.html\">Using Vault in playbooks<\/a><\/li><li><a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/playbooks_best_practices.html#variables-and-vaults\">Variables and Vaults<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Je l&rsquo;avais \u00e9voqu\u00e9 plusieurs fois dans quelques articles, j&rsquo;utilise ansible pour g\u00e9rer l&rsquo;installation automatique des services que j&rsquo;auto-h\u00e9berge. J&rsquo;\u00e9tais jusqu&rsquo;\u00e0 pr\u00e9sent rest\u00e9 dans une gestion simple des mots de passe li\u00e9s aux services (comprendre \u00ab\u00a0expos\u00e9 en clair dans les fichiers\u00a0\u00bb). Vraiment pas terrible du point de vue s\u00e9curit\u00e9, mais permettant de me concentrer sur la &hellip; <a href=\"https:\/\/www.unicoda.com\/?p=4213\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> de &laquo;&nbsp;Migration vers Ansible Vault&nbsp;&raquo;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[331],"tags":[522,530,423,529],"class_list":["post-4213","post","type-post","status-publish","format-standard","hentry","category-securite","tag-ansible","tag-ansible-vault","tag-password-store","tag-vault"],"_links":{"self":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4213"}],"version-history":[{"count":10,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4213\/revisions"}],"predecessor-version":[{"id":4244,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=\/wp\/v2\/posts\/4213\/revisions\/4244"}],"wp:attachment":[{"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unicoda.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}