WORKSHOP 9: Vault
Alle workshops die je tot nu toe uitgevoerd hebt maakten gebruik van unencrypted passwords. In de vorige workshop leerde je al hoe je het SSH-wachtwoord kon elimineren uit de inventory door gebruik te maken van een public/private key-pair. Dat is echter niet voldoende. Er zijn steeds verschillende variabelen die wachtwoorden of andere gevoelige data kunnen bevatten. Dit kunnen we oplossen door gebruik te maken van een Ansible vault.
Doelstelling
In deze workshop leer je:
- een Ansible
vaultaanmaken - de Ansible Playbooks en
varsaan te passen om gebruik te maken van een Vault.
Workshop Inleiding Vault
Vault is een mechanisme dat toelaat om inhoud te encrypteren en transparant te gebruiken in Ansible workflows. Dergelijke vaults kunnen zowel met het command ansible als ansible-playbook werken.
Vault werkt op bestandsniveau en dat betekent dat een volledige file geëncrypteerd of gedecrypteerd wordt. Vault maakt gebruik van het AES256 algoritme met symmetric keys. Meer info te vinden in de documentatie.
Stap 1 - Een nieuwe vault aanmaken
Het commando ansible-vault is de centrale tool waarmee we de verschillende bewerkingen op encrypted bestanden gaan uitvoeren.
Hiermee kunnen we bestanden initieel encrypteren en later bekijken, bewerken of decrypteren.
Werk voor dit deel van de workshop in een aparte map van je Ansible-project.
-
Voorzie een map
workshop-vaultin je homefolder:[student@ControlHost ansible-files]$ cd ~[student@ControlHost ~]$ mkdir workshop-vault[student@ControlHost ~]$ cd workshop-vault[student@ControlHost workshop-vault]$ -
Maak een nieuwe
vault(encrypted bestand) aan met de naamvault.yml:[student@ControlHost workshop-vault]$ ansible-vault create vault.yml -
Je wordt gevraagd om een wachtwoord te bedenken waarmee je deze
vaultwil beveiligen.New Vault password:Confirm New Vault password: -
Hierna zal ansible-vault onmiddellijk een standaard editor (
vim) uitvoeren waarin je kan je gevoelige data opnemen..vault.ymlHier is je supergeheime data!!!!Na het verlaten van de editor zou je vault de geëncrypteerde data moeten bevatten.
-
Controleer de inhoud van het bestand
vault.yml:[student@ControlHost workshop-vault]$ cat vault.yml$ANSIBLE_VAULT;1.1;AES256636535323139323634343930363765363031643332396561343532306362363065626534663862376332356362353165626365656333613235663336646266380a386332393531333064623339363464343732643637336234316232633037353232636461333430396130366165333538653834396164383032343935646535610a3566346535393733633864623638336433356330613162316532313238313264
Stap 2 - Bestaande files encrypteren
Als je al over bestanden beschikt die je achteraf wil encrypteren dan kan dat met ansible-vault encrypt.
-
Als test maken we eerst een eenvoudig, niet-geëncrypteerd bestand aan:
[student@ControlHost workshop-vault]$ echo 'unencrypted data' > encrypt_me.txt -
Dit bestand encrypteren we nu als volgt:
[student@ControlHost workshop-vault]$ ansible-vault encrypt encrypt_me.txtNew Vault password:Confirm New Vault password:Encryption successfulIn plaats van een editor te openen zal
ansible-vaultnu onmiddellijk het bestand encrypteren. -
Bekijk het encrypted bestand:
[student@ControlHost workshop-vault]$ cat encrypt_me.txt$ANSIBLE_VAULT;1.1;AES256393463393762376439633634333462333430343331373638356230306266633437656261343562666238346233363931306136653061653636363230666331640a323866313464386566386566333730383039353362623762363731383362333030333466336333633266363934326166306138643039646233633136373664330a66336632346565613235623766313832343838383564353930396232376337313833333563346664613339313830303665613366353934343563303836353236
Stap 3 - Encrypted bestanden bekijken
Eerder geëncrypteerde bestanden kunnen bekeken worden met ansible-vault view.
-
Test dit uit op je eerste bestand:
[student@ControlHost workshop-vault]$ ansible-vault view vault.ymlVault password:Hier is je supergeheime data!!!!
Stap 4 - Encrypted bestanden bewerken
Op een gelijkaardige manier kunnen we eerder geëncrypteerde bestanden bewerken met de default editor via ansible-vault edit.
[student@ControlHost workshop-vault]$ ansible-vault edit vault.yml
Vault password:
Stap 5 - Decrypteren van bestanden
Wanneer een geëncrypteerd bestand niet meer beveiligd moet blijven kan je het decrypteren met ansible-vault decrypt.
[student@ControlHost workshop-vault]$ ansible-vault decrypt vault.yml
Vault password:
-
Controleer of je het bestand nu weer gewoon kan bekijken:
[student@ControlHost workshop-vault]$ cat vault.ymlHier is je supergeheime data!!!!
Workshop Ansible Playbooks met vault
Nu we gezien hebben hoe je bestanden kan encrypteren moeten we even bekijken hoe we dit nu nuttig kunnen toepassen in ansible playbooks en andere bestanden.
Stap 1 - Voorbereiding vars
Om het gebruik van vault in de vingers te krijgen passen we eerst onze bestaand ansible-project wat aan.
Momenteel staan in de inventory nogal wat variabelen (waaronder usernames en wachtwoorden). Een aangewezen manier is deze variabelen in de group_vars of host_vars te plaatsen i.p.v. in de inventory.
-
Haal de variabelen in je inventory
hostsdie betrekking hebben op de groepallweg en plaats deze in een nieuw bestand met de naamall.ymlin de mapgroup_vars.hosts.yml---all:hosts:children:web:hosts:node1:ansible_host: X.X.X.Xnode2:ansible_host: Y.Y.Y.Ynode3:ansible_host: Z.Z.Z.Zftpserver:hosts:node2:ansible_host: Y.Y.Y.Ycontrol:hosts:ansible-1:ansible_host: A.A.A.Avars:ansible_user: studentansible_password: studentansible_connection: localansible_become_pass: studentvars:ansible_port: 22# => onderstaande variabelen worden hier weggenomen# ansible_user: ubuntu# ansible_connection: ssh# ansible_become_pass: Azerty123In de map
./ansible-files/group_vars/maak je het nieuwe bestandall.ymlwaarin je de variabelen van daarnet overneemt:all.ymlansible_user: ubuntuansible_connection: sshansible_become_pass: Azerty123 -
Controleer even of je playbook nog steeds werkt. In principe is er niets veranderd en werd alleen de locatie van de variabelen aangepast.
[student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml
Stap 2 - vars-bestand encrypteren
-
Zoals eerder gezien kunnen we nu het bestand
all.ymlencrypteren metansible-vault.[student@ControlHost ansible-files]$ ansible-vault encrypt group_vars/all.ymlNew Vault password:Confirm New Vault password:Encryption successful
Om nu Ansible tijdens de uitvoering van je playbook toegang te geven tot deze geëncrypteerde data geven we de optie --ask-vault-pass mee.
Op die manier zal de data on-the-fly gedecrypteerd en gebruikt kunnen worden.
-
Test je playbook uit met de optie
--ask-vault-pass:[student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --ask-vault-pass
We passen nu de inventory hosts verder aan zodat er helemaal geen confidentiële data meer staat.
-
Verwijder nu ook de variabelen onder
varsin je inventory van de groepcontrol:hosts.yml---all:hosts:children:web:hosts:node1:ansible_host: X.X.X.Xnode2:ansible_host: Y.Y.Y.Ynode3:ansible_host: Z.Z.Z.Zftpserver:hosts:node2:ansible_host: Y.Y.Y.Ycontrol:hosts:ansible-1:ansible_host: A.A.A.Avars:# => onderstaande variabelen worden hier weggenomen# ansible_user: student# ansible_password: student# ansible_connection: local# ansible_become_pass: studentvars: -
Neem deze variabelen over in een nieuw bestand
control.ymlin de mapgroup_vars:ansible_user: studentansible_password: studentansible_connection: localansible_become_pass: student -
Test voor het encrypteren van het bestand
control.ymlnog eens je project uit. Aangezien we nu de variabelen van de groepcontrolaangepast hebben, testen we best even deze groep uit. Met het onderstaande commando kan je eens alle variabelen opvragen voor een bepaalde host of groep. Zo kan je controleren of effectief de juiste waardes toegekend worden.[student@ControlHost ansible-files]$ ansible control -m debug -a "var=hostvars[inventory_hostname]" --ask-vault-pass
Desondanks dat we in bovenstaande command enkel ansible gebruiken voor de groep control moeten we toch het wachtwoord opgeven voor het geëncrypteerde bestand all.yml. Dat is omdat ansible by default alle bestanden probeert te laden die in de voorziene mappen-structuur van je project staan.
-
Encrypteer nu ook het bestand
control.yml[student@ControlHost ansible-files]$ ansible-vault encrypt group_vars/control.ymlNew Vault password:Confirm New Vault password:Encryption successful -
Test je playbook nu nogmaals uit:
[student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --ask-vault-pass[student@ControlHost ansible-files]$ ansible control -m ping --ask-vault-pass
Proficiat! Op dit moment heb je nu een volledig werkend ansible-project dat gebruik maakt van roles en zijn gevoelige data geëncrypteerd heeft.
Stap 3 - Ansible Vault en automation
Op dit moment is er nog steeds een interactie nodig met de uitvoerder van het Ansible-project. Er moet immers telkens een wachtwoord ingegeven worden vooraleer het Ansible commando kan uitgevoerd worden.
We kunnen dus nog een stukje verder gaan en vermijden dat er manueel een wachtwoord moet opgegeven worden.
Dit lossen we op door een bestand aan te maken waar het Ansible Vault Password in staat.
de locatie van dit bestand kan best goed beveiligd zijn. Je slaat dit bestand best niet op samen met je Ansible-project en je beperkt daarnaast best ook de permissies op dit bestand.
-
Maak een bestand
.vault_pass.txtaan waarin jevault-wachtwoordstaat in je home-folder:[student@ControlHost ansible-files]$ echo "MijnWachtwoord123" > ~/.vault_pass.txt
Met de optie --vault-password-file kan je dan verwijzen naar de locatie van van dit bestand zodat je bij uitvoering van het ansible-command geen interactie meer hoeft te doen.
-
Test dit uit:
[student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml --vault-password-file=~/.vault_pass.txt
Je kan het nog iets vereenvoudigen door in je ansible.cfg een entry te voorzien naar dit bestand. Zo wordt je ansible-command ook weer vrij eenvoudig.
-
Pas je
ansible.cfgbestand aan in je project-folder:[defaults]inventory = ./hostsvault_password_file = ~/.vault_pass.txt -
Test je project nogmaals uit. Je ansible-command zou nu heel eenvoudig moeten zijn en toch gebruik maken van een welbepaalde
inventoryen bijhorendegeëncrypteerde vars-bestanden:[student@ControlHost ansible-files] ansible ftpserver -m ping[student@ControlHost ansible-files] ansible-playbook test_apache_role.yml
Het is heel gebruikelijk om bepaalde variabelen van een inventory-group die niet "gevoelig" zijn af te scheiden van variabelen die je wil afschermen (typisch credentials, keys, certificates,...). Dit kan je makkelijkst bereiken door je mappenstructuur van je "groups" daarop af te stemmen en op die manier bv. 2 bestanden met variabelen bij te houden voor een groep (encrypted en unencrypted). Meer info daarover kan je lezen op volgende blog.
Stap 4 - Individuele waarden encrypteren met encrypt_string
Tot nu toe encrypteerden we steeds volledige bestanden. In de praktijk is het echter heel gangbaar om slechts één enkele waarde (bv. een wachtwoord) inline te encrypteren in een vars-bestand. Zo blijft de rest van het bestand gewoon leesbaar en hoef je geen apart encrypted bestand bij te houden.
Dit doe je met ansible-vault encrypt_string:
[student@ControlHost ansible-files]$ ansible-vault encrypt_string 'MijnGeheimWachtwoord' --name 'db_password'
New Vault password:
Confirm New Vault password:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
38633964303966623933323763623866386335376239613464613361623139386161386664323365
6137373865326266356461313735333031306461336463320a386264336336633832363534643332
34613763303464616262353661666135656464303939313766303030303133653835613563383461
3730623661323238360a373164336430613336346637303263623664323665316663336432666165
3939
Encryption successful
De uitvoer kan je rechtstreeks in een vars-bestand (bv. group_vars/all.yml) plakken naast de niet-gevoelige variabelen:
ansible_user: ubuntu
ansible_connection: ssh
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
38633964303966623933323763623866386335376239613464613361623139386161386664323365
...
Het !vault-label vertelt Ansible dat deze waarde at runtime gedecrypteerd moet worden. De rest van het bestand blijft ongeëncrypteerd en is gewoon leesbaar.
Je kan bij encrypt_string ook verwijzen naar een vault-wachtwoordbestand zodat je niet interactief een wachtwoord moet ingeven:
ansible-vault encrypt_string 'MijnGeheimWachtwoord' --name 'db_password' --vault-password-file=~/.vault_pass.txt
Nogmaals proficiat! Je bent nu in staat om zelf je eigen Ansible-projecten aan te vatten! Veel succes!!!