Ubuntu 12.04で新しいユーザーを作成するansibleタスクがあります。
- name: Add deployment user
action: user name=deployer password=mypassword
期待どおりに完了しますが、そのユーザーとしてログインし、パスワードを使用してSudoを試行すると、常に間違っていると表示されます。何が間違っていますか?
user
module のAnsibleのマニュアルを読むと、Ansible-examples github repo の詳細な使用方法 password
parameter にアクセスできます。
ここで、パスワードをハッシュする必要があることがわかります。
- hosts: all
user: root
vars:
# created with:
# python -c 'import crypt; print crypt.crypt("This is my Password", "$1$SomeSalt$")'
password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.
tasks:
- user: name=tset password={{password}}
プレイブックまたはansibleコマンドラインにパスワードがプレーンテキストのままである場合、これはshadowファイルに記録されたパスワードハッシュが間違っていることを意味します。つまり、パスワードで認証しようとすると、そのハッシュは一致しません。
また、パスワードパラメータの微妙な違いとその正しい使用方法については、Ansible FAQ を参照してください。
返信するには遅すぎるかもしれませんが、最近、jinja2フィルターには暗号化されたパスワードの生成を処理する機能があることがわかりました。 main.yml
では、暗号化されたパスワードを次のように生成しています。
- name: Creating user "{{ uusername }}" with admin access
user:
name: {{ uusername }}
password: {{ upassword | password_hash('sha512') }}
groups: admin append=yes
when: assigned_role == "yes"
- name: Creating users "{{ uusername }}" without admin access
user:
name: {{ uusername }}
password: {{ upassword | password_hash('sha512') }}
when: assigned_role == "no"
- name: Expiring password for user "{{ uusername }}"
Shell: chage -d 0 "{{ uusername }}"
「uusername」と「upassword」は--extra-vars
としてプレイブックに渡され、渡されたパスワードを暗号化するためにここでjinja2フィルターを使用したことに注意してください。
これに関連するチュートリアルをブログに追加しました
さらに別の解決策を提案したい:
- name: Create madhead user
user:
name: madhead
password: "{{ 'password' | password_hash('sha512') }}"
Shell: /bin/zsh
update_password: on_create
register: madhead
- name: Force madhead to change password
Shell: chage -d 0 madhead
when: madhead.changed
なぜそれが良いのですか?ここですでに述べたように、Ansibleプレイはべき等でなければなりません。それらは命令型スタイルのアクションのシーケンスとしてではなく、望ましい状態の宣言型スタイルのように考える必要があります。その結果、複数回実行して同じ結果、同じサーバー状態を取得できるはずです。
これはすべて素晴らしく聞こえますが、いくつかのニュアンスがあります。それらの1つはユーザーの管理です。 「望ましい状態」とは、ユーザーを作成するプレイを実行するたびに、その状態に一致するように更新されることを意味します。 「更新」とは、彼のパスワードも変更されることを意味します。しかし、おそらくそれはあなたが必要とするものではありません。通常、ユーザーを作成し、パスワードの設定と有効期限を1回だけ設定する必要があります。さらにプレイを実行してもパスワードは更新されません。
幸いなことに、Ansibleの user
module にはupdate_password
属性があり、この問題を解決します。これを 登録済み変数 と混合すると、ユーザーが実際に更新されたときにのみパスワードを失効させることもできます。
ユーザーのシェルを手動で変更すると(悪の管理者がプレイで強制したシェルが気に入らない場合)、ユーザーが更新されるため、パスワードが期限切れになることに注意してください。
また、プレイでプレーンテキストの初期パスワードを簡単に使用する方法にも注意してください。他の場所にエンコードしてハッシュを貼り付ける必要はありません。そのために Jinja2 filter を使用できます。ただし、最初にログインする前に誰かがログインした場合、これはセキュリティ上の欠陥になる可能性があります。
Ansible 'user'モジュールはidempotentの方法でユーザーを管理します。以下のプレイブックでは、最初のタスクがユーザーに対してstate = presentを宣言しています。最初のアクションの「register:newuser」は、2回目のアクションでユーザーが新規(newuser.changed == True)か既存(newuser.changed==False
)かを判断し、パスワードを1回だけ生成するのに役立ちます。
Ansibleプレイブックには次のものがあります。
tasks:
- name: create deployment user
user:
name: deployer
createhome: yes
state: present
register: newuser
- name: generate random password for user only on creation
Shell: /usr/bin/openssl Rand -base64 32 | passwd --stdin deployer
when: newuser.changed
このようにしてみて
vars_Prompt:
- name: "user_password"
Prompt: "Enter a password for the user"
private: yes
encrypt: "md5_crypt" #need to have python-passlib installed in local machine before we can use it
confirm: yes
salt_size: 7
- name: "add new user" user: name="{{user_name}}" comment="{{description_user}}" password="{{user_password}}" home="{{home_dir}}" Shell="/bin/bash"
この回答のロールの目的は、new_user_nameのランダムパスワードを生成し、パスワードをすぐに期限切れにすることです。 new_user_nameは、最初のログオン時にパスワードを変更するために必要です。
create_user.yml:
---
# create_user playbook
- hosts: your_Host_group
become: True
user: ansible
roles:
- create_user
roles/create_user/tasks/main.yml:
---
# Generate random password for new_user_name and the new_user_name
# is required to change his/her password on first logon.
- name: Generate password for new user
Shell: makepasswd --chars=20
register: user_password
- name: Generate encrypted password
Shell: mkpasswd --method=SHA-512 {{ user_password.stdout }}
register: encrypted_user_password
- name: Create user account
user: name={{ new_user_name }}
password={{ encrypted_user_password.stdout }}
state=present
append=yes
Shell="/bin/bash"
update_password=always
when: new_user_name is defined and new_user_name in uids
register: user_created
- name: Force user to change password
Shell: chage -d 0 {{ new_user_name }}
when: user_created.changed
- name: User created
debug: msg="Password for {{ new_user_name }} is {{ user_password.stdout }}"
when: user_created.changed
新しいユーザーを作成する場合:
ansible-playbook -i hosts.ini create_user.yml --extra-vars "new_user_name=kelvin"
これは簡単な方法です:
---
- name: Create user
user: name=user Shell=/bin/bash home=/srv/user groups=admin,Sudo generate_ssh_key=yes ssh_key_bits=2048
- name: Set password to user
Shell: echo user:plain_text_password | Sudo chpasswd
no_log: True
これは私のために働いた方法です
- hosts: main
vars:
# created with:
# python -c "from passlib.hash import sha512_crypt; print sha512_crypt.encrypt('<password>')"
# above command requires the PassLib library: Sudo pip install passlib
- password: '$6$rounds=100000$H/83rErWaObIruDw$DEX.DgAuZuuF.wOyCjGHnVqIetVt3qRDnTUvLJHBFKdYr29uVYbfXJeHg.IacaEQ08WaHo9xCsJQgfgZjqGZI0'
tasks:
- user: name=spree password={{password}} groups=Sudo,www-data Shell=/bin/bash append=yes
Sudo: yes
完全を期すために、ansibleを使用してアドホックコマンドを投稿します。
まず、ほとんどのLinuxシステムで利用可能なmkpasswdユーティリティを使用して、暗号化されたパスワードを生成してみてください。
mkpasswd --method=SHA-512
次に、ansible ad-hockコマンドを試してください。
ansible all -m user -a 'name=testuser Shell=/bin/bash \
comment="Test User" password=$6$XXXX' -k -u admin --Sudo
ただし、次のことを確認してください。
--Sudo
で実行するか、(useradd: cannot lock /etc/passwd; try again later
)のようなエラーが発生しますプレイブックで秘密鍵を使用するためにansible-vaultを使用できます。 ymlでパスワードを定義します。
例パス:秘密または
user:
pass: secret
name: fake
で秘密ファイルを暗号化します:
ansible-vault encrypt /path/to/credential.yml
ansibleは暗号化のためにパスワードを要求します。 (そのパスの使用方法を説明します)
そして、必要な場所で変数を使用できます。誰もボールトキーなしでそれらを読むことができません。
Vaultキーの使用法:
プレイブックの実行時に引数を渡すことにより。
--ask-vault-pass: secret
または、password.txtなどのファイルに保存して、どこかに隠すことができます。 (CIユーザーに有用)
--vault-password-file=/path/to/file.txt
あなたの場合:vars ymlを含め、変数を使用します。
- include_vars: /path/credential.yml
- name: Add deployment user
action: user name={{user.name}} password={{user.pass}}
上記のいくつかのソリューションを組み合わせて、暗号化されたローカルansibleボールトファイルに保存されたプレーンテキストパスワードに基づいて正しいパスワードハッシュを自動的に生成するプレイブックを作成しました。
---
- hosts: [your hosts]
tasks:
- include_vars: [path to your encrypted vault file]
- local_action: "command openssl passwd -salt '{{password_salt}}' -1 '{{password}}'"
register: password_hash
- user: >
name=[your username]
state=present
password="{{password_hash.stdout}}"
「--ask-vault-pass」オプションを使用してこのコマンドを実行し、ボールトファイルを復号化します(暗号化されたボールトの管理方法については、ansible-vaultを参照してください)。
ser module のタスク定義は、最新のAnsibleバージョンで異なる必要があります。
tasks:
- user: name=test password={{ password }} state=present
パスワード認証を許可するLinuxアカウントを作成できるansible-playbookを作成しました。
CreateLinuxAccountWithAnsible を参照してください。
ハッシュされたパスワードは、mkpasswd
コマンドを使用して生成されます。異なるオペレーティングシステムにmkpasswd
をインストールする方法を提供しました。
スクリプトを使用するために必要な手順は次のとおりです。
<your_user_name>
と<your_password>
内のrun.sh
を希望のユーザー名とパスワードに置き換えます。
Ansibleがマシンに接続してユーザーを作成できるように、inventory
の接続情報を変更します。
./run.sh
を実行して、スクリプトを実行します。
Mxxの答えは正しいですが、異なるオペレーティングシステムが関与している場合、python crypt.crypt()
メソッドは安全ではありません(システムで使用されるglibcハッシュアルゴリズムに関連)。
たとえば、MacOSからハッシュを生成し、Linuxでプレイブックを実行する場合は機能しません。そのような場合、passlib(pip install passlib
を使用してローカルにインストールできます)。
from passlib.hash import md5_crypt
python -c 'import crypt; print md5_crypt.encrypt("This is my Password,salt="SomeSalt")'
'$1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.'
どちらのソリューションも、Ubuntuを制御するMacで直接機能しませんでした。他の人のために、MxxとJoelBの回答を組み合わせて、現在のPython 3ソリューションがあります:
pip3 install passlib
python3 -c 'from passlib.hash import md5_crypt; \
print(md5_crypt.encrypt("This is my Password", salt="SomeSalt"))'
結果は、Mxxの答えのように$1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.
になります。
より良い、MD5の代わりにSHA512を使用:
python3 -c 'from passlib.hash import sha512_crypt; \
print(sha512_crypt.encrypt("This is my Password", salt="SomeSalt"))'
結果:
$ 6 $ rounds = 656000 $ SomeSalt $ oYpmnpZahIsvn5FK8g4bDFEAmGpEN114Fe6Ko4HvinzFaz5Rq2UXQxoJZ9ZQyQoi9zaBo3gBH/FEAov3FHv48
ユーザーのランダムパスワードの生成
最初にユーザー変数を定義する必要があり、次に以下に従う
タスク:
- name: Generate Passwords
become: no
local_action: command pwgen -N 1 8
with_items: '{{ users }}'
register: user_passwords
- name: Update User Passwords
user:
name: '{{ item.item }}'
password: "{{ item.stdout | password_hash('sha512')}}"
update_password: on_create
with_items: '{{ user_passwords.results }}'
- name: Save Passwords Locally
become: no
local_action: copy content={{ item.stdout }} dest=./{{ item.item }}.txt
with_items: '{{ user_passwords.results }}'
password
varからAnsible user
タスクに渡すための暗号化されたパスワードを作成する方法(@Brendan Woodのコメントより):
openssl passwd -salt 'some_plain_salt' -1 'some_plain_pass'
結果は次のようになります。
$1$some_pla$lmVKJwdV3Baf.o.F0OOy71
user
タスクの例:
- name: Create user
user: name="my_user" password="$1$some_pla$lmVKJwdV3Baf.o.F0OOy71"
UPD:SHA-512を使用した暗号化 here および here :を参照
$ python -c "import crypt, getpass, pwd; print crypt.crypt('password', '\$6\$saltsalt\$')"
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
$ Perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
$ Ruby -e 'puts "password".crypt("$6$saltsalt$")'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
Mkpasswd、Pythonなどを含む多くのユーティリティを試してみました。しかし、他のツールによって生成されたHASH値を読み込む際にAnsibleとの互換性の問題があるようです。最後に、それはansible#値自体によって機能しました。
ansible all -i localhost、-m debug -a "msg = {{'yourpasswd' | password_hash( 'sha512'、 'mysecretsalt')}}"
プレイブック-
- name: User creation
user:
name: username
uid: UID
group: grpname
Shell: /bin/bash
comment: "test user"
password: "$6$mysecretsalt$1SMjoVXjYf.3sJR3a1WUxlDCmdJwC613.SUD4DOf40ASDFASJHASDFCDDDWERWEYbs8G00NHmOg29E0"
私はパーティーに遅れていることを知っていますが、私が使用している別のソリューションがあります。 passwdバイナリに--stdin
を持たないディストリビューションに便利かもしれません。
- hosts: localhost
become: True
tasks:
- name: Change user password
Shell: "yes '{{ item.pass }}' | passwd {{ item.user }}"
loop:
- { pass: 123123, user: foo }
- { pass: asdf, user: bar }
loop_control:
label: "{{ item.user }}"
loop_control
のラベルは、印刷を担当しますのみユーザー名。プレイブック全体またはユーザー変数(vars_files:
を使用できます)は、ansible-vaultで暗号化する必要があります。
私の解決策は、ルックアップを使用し、パスワードを自動的に生成します。
---
- hosts: 'all'
remote_user: root
gather_facts: no
vars:
deploy_user: deploy
deploy_password: "{{ lookup('password', '/tmp/password chars=ascii_letters') }}"
tasks:
- name: Create deploy user
user:
name: "{{ deploy_user }}"
password: "{{ deploy_password | password_hash('sha512') }}"
これをAnsibleアドホックコマンドとして実行する場合は、次の操作を実行できます。
$ password='SomethingSecret!'
$ ansible 192.168.1.10 -i some_inventory -b -m user -a "name=joe_user \
update_password=always password=\"{{ \"$password\" | password_hash('sha512') }}\""
上記のコマンドからの出力:
192.168.1.10 | SUCCESS => {
"append": false,
"changed": true,
"comment": "Joe User",
"group": 999,
"home": "/home/joe_user",
"move_home": false,
"name": "joe_user",
"password": "NOT_LOGGING_PASSWORD",
"Shell": "/bin/bash",
"state": "present",
"uid": 999
}