问题描述
我有一个麻烦的任务,它在ubuntu 12.04上创建了一个新用户;
- name: Add deployment user
action: user name=deployer password=mypassword
它可以按预期完成,但是当我以该用户身份登录并尝试使用我设置的密码sudo时,它总是表示不正确。我究竟做错了什么?
最佳回答
如果您阅读了user
模块的Ansible手册,它将带您到Ansible-examples github repo,以获取有关如何使用password
参数的详细信息。
在那里,您将看到密码必须经过哈希处理。
- 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命令行的纯文本密码为as-is,则意味着影子文件中记录的密码哈希错误。这意味着当您尝试使用密码进行身份验证时,其哈希值将永远不匹配。
另外,有关密码参数的一些细微差别以及如何正确使用它,请参阅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剧本应该是幂等的。您不应将它们视为命令式风格的一系列动作,而应将其视为所需状态,声明式风格。因此,您应该能够多次运行它,并获得相同的结果,相同的服务器状态。
听起来不错,但有一些细微差别。其中之一是管理用户。 “Desired state”意味着每次您运行创建用户的剧本时,他都会被更新为与该状态完全匹配。通过”updated”,我的意思是他的密码也将被更改。但很可能不是您所需要的。通常,您只需要创建用户,设置一次密码和使其密码过期就可以,以后的播放不应更新其密码。
幸运的是,Ansible在user
模块中具有update_password
属性,可以解决此问题。将此密码与registered variables混合使用,也只能在实际更新用户时使他的密码失效。
请注意,如果您手动更改用户的 shell 程序(假设您不喜欢邪恶管理员在其游戏中强制使用的 shell 程序),则该用户将被更新,因此其密码将过期。
还要注意如何在剧本中轻松使用纯文本初始密码。无需在其他地方对其进行编码并粘贴哈希,则可以使用Jinja2 filter。但是,如果有人在您初次登录之前碰巧登录,则可能是安全漏洞。
第四种回答
Ansible ‘user’模块以幂等方式管理用户。在下面的剧本中,第一个任务为用户声明state = present。请注意,第一个操作中的’register: newuser’帮助第二个操作确定用户是新用户(newuser.changed == True)还是现有用户(newuser.changed==False
),仅生成一次密码。
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
角色/create_user /任务/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
第九种回答
为了完整起见,我将使用ansable发布ad-hoc命令,因为那里也有一个问题。
首先,尝试使用大多数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
)的错误