使用Ansible创建新用户和密码

rap*_*tle 92 bash shell ubuntu ansible

我有一个ansible任务,在ubuntu 12.04上创建一个新用户;

- name: Add deployment user
    action: user name=deployer password=mypassword
Run Code Online (Sandbox Code Playgroud)

它按预期完成,但当我以该用户身份登录并尝试使用我设置的密码sudo时,它总是说它不正确.我究竟做错了什么?

thi*_*ter 156

我可能来不及回复这个问题,但最近我发现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 }}"
Run Code Online (Sandbox Code Playgroud)

"uusername"和"upassword"被传递--extra-vars给剧本,并注意我在这里使用了jinja2过滤器来加密传递的密码.

我已将以下与此相关的教程添加到我的博客中

  • 根据@MichaelWyraz的建议:添加第二个"盐"参数可以避免"改变".您可以通过变量设置它,例如`password = {{upassword | password_hash('sha512',upassword_salt)}}`.这可以让你把盐放在[变量库](https://docs.ansible.com/ansible/playbooks_vault.html)中,因为你可能也会使用`upassword`,将两者都放在tasks.yml之外. (10认同)
  • 这是正确的答案.投票!谢谢! (7认同)
  • 为了避免该项始终"更改",您可以在password_hash中添加一个秘密"salt"作为第二个参数. (6认同)
  • 感谢您的好榜样,这使我走上了正确的道路。尽管如此,我还必须做更多的事情才能让它在 ansible 版本 2.8.2 的 Mac 上工作。首先,在 Mac 上无法使用 crypt,因此需要使用“pip install passlib”安装 passlib 库。然后,为了能够使用内联保险库加密字符串,我必须添加以下内容重新格式化:`password: {{ uppassword | 字符串| 密码哈希('sha512')}}`。这可以避免错误消息“秘密必须是 unicode 或字节,而不是 ansible.parsing.yaml.objects.AnsibleVaultEncryptedUnicode” (2认同)

Mxx*_*Mxx 92

如果您阅读Ansible的user模块手册,它将引导您访问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}}
Run Code Online (Sandbox Code Playgroud)

如果您的playbook或ansible命令行以明文形式显示密码,则表示您的影子文件中记录的密码哈希是错误的.这意味着当您尝试使用密码进行身份验证时,其哈希将永远不会匹配.

另外,请参阅Ansible 常见问题解答,了解密码参数的一些细微差别以及如何正确使用它.

  • 谢谢你的提示.我只想指出上面链接的用户模块文档建议使用`openssl passwd -salt <salt> -1 <plaintext>`生成密码哈希,而不是上面的Python单行.我从Python获得正确的输出时遇到了一些麻烦,可能是由于我自己的无能而且openssl命令工作得更好. (23认同)
  • 如何同步与操作系统一起使用的盐? (6认同)
  • @Breedly:没有必要 - salt总是作为密码的一部分存储($ 1 $ thesalt $ thepasswordhash),这意味着它可以在使用相同哈希函数的操作系统之间移植 (5认同)
  • 使用此python命令生成哈希对我不起作用。但是在使用`passwd &lt;user&gt;`手动设置密码后,我在`/ etc / shadow`中找到了哈希。 (3认同)

mad*_*ead 41

我想提出另一个解决方案:

- 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
Run Code Online (Sandbox Code Playgroud)

为什么它更好?就像这里已经注意到的那样,Ansible游戏应该是幂等的.你应该把它们看作是命令式风格中的一系列动作,而不是像期望的状态,陈述式风格.因此,您应该能够多次运行它并获得相同的结果,相同的服务器状态.

这听起来很棒,但也有一些细微差别.其中之一是管理用户."期望状态"意味着每次运行创建用户的游戏时,他都会更新以完全匹配该状态.通过"更新"我的意思是他的密码也将被更改.但最有可能的不是你需要的东西.通常,您只需要创建一次用户,设置和过期他的密码,进一步的游戏运行不应该更新他的密码.

幸运的是,Ansible update_passworduser模块中具有解决此问题的属性.将此与已注册的变量混合使用,只有在用户实际更新时,您才能使其密码失效.

请注意,如果您手动更改用户的shell(假设您不喜欢邪恶的管理员在其游戏中强制使用的shell),则用户将被更新,因此他的密码将过期.

另请注意如何在播放中轻松使用纯文本初始密码.无需在其他地方对它们进行编码并粘贴哈希,您可以使用Jinja2过滤器.但是,如果有人在您最初​​做之前登录,这可能是一个安全漏洞.

  • 我无法让其他解决方案为我工作.但你的回答很简单而且很有效.如果可以的话,我想给你5个赞成票. (2认同)

bba*_*iee 11

Ansible'用户'模块以幂等方式管理用户.在下面的剧本中,第一个任务为用户声明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
Run Code Online (Sandbox Code Playgroud)


小智 10

试试这样

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"
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案,因为它允许在脚本运行时输入密码.对于不应每次都运行的引导脚本的好解决方案.对于Ubuntu,我使用了"sha512_crypt". (2认同)

小智 6

我尝试了许多实用程序mkpasswd,包括Python等,但似乎Ansible在读取其他工具生成的HASH值时存在一些兼容性问题。所以最终它通过 Ansible # value 本身起作用了。

ansible all -i localhost, -m debug -a "msg={{ 'yourpasswd' | password_hash('sha512', 'mysecretsalt') }}"
Run Code Online (Sandbox Code Playgroud)

剧本:

- name: User creation
  user: 
    name: username  
    uid: UID
    group: grpname
    shell: /bin/bash
    comment: "test user"
    password: "$6$mysecretsalt$1SMjoVXjYf.3sJR3a1WUxlDCmdJwC613.SUD4DOf40ASDFASJHASDFCDDDWERWEYbs8G00NHmOg29E0"
Run Code Online (Sandbox Code Playgroud)


McK*_*vin 5

此答案中的角色的目的是为new_user_name生成随机密码并立即使密码到期.new_user_name需要在他/她的第一次登录时更改密码.

create_user.yml:

---
# create_user playbook

- hosts: your_host_group
  become: True
  user: ansible

  roles:
    - create_user
Run Code Online (Sandbox Code Playgroud)

角色/ 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
Run Code Online (Sandbox Code Playgroud)

如果要创建新用户:

ansible-playbook -i hosts.ini create_user.yml --extra-vars "new_user_name=kelvin"
Run Code Online (Sandbox Code Playgroud)