2019-01-19 21:53:11 +01:00
<!DOCTYPE html>
< html lang = "en-us" >
< head >
< meta charset = "utf-8" / >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" / >
< meta name = "twitter:card" content = "summary" / >
< meta name = "twitter:title" content = "Updating passwords with Ansible" / >
< meta name = "twitter:description" content = "" / >
< meta name = "twitter:site" content = "@" / >
< meta property = "og:title" content = "Updating passwords with Ansible · Sysadmining. All day. Every day." / >
< meta property = "og:site_name" content = "Sysadmining. All day. Every day." / >
2024-12-28 13:38:22 +01:00
< meta property = "og:url" content = "https://blog.captainark.net/2019/01/19/updating-passwords-with-ansible/" / >
2019-01-19 21:53:11 +01:00
< meta property = "og:image" content = "/images/cover.jpg" / >
< meta property = "og:description" content = "" / >
< meta property = "og:type" content = "article" / >
< meta property = "article:published_time" content = "2019-01-19T00:00:00+01:00" / >
< title > Updating passwords with Ansible · Sysadmining. All day. Every day.< / title >
< meta name = "description" content = "I&rsquo;ve recently migrated from KeePassXC to Bitwarden_RS ( which I highly recommend , by the way ) to manage my passwords .
I figured it was an opportunity to up" />
< meta name = "HandheldFriendly" content = "True" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" / >
2024-12-28 13:38:22 +01:00
< link rel = "apple-touch-icon" sizes = "180x180" href = "https://blog.captainark.net/apple-touch-icon.png" >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "https://blog.captainark.net/favicon-32x32.png" >
< link rel = "icon" type = "image/png" sizes = "16x16" href = "https://blog.captainark.net/favicon-16x16.png" >
< link rel = "manifest" href = "https://blog.captainark.net/site.webmanifest" >
< link rel = "mask-icon" href = "https://blog.captainark.net/safari-pinned-tab.svg" color = "#5bbad5" >
2019-01-26 14:45:34 +01:00
< meta name = "msapplication-TileColor" content = "#9f00a7" >
< meta name = "theme-color" content = "#ffffff" >
2019-01-19 21:53:11 +01:00
2024-12-28 13:38:22 +01:00
< link rel = "stylesheet" type = "text/css" href = "https://blog.captainark.net/css/screen.css" / >
< link rel = "stylesheet" type = "text/css" href = "https://blog.captainark.net/css/nav.css" / >
2019-01-19 21:53:11 +01:00
< link rel = "stylesheet" type = "text/css" href = "https://fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400|Inconsolata:700,400" / >
< link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/solarized-light.min.css" integrity = "sha384-bFKDPkG3geCujYJIbPornilfOgmYQoPS45Oh/8daqqo1SUwNY06OeHorpgnNvx82" crossorigin = "anonymous" >
< script src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js" integrity = "sha384-BlPof9RtjBqeJFskKv3sK3dh4Wk70iKlpIe92FeVN+6qxaGUOUu+mZNpALZ+K7ya" crossorigin = "anonymous" > < / script >
2024-12-28 13:38:22 +01:00
< script type = "text/javascript" src = "https://blog.captainark.net/js/hjsload.js" > < / script >
2019-01-19 21:53:11 +01:00
2024-12-28 13:38:22 +01:00
< link href = "https://blog.captainark.net/index.xml" rel = "alternate" type = "application/rss+xml" title = "Sysadmining. All day. Every day." / >
2019-01-19 21:53:11 +01:00
2019-02-21 18:20:24 +01:00
< meta name = "generator" content = "Hugo 0.54.0" / >
2019-01-19 21:53:11 +01:00
2024-12-28 13:38:22 +01:00
< link rel = "canonical" href = "https://blog.captainark.net/2019/01/19/updating-passwords-with-ansible/" / >
2019-01-19 21:53:11 +01:00
< script type = "application/ld+json" >
{
"@context": "https://schema.org",
"@type": "Article",
"publisher": {
"@type": "Organization",
"name": ,
2024-12-28 13:38:22 +01:00
"logo": https://blog.captainark.net/images/logo.png
2019-01-19 21:53:11 +01:00
},
"author": {
"@type": "Person",
"name": ,
"image": {
"@type": "ImageObject",
2024-12-28 13:38:22 +01:00
"url": https://blog.captainark.net/images/author.jpg,
2019-01-19 21:53:11 +01:00
"width": 250,
"height": 250
},
2024-12-28 13:38:22 +01:00
"url": https://blog.captainark.net,
2019-01-19 21:53:11 +01:00
"sameAs": [
],
"description": Geek | Gamer | TV Shows Aficionado
},
"headline": Updating passwords with Ansible,
"name": Updating passwords with Ansible,
"wordCount": 708,
"timeRequired": "PT4M",
"inLanguage": {
"@type": "Language",
"alternateName": en
},
2024-12-28 13:38:22 +01:00
"url": https://blog.captainark.net/2019/01/19/updating-passwords-with-ansible/,
2019-01-19 21:53:11 +01:00
"datePublished": 2019-01-19T00:00Z,
"dateModified": 2019-01-19T00:00Z,
"description": ,
"mainEntityOfPage": {
"@type": "WebPage",
2024-12-28 13:38:22 +01:00
"@id": https://blog.captainark.net/2019/01/19/updating-passwords-with-ansible/
2019-01-19 21:53:11 +01:00
}
}
< / script >
2021-10-10 01:04:20 +02:00
< script data-goatcounter = "https://stats.captainark.net/count"
async src="//stats.captainark.net/count.js">< / script >
2019-01-19 21:53:11 +01:00
2019-03-02 20:54:50 +01:00
< link rel = "stylesheet" href = "https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity = "sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin = "anonymous" >
2019-01-19 21:53:11 +01:00
< / head >
< body class = "nav-closed" >
< div class = "nav" >
< h3 class = "nav-title" > Menu< / h3 >
< a href = "#" class = "nav-close" >
< span class = "hidden" > Close< / span >
< / a >
< ul >
< h3 > This site< / h3 >
< li class = "nav-opened" role = "presentation" >
2024-12-28 13:38:22 +01:00
< a href = "https://blog.captainark.net/" > Home< / a >
2019-01-19 21:53:11 +01:00
< / li >
< li class = "nav-opened" role = "presentation" >
2024-12-28 13:38:22 +01:00
< a href = "https://blog.captainark.net/about" > About< / a >
2019-01-19 21:53:11 +01:00
< / li >
< li class = "nav-opened" role = "presentation" >
2024-12-28 13:38:22 +01:00
< a href = "https://blog.captainark.net/resume" > Resume< / a >
2019-01-19 21:53:11 +01:00
< / li >
< h3 > Other services< / h3 >
< li class = "nav-opened" role = "presentation" >
2019-03-09 11:25:21 +01:00
< a href = "https://chat.captainark.net" > Rocket.Chat< / a >
2019-01-19 21:53:11 +01:00
< / li >
< li class = "nav-opened" role = "presentation" >
2019-03-09 11:25:21 +01:00
< a href = "https://notes.captainark.net" > CodiMD< / a >
< / li >
< li class = "nav-opened" role = "presentation" >
< a href = "https://git.captainark.net" > Gitea< / a >
2019-01-19 21:53:11 +01:00
< / li >
< li class = "nav-opened" role = "presentation" >
< a href = "https://paste.captainark.net" > Privatebin< / a >
< / li >
< li class = "nav-opened" role = "presentation" >
2019-03-09 11:25:21 +01:00
< a href = "https://pics.captainark.net" > Pics< / a >
2019-01-19 21:53:11 +01:00
< / li >
< / ul >
2024-12-28 13:38:22 +01:00
< a class = "subscribe-button icon-feed" href = "https://blog.captainark.net/index.xml" > Subscribe< / a >
2019-01-19 21:53:11 +01:00
< / div >
< span class = "nav-cover" > < / span >
< div class = "site-wrapper" >
< header class = "main-header post-head no-cover" >
< nav class = "main-nav clearfix" >
2024-12-28 13:45:37 +01:00
< a class = "blog-logo" href = "https://blog.captainark.net/" > < img src = "https://blog.captainark.net/images/logo.png" alt = "Home" / > < / a >
2019-01-19 21:53:11 +01:00
< a class = "menu-button" href = "#" > < span class = "burger" > ☰ < / span > < span class = "word" > Menu< / span > < / a >
< / nav >
< / header >
< main class = "content" role = "main" >
< article class = "post post" >
< header class = "post-header" >
< h1 class = "post-title" > Updating passwords with Ansible< / h1 >
< small > < / small >
< section class = "post-meta" >
< time class = "post-date" datetime = "2019-01-19T00:00:00+01:00" >
19 January 2019
< / time >
< / section >
< / header >
< section class = "post-content" >
< p > I’ ve recently migrated from < a href = "https://keepassxc.org/" > KeePassXC< / a > to < a href = "https://github.com/dani-garcia/bitwarden_rs" > Bitwarden_RS< / a > (which I highly recommend, by the way) to manage my passwords.< / p >
< p > I figured it was an opportunity to update passwords I hadn’ t changed in… < em > years< / em > . My Linux users’ passwords were among those.< / p >
< p > 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!< / p >
< p > < strong > Please be careful when it comes to password modification automation. You might end up locking yourself out of your servers.< / strong > < / p >
< h2 id = "generating-password-hashes" > Generating password hashes< / h2 >
< p > First thing first, we’ ll need to generate < code > passwd< / code > compatible password hashes for our users.< / p >
< p > In this example, I’ ll generate a hash for the < em > P@ssw0rd< / em > password :< / p >
< pre > < code > mkpasswd -m sha-512
Password:
$6$wAVPV.Coc$o3FNxs9EPgXF54hv1BeKtfoMnLwE5VATL71jlHQHeVyCaevnnxfSp/x1UbJ00F3qlyyfUAmscuGXImoHmXBFa.
< / code > < / pre >
< p > You might notice you’ ll get a different result if you run the same command again :< / p >
< pre > < code > mkpasswd -m sha-512
Password:
$6$iFBWJD3300m$CYZJRSfZ4scHYNI9ggqe8WYef7Qym2Oi5ycgb64VsbU3.WM1GoJYlh1sawENTD7nrXVCthvs8LRPw1CVjzkP71
< / code > < / pre >
< p > That’ s because, unless you specify it, the salt used by < code > mkpasswd< / code > to encrypt the password is random.< / p >
< p > You can choose a salt with the < code > -S< / code > parameter if you want :< / p >
< pre > < code > 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 ~ %
< / code > < / pre >
< h2 id = "ansible-vault" > Ansible vault< / h2 >
< p > Passwords are < em > secrets< / em > . Even if there are hashed, you don’ t want them to be publicly accessible.< / p >
< p > If, like me, your Ansible configuration is in a git repository, you should not commit them in an unencrypted file.< / p >
< p > Ansible offers a way to encrypt a file containing variables with the < code > ansible-vault< / code > command.< / p >
< p > We first have to create a vault :< / p >
< pre > < code > cd /your/ansible/project
mkdir -p group_vars/all/
ansible-vault create group_vars/all/vault.yml
New Vault password:
Confirm New Vault password:
< / code > < / pre >
< p > As you can see, the command will ask you to provide a password for the vault. It will then open the file in your < code > $EDITOR< / code > (that’ ll be < code > vim< / code > if you’ re a cool kid).< / p >
< p > The file is like any Ansible vault file. I’ ll create a variable for the < code > root< / code > and < code > captainark< / code > users in my case :< / p >
< pre > < code class = "language-yaml" > vault_captainarkpwd: " $6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/"
vault_rootpwd: " $6$hmmmsalt$RwZR2r9W5cSv5bVgeSFPX0rJiovWOD5kMDFey1xPR6JtasqQZqHTiuW5JoQ.0VCW6oNHJlgOYJ.auhl82gfX8/"
< / code > < / pre >
< p > An < a href = "https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#variables-and-vaults" > Ansible best practice< / a > is to prepend all variables that are stored in a vault with the < code > vault_< / code > prefix. It makes where they are stored clear when reading through a playbook.< / p >
< p > Once saved, if you try to < code > cat< / code > the file, you won’ t be able to see its actual content :< / p >
< pre > < code > 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
< / code > < / pre >
< p > To view the variables in the file, you can use the < code > ansible-vault view< / code > command :< / p >
< pre > < code class = "language-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/"
< / code > < / pre >
< p > To edit the vault’ s content, you can use the < code > ansible-vault edit group_vars/all/vault.yml< / code > command.< / p >
< h2 id = "the-playbook" > The playbook< / h2 >
< p > Now that our vault is ready, all that’ s left is to run the following playbook :< / p >
< pre > < code class = "language-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
< / code > < / pre >
< p > I’ ve called this playbook < code > passwords.yml< / code > . To run it, I simply execute the following command :< / p >
< pre > < code > ansible-playbook passwords.yml --ask-vault-pass
< / code > < / pre >
< p > The command asks for the vault password to decrypt its contents.< / p >
< p > The playbook will first check if the < code > captainark< / code > user exists, and it will update its password if it does. If it doesn’ t, the user will be created with the defined options.< / p >
< p > Since the < code > root< / code > user should always exist, the playbook changes its password without checking.< / p >
< p > < strong > N.B. :< / strong > 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 :< / p >
< pre > < code class = "language-yaml" > - name: PASSWORDS | Load the vault
include_vars: /path/to/your/vault.yml
< / code > < / pre >
< h2 id = "conclusion" > Conclusion< / h2 >
< p > That’ s all! As always, I hope someone finds this article useful!< / p >
< p > If you do, please let me know in the comments here, on < a href = "https://twitter.com/captainark" > Twitter< / a > or on the < a href = "https://social.captainark.net/users/captainark/" > Fediverse< / a > !< / p >
< p > Also, if you have any questions, feel free to hit me up on my < a href = "https://chat.captainark.net" > Rocket.Chat< / a > instance! Hopefully I’ ll write about it in the future!< / p >
< / section >
< footer class = "post-footer" >
< figure class = "author-image" >
2024-12-28 13:38:22 +01:00
< a class = "img" href = "https://blog.captainark.net/" style = "background-image: url(/images/author.jpg)" > < span class = "hidden" > Antoine Joubert's Picture< / span > < / a >
2019-01-19 21:53:11 +01:00
< / figure >
< section class = "author" >
2024-12-28 13:38:22 +01:00
< h4 > < a href = "https://blog.captainark.net/" > Antoine Joubert< / a > < / h4 >
2019-01-19 21:53:11 +01:00
< p > Geek | Gamer | TV Shows Aficionado< / p >
< div class = "author-meta" >
< span class = "author-location icon-location" > Angers, France< / span >
2024-12-28 13:45:37 +01:00
< span class = "author-link icon-link" > < a href = "https://blog.captainark.net" > https://blog.captainark.net< / a > < / span >
2019-01-19 21:53:11 +01:00
< / div >
< / section >
<!-- isso -->
2024-12-28 13:45:37 +01:00
< script data-isso = "https://blog.captainark.net/comments/" src = "https://blog.captainark.net/comments/js/embed.min.js" > < / script >
2019-01-19 21:53:11 +01:00
< noscript > Please enable JavaScript to view comments< / noscript >
< section id = "isso-thread" > < / section >
<!-- end isso -->
< / footer >
< / article >
< / main >
< aside class = "read-next" >
2024-12-28 13:38:22 +01:00
< a class = "read-next-story prev" style = "no-cover" href = "https://blog.captainark.net/2018/12/03/debian-repos-over-https/" >
2019-01-19 21:53:11 +01:00
< section class = "post" >
< h2 > Debian repos over HTTPS< / h2 >
< / section >
< / a >
< / aside >
< center >
< a class = "fa-icons" href = "mailto:contact@captainark.net" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-envelope fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://twitter.com/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-twitter fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://social.captainark.net/users/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-mastodon-alt fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://github.com/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-github fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://www.last.fm/user/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-lastfm fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://steamcommunity.com/id/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-steam fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< a class = "fa-icons" href = "https://www.twitch.tv/captainark" >
< span class = "fa-stack fa-lg" >
< i class = "fa fa-circle fa-stack-2x" > < / i >
< i class = "fa fa-twitch fa-stack-1x fa-inverse" > < / i >
< / span >
< / a >
< / center >
< footer class = "site-footer clearfix" >
< section class = "copyright" > < a href = "" > Sysadmining. All day. Every day.< / a > © 2015 - 2019< / section >
< section class = "poweredby" > Proudly generated by < a class = "icon-hugo" href = "http://gohugo.io" > HUGO< / a > , with < a class = "icon-theme" href = "https://github.com/vjeantet/hugo-theme-casper" > Casper< / a > theme< / section >
< / footer >
< / div >
< script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" integrity = "sha384-CgeP3wqr9h5YanePjYLENwCTSSEz42NJkbFpAFgHWQz7u3Zk8D00752ScNpXqGjS" crossorigin = "anonymous" > < / script >
< script src = "https://cdnjs.cloudflare.com/ajax/libs/fitvids/1.1.0/jquery.fitvids.min.js" integrity = "sha384-2/VQUb0aZHixKnNLh7pD38DZk+acGpEw5LeHieWVDPR0h/H326kp/1qnRPDYmFXM" crossorigin = "anonymous" > < / script >
2024-12-28 13:38:22 +01:00
< script type = "text/javascript" src = "https://blog.captainark.net/js/index.js" > < / script >
2019-01-19 21:53:11 +01:00
< / body >
< / html >