# Ansibleのuserモジュールでパスワードをソルト指定なしのpassword_hash()で生成すると毎回changedになる

2019/05/29

掲題の通り。恥ずかしながらソルトという概念を知らずにべき等性の闇に飲まれてはまったのでメモ。

こんなRoleがあったとします。

  • tasks/main.yml
---
- name: add the user 'jenkins'
  user:
    name: jenkins
    group: jenkins
    shell: /bin/bash
    password: "{{ vaulted_passwd }}"
    state: present
...
1
2
3
4
5
6
7
8
9
  • vars/main.yml(実際はこのファイルにansible-vaultを書けてファイルごと暗号化しています)
---
vaulted_passwd: "{{ 'thisispassword' | password_hash('sha512') }}"
...
1
2
3

Ansibleのuserモジュールの公式doc (opens new window)にもある通り、userモジュールでパスワードを指定する際は、パスワードを平文ではなくハッシュ(“crypted value”)化して記載します。これまで公式doc見て何も疑問を持たず脳死でこれやってた。

んで今日気付いたのですが、このRoleをansible-playbookでかけると毎回changedになります。でも普通に同じユーザ名/パスワードでログインはできる。おかしいなと思ったら、password_hash()でソルトの指定をしていなかったからなんですね。

Unix系のパスワード管理には/etc/shadowというファイルが利用されます。このファイルは、ユーザ名とハッシュアルゴリズム、ソルト、ソルトとパスワードを組み合わせてからハッシュ関数をかけたものが使用されます。Ansibleはこの/etc/shadowを直接操作するため、ソルトを指定してあげないと実行のたびにハッシュ値が変わり、/etc/shadowが変更されるのでchangedになるのですね。

参考:

【CentOS】/etc/shadowのハッシュ化パスワードについて - よくわからないエンジニア (opens new window)

Linux の UNIX パスワード認証について調べた - CUBE SUGAR CONTAINER (opens new window)

vars/main.ymlでpassword_hashフィルタをかけるときにソルトを指定してやることで、changedが出なくなる。Ansible公式doc (opens new window)にやり方自体は書いてありました。当時はきちんとこれを読んでからRoleを作った作ったはずなのですが、知らない単語「salt」を脳内フィルタかけて読み飛ばしていたみたいですね……

  • vars/main.yml
---
vaulted_passwd: "{{ 'thisispassword' | password_hash('sha512', 'thisissalt') }}"
...
1
2
3

本当に恥の多い人生を送っています。