【问题标题】:How do I create a user and set a password using ansible?如何使用 ansible 创建用户并设置密码?
【发布时间】:2013-03-05 18:45:24
【问题描述】:

documentation 指的是我们的 github example,但这有点稀疏和神秘。

上面写着:

# created with:
# crypt.crypt('This is my Password', '$1$SomeSalt')
password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.

crypt.crypt 不会发出示例显示的内容。它还使用 MD5。

我试过了:

# python
import crypt
crypt.crypt('This is my Password', '$6$somereallyniceandbigrandomsalt$')
>> '$69LxCegsnIwI'

但是用户的密码字段应该是这样的:

password: $6$somereallyniceandbigrandomsalt$UqddPX3r4kH3UL5jq5/ZI.

其中包括三个 $ 分隔符,分隔 6(表示它是 SHA-512 哈希)、salt 和加密密码。

请注意,python crypt docs 没有提及任何关于 $N 格式的内容。

问题:

  1. 提供给crypt.crypt 的盐是应该以尾随$ 结尾还是$N$SALT 格式? p>

  2. Python 文档引用了 DES,但如何调用 SHA-512 或 MD5?相关文档在哪里?

  3. 我真的应该获取crypt.crypt 的输出并切断第一个$6 并制作$N$SALT$CRYPTED?这是ansible需要的吗?

【问题讨论】:

  • A1 : 在盐中尾随 $ 没有任何区别
  • 与 Ansible IRC 人员交谈过,您应该根据您从 Github github.com/ansible/ansible/issues/2305 获得的反馈更新并回答此问题
  • 反馈没有解决问题。我仍然无法使用 ansible 创建密码。尽管有更多信息要添加,但我会更新问题。谢谢提醒
  • 对不起stackoverflow.com/users/1937270/syb0rg,但我刚刚回滚了您的编辑。您删除了链接,其余更改只是大小写更改,其中一些导致语法不正确。这对问题没有任何帮助。

标签: cryptography pycrypto ansible


【解决方案1】:

文档中显示的 python 示例取决于您使用的操作系统上运行的 crypt 版本。

我在 OS X 上生成了 crypt,我的目标服务器是 ubuntu。

由于操作系统提供 crypt 的实现方式不同,导致结果不同且不兼容。

改用这个:

http://pythonhosted.org/passlib/

Passlib 是 Python 2 和 3 的密码哈希库,它提供 超过 30 种密码哈希算法的跨平台实现, 以及管理现有密码哈希的框架。它的 设计用于广泛的任务,从验证哈希 在 /etc/shadow 中找到,为 多用户应用程序。

>>> # import the hash algorithm
>>> from passlib.hash import sha512_crypt

>>> # generate new salt, and hash a password
>>> hash = sha512_crypt.encrypt("password")
>>> hash

'$6$rounds=656000$BthPsosdEpqOM7Qd$l/ln9nyEfxM67ea8Bvb79JoW50pGjf6iM87taIvfSmpjasE4/wBG1.60pFS6W992T7Q1q2wikMbxYUvMHD1tT1'

【讨论】:

  • 我该如何处理这个输出字符串?我应该把它放在哪里以及这个字符串的哪一部分?您能否提供使用此字符串的示例 ansible 剧本?
  • 是否需要将 ' 替换为 " 以便在 yml 中使用它?
  • 谢谢!我把它做成了一个脚本,包含在我的项目中,以使 macOS 用户不必求助于谷歌。我在下面的答案中包含了脚本。 stackoverflow.com/a/45105252/117471
【解决方案2】:

这已在Ansible docs 中更新。有两种首选方式:

如何为用户模块生成加密密码?

大多数 Linux 系统上可用的 mkpasswd 实用程序是一个不错的选择:

mkpasswd --method=SHA-512 如果您的电脑上没有安装此实用程序 系统(例如,您使用的是 OS X),那么您仍然可以轻松生成 这些密码使用 Python。一、确保Passlib密码 哈希库已安装。

pip install passlib

库准备就绪后,SHA512 密码值 然后可以生成如下:

python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"

【讨论】:

    【解决方案3】:

    这对我有用(使用 python 2.7.4):

    python
    >>> import crypt
    >>> crypt.crypt('thisismypassword', '$6$Som3S@lt$')
    '$6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.'
    

    我有一个看起来像这样的 vars.yml:

    ---
    password: $6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.
    

    还有一个这样的 playbook.yml:

    ---
    - hosts: vagrant
      vars_files:
        - vars.yml
      user: vagrant
    
      tasks:
      - name: create artefactual user
        user: name=artefactual state=present password={{password}} shell=/bin/bash
    

    我使用 vagrant vagrant up 运行我的剧本,然后从另一个控制台我可以使用 ansible 创建的人工用户使用密码 thisismypassword SSH 到新创建的虚拟机。

    我只是将 crypt.crypt 的输出复制到名为 password 的 ansible 变量中并使用它。您在问题中显示的 crypt 输出看起来太短了,我不确定您为什么会这样,也许是不同版本的 python?

    【讨论】:

    • 查看我刚刚发布的答案。使用 python crypt 不能跨平台迁移。
    【解决方案4】:

    您可以使用能够处理加密密码生成的 jinja2 过滤器。这是一个使用提供的密码创建 linux 用户的工作示例:

    - name: Creating Linux User
      user:
        name: "{{ myuser }}" 
        password: "{{ mypassword | password_hash('sha512') }}"
    

    希望这会对您和其他人有所帮助。

    【讨论】:

    • 较少跨平台,仅适用于 ubuntu。 Crypt 随 python 一起提供并且适用于所有。
    • 谢谢! MacOS 支持这种方式。
    【解决方案5】:

    我把@felix's answer 做成了一个脚本,我可以将它包含在我正在处理的 docker 项目中。我知道很多开发人员都使用 macOS/OSX,并且该平台上没有 mkpasswd,所以我将他们保存为谷歌搜索。

    我添加了以下选项:

    • PROCESS_TIME (布尔值)
      • 启用带有轮数和 CPU 时间的第二行输出
    • ROUNDS (整数)
      • 覆盖default_rounds 值,该值被调整为在“平均”系统上花费约 300 毫秒。您需要至少 100 毫秒,但应该尽可能长。
    #!/usr/bin/env python3
    
    # Because OSX doesn't have mkpasswd...
    
    # Based on https://stackoverflow.com/a/17992126/117471
    # python3 -c "from passlib.hash import sha512_crypt; print(sha512_crypt.encrypt(input()))" <<< bruno  # NOQA
    
    # Usage:
    #
    # $ ./mkpasswd.py
    # Password:
    # $6$rounds=656000$pfFmQISGcjWHOCxW$rBptiSK.tqSPnUiq6KiSHzz6LvvW/x1SjkkWFwxWB9Dt75NLNBs0N3OyGV4K5ejjBs/u.o3jtigvUKbmmwVQP.
    #
    # $ PROCESS_TIME=1 ./mkpasswd.py
    # Password:
    # $6$rounds=656000$e0OGrad82DBrUo9T$ldqtOdN54gmXI6nb0D.Y5mm5ih.LIQm/Ep/bkNL76.3hE65FqXA9wyZ.M5YOrv6dSvwhPAktXGJ6LJT0Fgd4x.
    # 656000 rounds in 1.008705 seconds of cpu time
    #
    # $ ROUNDS=1280000 PROCESS_TIME=1 ./mkpasswd.py <<< bruno
    # $6$rounds=1280000$QO5FSyw5rQpiY6PI$0zRMJ4RzCbH61XxIdpsUm/79.VZ13Mm9TBN9GvJwt1LI1U5FVzakrLya5VJsXlTou3p5ZeWmo29bIUjubRuc31
    # 1280000 rounds in 1.9206560000000001 seconds of cpu time
    
    import os
    import sys
    import time
    from getpass import getpass
    from passlib.hash import sha512_crypt
    
    rounds = os.environ.get('ROUNDS')
    if not rounds:
        rounds = sha512_crypt.default_rounds
    
    passwd = input() if not sys.stdin.isatty() else getpass()
    
    proc = sha512_crypt.using(rounds=rounds)
    start = time.process_time()
    out = proc.encrypt(passwd)
    end = time.process_time()
    
    print(out)
    
    if os.environ.get('PROCESS_TIME'):
        print('{} rounds in {} seconds of cpu time'.format(rounds, end-start))
    

    【讨论】:

    • 仅使用散列函数是不够的,仅添加盐对提高安全性无济于事。而是使用随机盐在 HMAC 上迭代大约 100 毫秒,然后将盐与哈希一起保存。使用PBKDF2Rfc2898DeriveBytesBcrypt 等函数或类似函数。关键是让攻击者花费大量时间通过蛮力寻找密码。
    • 我不确定你的意思,但我怀疑这可能与输出的 $6$rounds=656000$ 部分有关。我想摆脱它。它在 python 中与crypt.crypt 一起工作得更好,但是使用操作系统的 crypt 并且 macOS 附带的那个是不够的。您对如何使用passlib.readthedocs.io/en/stable 执行您所说的操作有什么建议吗?
    • “工作得更好”是指生成的输出与mkpasswd -m sha-512(包括随机盐)一致。我根据passlib.readthedocs.io/en/stable/narr/… 选择了passlib.hash.sha512_crypt.encrypt,它应该符合您的标准。它很慢,因为它需要超过 1 秒的实时时间和 0.026 秒的系统时间。
    • Python passlib.hash.sha512_crypt 是一个很好的解决方案,但 rounds 需要设置为占用大约 100 毫秒 CPU 时间的值。
    • @zaph 我已经更新了代码以证明default_rounds 轮次确实足够。我还包括了我认为您会喜欢的选项。我会很感激你的支持。这是我在 SO 答案中投入的最大努力,试图扭转否决票。
    【解决方案6】:

    我一直在使用下面的 shell 命令来设置密码。

    - name: "Set user password: someuser"
      command: 'echo "somepassword"| passwd --stdin "someuser"'
      sudo: yes
    

    【讨论】:

      【解决方案7】:

      这样试试

      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"
      

      【讨论】:

        【解决方案8】:

        这需要在目标主机上安装pwgen

        - name: generate linux user password
          local_action: shell /usr/bin/pwgen 16 1
          register: generated_linux_user_password
        

        使用hosts: localhostset_fact 和主机变量,如果您需要全局可用的“变量”(事实在创建后是只读的):

        {{hostvars['localhost']["new_fact"]}}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-25
          • 1970-01-01
          • 2013-10-18
          • 1970-01-01
          • 1970-01-01
          • 2016-08-31
          • 1970-01-01
          相关资源
          最近更新 更多