Creating a new user and password with Ansible

后端 未结 22 1395
迷失自我
迷失自我 2020-12-22 17:00

I have an ansible task which creates a new user on ubuntu 12.04;

- name: Add deployment user
    action: user name=deployer password=mypassword
相关标签:
22条回答
  • 2020-12-22 17:19

    try like this

    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"
    
    0 讨论(0)
  • 2020-12-22 17:19

    This is the easy way:

    ---
    - 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
    
    0 讨论(0)
  • 2020-12-22 17:23

    How to create encrypted password for passing to password var to Ansible user task (from @Brendan Wood's comment):

    openssl passwd -salt 'some_plain_salt' -1 'some_plain_pass'
    

    The result will look like:

    $1$some_pla$lmVKJwdV3Baf.o.F0OOy71
    

    Example of user task:

    - name: Create user
      user: name="my_user" password="$1$some_pla$lmVKJwdV3Baf.o.F0OOy71"
    

    UPD: crypt using SHA-512 see here and here:

    Python

    $ python -c "import crypt, getpass, pwd; print crypt.crypt('password', '\$6\$saltsalt\$')"
    
    $6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
    

    Perl

    $ perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
    
    $6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
    

    Ruby

    $ ruby -e 'puts "password".crypt("$6$saltsalt$")'
    
    $6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
    
    0 讨论(0)
  • 2020-12-22 17:26

    I want to propose yet another solution:

    - 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
    

    Why it is better? Like already has been noted here, Ansible plays should be idempotent. You should think of them not as a sequence of actions in imperative style, but like a desired state, declarative style. As a result you should be able to run it multiple times and get the same result, the same server state.

    This all sounds great, but there are some nuances. One of them is managing users. "Desired state" means that every time you run a play that creates a user he will be updated to match exactly that state. By "updated" I mean that his password will be changed too. But most probably it is not what you need. Usually, you need to create user, set and expire his password only once, further play runs shouldn't update his password.

    Fortunately, Ansible has update_password attribute in user module that solves this issue. Mixing this with registered variables you can also expire his password only when the user is actually updated.

    Note that if you change user's shell manually (suppose, you don't like the shell that evil admin forced in his play) the user will be updated, thus his password will be expired.

    Also note how you can easily use plain text initial passwords in plays. No need to encode them somewhere else and paste hashes, you can use Jinja2 filter for that. However, this can be a security flaw if someone happens to login before you initially do.

    0 讨论(0)
  • 2020-12-22 17:26

    The Ansible 'user' module manages users, in the idempotent way. In the playbook below the first task declares state=present for the user. Note that 'register: newuser' in the first action helps the second action to determine if the user is new (newuser.changed==True) or existing (newuser.changed==False), to only generate the password once.

    The Ansible playbook has:

    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
    
    0 讨论(0)
  • 2020-12-22 17:29

    Neither of the solutions worked directly on my Mac controlling Ubuntu. So for others' sake, combining Mxx and JoelB answers, here is the current Python 3 solution:

    pip3 install passlib
    
    python3 -c 'from passlib.hash import md5_crypt; \
          print(md5_crypt.encrypt("This is my Password", salt="SomeSalt"))'
    

    The result will be $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI., as in Mxx' answer.

    Better still, use SHA512 instead of MD5:

    python3 -c 'from passlib.hash import sha512_crypt; \
          print(sha512_crypt.encrypt("This is my Password", salt="SomeSalt"))' 
    

    Result:

    $6$rounds=656000$SomeSalt$oYpmnpZahIsvn5FK8g4bDFEAmGpEN114Fe6Ko4HvinzFaz5Rq2UXQxoJZ9ZQyQoi9zaBo3gBH/FEAov3FHv48

    0 讨论(0)
提交回复
热议问题