简体   繁体   English

从 Ansible Playbook 创建用户密码

[英]Creating user passwords from an Ansible Playbook

I'm sure someone here can solve my problem.我相信这里有人可以解决我的问题。 I am creating users on hosts that are defined in my Ansible hosts file.我在 Ansible 主机文件中定义的主机上创建用户。 BUT when the users wish to login, the root user needs to define the user password.但是当用户希望登录时,root 用户需要定义用户密码。 I need to automate the creation of user passwords.我需要自动创建用户密码。

To create user passwords with a playbook we can't specify the password in clear text, we can only do that by supplying a hash:要使用剧本创建用户密码,我们不能以明文形式指定密码,我们只能通过提供哈希来实现:

 - name: Add Users + Assign to Group
   user:
      name: "{{ item }}"
      password: $6$ul4TACYvHI.kmGUK$j32lU8fNbX.eW0DZOqnnDlP8i0...

To create the hash, the 1st step is to define the password by logging into the target server as root, and then use python-crypt to create the hash.要创建哈希,第一步是通过以 root 身份登录目标服务器来定义密码,然后使用 python-crypt 创建哈希。 Once running the command, the terminal will then provide the hash, which I paste into the playbook.运行命令后,终端将提供哈希,我将其粘贴到剧本中。 ( in the below example, the password is “ansible”) (在下面的例子中,密码是“ansible”)

python -c 'import crypt; print crypt.crypt("ansible")'

When I run the playbook against the target server, I can then login as the user that the playbook created with the password I defined using python-crypt (in this case I login as user2 with the password “ansible” )当我针对目标服务器运行剧本时,我可以以剧本创建的用户身份登录,并使用我使用 python-crypt 定义的密码(在这种情况下,我以 user2 身份登录,密码为“ansible”)

login as: user2

user1@10.65.8.50's password: "ansible"


[user1@hostname ~]$

This means that I have to create the hash in the terminal of the server where I am creating users, then copy and paste that hash into the playbook.这意味着我必须在创建用户的服务器的终端中创建散列,然后将该散列复制并粘贴到剧本中。 Not too much trouble if I have one server but If I am running the playbook against 100 servers then I need to log in to 100 servers as root and create 100 hashes then define all of those hashes in the playbook, which is not very automated!如果我有一台服务器并不会太麻烦,但是如果我在 100 台服务器上运行剧本,那么我需要以 root 身份登录到 100 个服务器并创建 100 个哈希,然后在剧本中定义所有这些哈希,这不是很自动化!

So what is needed is the ability to execute python-crypt from the playbook, grep the hash that is created, then put this in the playbook.所以需要的是从剧本中执行 python-crypt 的能力,grep 创建的哈希,然后把它放在剧本中。 Do you have any ideas on how to do this?你对如何做到这一点有什么想法吗? not even specifically in Ansible, I don't expect you guys to write the playbook for me.甚至不是专门在 Ansible 中,我不希望你们为我编写剧本。 Maybe think about how you would do this in your tool of choice, eg PowerShell.也许考虑一下您将如何在您选择的工具中执行此操作,例如 PowerShell。 Once I have an understanding of the process then I can translate it to a playbook.一旦我了解了这个过程,我就可以将其翻译成剧本。

Any help is much appreciated!任何帮助深表感谢!

This is sort of a far out answer, and I have not tested this, but I've been considering a way of using ansible-vault in an automated way so that I can deploy an application without defining passwords beforehand , while keeping an encrypted record of the password once it's created.这是一个很远的答案,我还没有测试过,但我一直在考虑一种以自动化方式使用ansible-vault的方法,这样我就可以在不预先定义密码的情况下部署应用程序,同时保留加密记录创建后的密码。

The playbook below shows one way that you might:下面的剧本显示了您可能的一种方式:

  • generate a password on the remote host,在远程主机上生成密码,
  • use that password on the remote host,在远程主机上使用该密码,
  • store an encrypted copy of that password on the local (control) system.在本地(控制)系统上存储该密码的加密副本。

Again, this is untested and it's possible it can't work for some reason I haven't anticipated, but I actually think it should be able to work like this (only relevant tasks shown):同样,这是未经测试的,它可能由于某种我没有预料到的原因而无法工作,但我实际上认为它应该能够像这样工作(仅显示相关任务):

ansible.cfg ansible.cfg

vault_password_file = /path/to/vault_password_file

playbook.yml剧本.yml

---
- hosts: example_com
  gather_facts: true
  become: true

  vars:
    password_var_name: "example_com_db_password"
    vault_vars_file: "example_com_vault.yml"

  tasks:
    - name: Find out if we have already set a password.
      command: "grep \"'password' => '',\" settings.php"
      args:
        chdir: "/path/to/settings"
      register: password_in_file

    - name: Create a password and use ansible-vault to write it.
      block:
        - name: Create a new password.
          command: "apg -a1 -m32 -n1"
          register: new_vault_password
          no_log: true

        - name: Encrypt the new password.
          command: "ansible-vault encrypt \"{{ new_vault_password.stdout }}\""
          register: new_vault_password_encrypted
          no_log: true

        - name: Write the encrypted password to our local ansible-vault file.
          lineinfile:
            path: "{{ playbook_dir }}/{{ vault_file }}"
            line: "{{ password_var_name }}: {{ new_vault_password_encrypted.stdout }}"
            insertafter: "EOF"
          when: password_in_file.stdout = 0
          delegate_to: localhost

        - name: Write the unencrypted password into our remote settings file.
          lineinfile:
            path: "/path/to/settings/settings.php"
            line: "  'password' => '{{ new_password.stdout }}',"
            regexp: "^  'password' => '',$"
          no_log: true

So the tldr for this is that:所以这个 tldr 是:

  • we have an Ansible config file ansible.cfg .我们有一个 Ansible 配置文件ansible.cfg
  • that file contains the path to our ansible-vault password file.该文件包含我们的ansible-vault密码文件的路径。
  • We have a local unencrypted file for dynamic Ansible variables.我们有一个用于动态 Ansible 变量的本地未加密文件。
  • we check to see if we need to proceed with creating a new password etc.我们检查是否需要继续创建新密码等。
  • if so, we create a password.如果是这样,我们创建一个密码。
  • then we encrypt it.然后我们加密它。
  • then we write the unencrypted password to the settings file.然后我们将未加密的密码写入设置文件。
  • then we write the encrypted password to our local , un -encrypted variables file.然后我们将加密的密码写入本地加密的变量文件。

Set your password in a variable like FAP, add it to your script to create the user:在像 FAP 这样的变量中设置您的密码,将其添加到您的脚本中以创建用户:

  - name: "Encrypt password for target system"
    command: "python -c 'import crypt; print crypt.crypt(\"{{ FAP }}\")'"
    register: EFAP
  - name: "Add user USER1"
    user: name="USER1" state="present" password="{{ EFAP.stdout }}"

I've tested this with a complex password and works fine我已经用复杂的密码测试过这个并且工作正常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM