diff --git a/content/post/2019-01-19-updating-passwords-with-ansible.md b/content/post/2019-01-19-updating-passwords-with-ansible.md new file mode 100644 index 0000000..de92a93 --- /dev/null +++ b/content/post/2019-01-19-updating-passwords-with-ansible.md @@ -0,0 +1,171 @@ +--- +title: "Updating passwords with Ansible" +date: 2019-01-19T00:00:00+01:00 +draft: false +share: false +--- + +I've recently migrated from [KeePassXC](https://keepassxc.org/) to [Bitwarden_RS](https://github.com/dani-garcia/bitwarden_rs) (which I highly recommend, by the way) to manage my passwords. + +I figured it was an opportunity to update passwords I hadn't changed in... *years*. My Linux users' passwords were among those. + +Instead of updating them manually on each machine, I thought there might be a way to do so with Ansible, and since it turns out there is, I thought I might as well share it here! + +**Please be careful when it comes to password modification automation. You might end up locking yourself out of your servers.** + +## Generating password hashes + +First thing first, we'll need to generate `passwd` compatible password hashes for our users. + +In this example, I'll generate a hash for the *P@ssw0rd* password : +``` +mkpasswd -m sha-512 +Password: +$6$wAVPV.Coc$o3FNxs9EPgXF54hv1BeKtfoMnLwE5VATL71jlHQHeVyCaevnnxfSp/x1UbJ00F3qlyyfUAmscuGXImoHmXBFa. +``` + +You might notice you'll get a different result if you run the same command again : +``` +mkpasswd -m sha-512 +Password: +$6$iFBWJD3300m$CYZJRSfZ4scHYNI9ggqe8WYef7Qym2Oi5ycgb64VsbU3.WM1GoJYlh1sawENTD7nrXVCthvs8LRPw1CVjzkP71 +``` + +That's because, unless you specify it, the salt used by `mkpasswd` to encrypt the password is random. + +You can choose a salt with the `-S` parameter if you want : +``` +mkpasswd -m sha-512 -S hmmmsalt +Password: +$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/ + +mkpasswd -m sha-512 -S hmmmsalt +Password: +$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/ +captainark@heimdall ~ % +``` + +## Ansible vault + +Passwords are *secrets*. Even if there are hashed, you don't want them to be publicly accessible. + +If, like me, your Ansible configuration is in a git repository, you should not commit them in an unencrypted file. + +Ansible offers a way to encrypt a file containing variables with the `ansible-vault` command. + +We first have to create a vault : +``` +cd /your/ansible/project +mkdir -p group_vars/all/ +ansible-vault create group_vars/all/vault.yml +New Vault password: +Confirm New Vault password: +``` + +As you can see, the command will ask you to provide a password for the vault. It will then open the file in your `$EDITOR` (that'll be `vim` if you're a cool kid). + +The file is like any Ansible vault file. I'll create a variable for the `root` and `captainark` users in my case : +```yaml +vault_captainarkpwd: "$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/" +vault_rootpwd: "$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/" +``` + +An [Ansible best practice](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#variables-and-vaults) is to prepend all variables that are stored in a vault with the `vault_` prefix. It makes where they are stored clear when reading through a playbook. + +Once saved, if you try to `cat` the file, you won't be able to see its actual content : +``` +cat group_vars/all/vault.yml +$ANSIBLE_VAULT;1.1;AES256 +32393530376537323233633636316330373136316265316662646437393533376135666232656366 +3335623863333865666133666634633233616531636634370a663965356466383039326262313066 +62633434396465313666333032663130343434326665386333323733633062613832653530393761 +6333653338393231640a623938616634626462653965613766313335386136333362313033363735 +64313662623039363365326639633231306335366432306361613837656364356464373837656565 +61636538376262333762376235306337303531386638643632316361323037393230366537393132 +35373861373863613666303531353737373130353330643535353238633665653236633130653064 +39346330326566633262613535386633613565633566623934613066613238353739386133346535 +64643762333462653966633363653439633037373161316663646261663764393332653732656335 +61373462666336343533333162663637656236333739633065623939323937663137376431346231 +38653338386539383663613230656165313566363733396134386366626430313235343264643938 +64306163353437366362616166666565316663366163346565313436343537366330363932303038 +37653138643165353138393466343063666535313933663066633832353331643838356539303533 +61626237356538353261326136613239336662346337363331393037623863623433336432353461 +32356136316339623139346330333235363331653634373836333730653436636563323134616337 +36643433356133376138 +``` + +To view the variables in the file, you can use the `ansible-vault view` command : + +```yaml +ansible-vault view group_vars/all/vault.yml +Vault password: +vault_captainarkpwd: "$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/" +vault_rootpwd: "$6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/" +``` + +To edit the vault's content, you can use the `ansible-vault edit group_vars/all/vault.yml` command. + +## The playbook + +Now that our vault is ready, all that's left is to run the following playbook : + +```yaml +--- +- hosts: all + become: yes + become_method: sudo + + tasks: + - name: PASSWORDS | Check if the captainark user exists + shell: id -u captainark + register: captainark_exists + ignore_errors: true + + - name: PASSWORDS | Update captainark password + user: + name: captainark + password: "{{ vault_captainarkpwd }}" + update_password: always + when: captainark_exists.rc == 0 + + - name: PASSWORDS | Create captainark user + user: + name: captainark + password: "{{ vault_captainarkpwd }}" + shell: /usr/bin/zsh + uid: 1000 + groups: adm,sudo,apps + when: captainark_exists.rc != 0 + + - name: PASSWORDS | Update root password + user: + name: root + password: "{{ vault_rootpwd }}" + update_password: always +``` + +I've called this playbook `passwords.yml`. To run it, I simply execute the following command : +``` +ansible-playbook passwords.yml --ask-vault-pass +``` + +The command asks for the vault password to decrypt its contents. + +The playbook will first check if the `captainark` user exists, and it will update its password if it does. If it doesn't, the user will be created with the defined options. + +Since the `root` user should always exist, the playbook changes its password without checking. + +**N.B. :** If you've decided to store your vault somewhere else, you might need to add a task at the beginning of the playbook to load it, like so : + +```yaml + - name: PASSWORDS | Load the vault + include_vars: /path/to/your/vault.yml +``` + +## Conclusion + +That's all! As always, I hope someone finds this article useful! + +If you do, please let me know in the comments here, on [Twitter](https://twitter.com/captainark) or on the [Fediverse](https://social.captainark.net/users/captainark/)! + +Also, if you have any questions, feel free to hit me up on my [Rocket.Chat](https://chat.captainark.net) instance! Hopefully I'll write about it in the future! diff --git a/public/2018/12/03/debian-repos-over-https/index.html b/public/2018/12/03/debian-repos-over-https/index.html index dea68bd..b228b40 100644 --- a/public/2018/12/03/debian-repos-over-https/index.html +++ b/public/2018/12/03/debian-repos-over-https/index.html @@ -345,6 +345,13 @@ deb https://deb.debian.org/debian stretch-backports main contrib non-free