code

Ansible로 새 사용자 및 암호 생성

codestyles 2020. 9. 4. 07:29
반응형

Ansible로 새 사용자 및 암호 생성


우분투 12.04에서 새 사용자를 만드는 ansible 작업이 있습니다.

- name: Add deployment user
    action: user name=deployer password=mypassword

예상대로 완료되지만 해당 사용자로 로그인하고 암호로 sudo를 시도하면 항상 잘못되었다고 설정합니다. 내가 뭘 잘못하고 있죠?


user모듈대한 Ansible의 매뉴얼을 읽으면 parameter 사용 방법에 대한 자세한 내용을 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 명령 줄에 일반 텍스트로 된 암호가있는 경우 이는 섀도우 파일에 기록 된 암호 해시 가 잘못 되었음을 의미합니다 . 즉, 암호로 인증을 시도하면 해시가 일치하지 않습니다.

또한 암호 매개 변수의 일부 뉘앙스와이를 올바르게 사용하는 방법에 대해서는 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 플레이는 멱 등성이어야합니다. 명령형의 일련의 동작이 아니라 원하는 상태, 선언적 스타일로 생각해야합니다. 결과적으로 여러 번 실행하고 동일한 결과, 동일한 서버 상태를 얻을 수 있어야합니다.

이 모든 것이 훌륭하게 들리지만 약간의 뉘앙스가 있습니다. 그중 하나는 사용자를 관리하는 것입니다. "원하는 상태"는 사용자를 생성하는 플레이를 실행할 때마다 해당 상태와 정확히 일치하도록 업데이트됨을 의미합니다. "업데이트 됨"이란 그의 비밀번호도 변경된다는 것을 의미합니다. 그러나 아마도 그것은 당신이 필요로하는 것이 아닙니다. 일반적으로 사용자를 생성하고 비밀번호를 한 번만 설정 및 만료해야하며, 추가 플레이를 실행해도 비밀번호를 업데이트하면 안됩니다.

다행히 Ansible 은이 문제를 해결 update_password하는 user모듈에 속성을 가지고 있습니다. 이것을 등록 된 변수 와 혼합 하면 사용자가 실제로 업데이트 될 때만 그의 암호를 만료시킬 수도 있습니다.

사용자의 셸을 수동으로 변경하면 (예를 들어 악의적 인 관리자가 자신의 플레이에서 강제 한 셸이 마음에 들지 않는다고 가정) 사용자가 업데이트되므로 암호가 만료됩니다.

또한 연극에서 일반 텍스트 초기 암호를 쉽게 사용할 수있는 방법에 유의하십시오. 다른 곳에서 인코딩하고 해시를 붙여 넣을 필요가 없습니다 . Jinja2 필터사용할 수 있습니다 . 그러나 처음 로그인하기 전에 누군가가 로그인하는 경우 보안 결함이 될 수 있습니다.


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

roles / create_user / tasks / 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

완성을 위해 ansible을 사용하여 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

그러나 다음 사항을 확인하십시오.

  1. 명령은 작은 따옴표로 묶여 있고 이중이 아닙니다. 그렇지 않으면 암호가 작동하지 않습니다.
  2. 함께 실행 --sudo하거나 ( useradd: cannot lock /etc/passwd; try again later) 와 같은 오류가 발생합니다.

사용자 모듈 의 작업 정의 는 최신 Ansible 버전에서 달라야합니다.

tasks:
  - user: name=test password={{ password }} state=present

위의 몇 가지 솔루션을 결합하여 암호화 된 로컬 ansible 볼트 파일에 저장된 일반 텍스트 암호를 기반으로 올바른 암호 해시를 자동으로 생성하는 플레이 북을 만들었습니다.

---
- hosts: [your hosts]
  tasks:
  - include_vars: [path to your encrypted vault file]
  - local_action: "command openssl passwd -salt '{{password_salt}}' -1 '{{password}}'"
    register: password_hash
  - user: >
        name=[your username]
        state=present
        password="{{password_hash.stdout}}"

"--ask-vault-pass"옵션을 사용하여이 명령을 실행하여 볼트 파일의 암호를 해독합니다 (암호화 된 볼트 관리 방법에 대한 정보는 ansible-vault 참조).


플레이 북에서 비밀 키를 사용하기 위해 ansible-vault를 사용할 수 있습니다. yml에서 비밀번호를 정의하십시오.

전의. 통과 : 비밀 또는

user:
  pass: secret
  name: fake

다음으로 비밀 파일을 암호화하십시오.

ansible-vault encrypt /path/to/credential.yml

ansible은 암호화를 위해 암호를 묻습니다. (이 패스 사용 방법을 설명하겠습니다)

그런 다음 원하는 곳에서 변수를 사용할 수 있습니다. 볼트 키 없이는 아무도 읽을 수 없습니다.

Vault 키 사용 :

플레이 북을 실행할 때 인수 전달을 통해.

--ask-vault-pass: secret

또는 password.txt와 같은 파일에 저장하고 어딘가에 숨길 수 있습니다. (CI 사용자에게 유용)

--vault-password-file=/path/to/file.txt

귀하의 경우 : vars yml을 포함하고 변수를 사용하십시오.

- include_vars: /path/credential.yml

  - name: Add deployment user
    action: user name={{user.name}} password={{user.pass}}

사용자에 대한 임의 비밀번호 생성

먼저 사용자 변수를 정의한 다음 아래를 따라야합니다.

작업 :

- name: Generate Passwords
  become: no
  local_action: command pwgen -N 1 8
  with_items: '{{ users }}'
  register: user_passwords

- name: Update User Passwords
  user:
    name: '{{ item.item }}'
    password: "{{ item.stdout | password_hash('sha512')}}"
    update_password: on_create
  with_items: '{{ user_passwords.results }}'

- name: Save Passwords Locally
  become: no
  local_action: copy content={{ item.stdout }} dest=./{{ item.item }}.txt
  with_items: '{{ user_passwords.results }}'

passwordvar에 Ansible user작업 에 전달하기 위해 암호화 된 암호를 만드는 방법 (@Brendan Wood의 의견에서) :

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

결과는 다음과 같습니다.

$1$some_pla$lmVKJwdV3Baf.o.F0OOy71

user작업 :

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

UPD : SHA-512를 사용한 crypt here and here 참조 :

파이썬

$ 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 -e 'puts "password".crypt("$6$saltsalt$")'

$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/

Mxx의 대답은 정확하지만 crypt.crypt()다른 운영 체제가 관련되어있을 때 파이썬 방법은 안전하지 않습니다 (시스템에서 사용되는 glibc 해시 알고리즘 관련).

예를 들어 MacOS에서 해시를 생성하고 Linux에서 플레이 북을 실행하면 작동하지 않습니다. 이 경우 passlib를 사용 pip install passlib하여 로컬로 설치할 수 있습니다 .

from passlib.hash import md5_crypt
python -c 'import crypt; print md5_crypt.encrypt("This is my Password,salt="SomeSalt")'
'$1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.'

두 솔루션 모두 Ubuntu를 제어하는 ​​Mac에서 직접 작동하지 않았습니다. 따라서 다른 사람들을 위해 Mxx 및 JoelB 답변을 결합하여 현재 Python 3 솔루션은 다음과 같습니다.

pip3 install passlib

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

결과는 $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.Mxx의 대답과 같이입니다.

더 나은 방법 은 MD5 대신 SHA512를 사용하는 것입니다.

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

결과:

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


암호 인증을 허용하는 Linux 계정을 만들 수있는 ansible 플레이 북을 만들었습니다.

CreateLinuxAccountWithAnsible을 참조하십시오 .

해시 된 암호는 mkpasswd명령을 사용하여 생성됩니다 . mkpasswd다른 운영 체제에 설치하는 방법을 제공했습니다 .

내 스크립트를 사용하는 데 필요한 단계는 다음과 같습니다.

  1. 교체 <your_user_name><your_password>내부 run.sh원하는 사용자 이름과 암호.

  2. inventoryansible이 시스템에 연결하여 사용자를 생성 할 수 있도록 연결 정보를 변경합니다 .

  3. ./run.sh스크립트를 실행 하려면 실행하십시오.


이 작업을 Ansible 임시 명령으로 수행하려면 다음을 수행 할 수 있습니다.

$ password='SomethingSecret!'
$ ansible 192.168.1.10 -i some_inventory -b -m user -a "name=joe_user \
       update_password=always password=\"{{ \"$password\" | password_hash('sha512') }}\""

위 명령의 출력 :

192.168.1.10 | SUCCESS => {
    "append": false,
    "changed": true,
    "comment": "Joe User",
    "group": 999,
    "home": "/home/joe_user",
    "move_home": false,
    "name": "joe_user",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/bash",
    "state": "present",
    "uid": 999
}

나는 내가 파티에 늦었다는 것을 알고 있지만 내가 사용하고있는 또 다른 해결책이있다. --stdinpasswd 바이너리 가없는 배포판에 유용 할 수 있습니다 .

- hosts: localhost
  become: True
  tasks:
    - name: Change user password
      shell: "yes '{{ item.pass }}' | passwd {{ item.user }}"
      loop:
       - { pass: 123123, user: foo }
       - { pass: asdf, user: bar }
      loop_control:
        label: "{{ item.user }}"

라벨 입력은 사용자 이름 loop_control 인쇄 합니다 . 전체 플레이 북 또는 사용자 변수 (를 사용할 수 있음 vars_files:) 만 ansible-vault로 암호화해야합니다.


내 솔루션은 조회를 사용하고 암호를 자동으로 생성합니다.

---
- hosts: 'all'
  remote_user: root
  gather_facts: no
  vars:
    deploy_user: deploy
    deploy_password: "{{ lookup('password', '/tmp/password chars=ascii_letters') }}"

  tasks:
    - name: Create deploy user
      user:
        name: "{{ deploy_user }}"
        password: "{{ deploy_password | password_hash('sha512') }}"

mkpasswd, Python 등을 포함한 많은 유틸리티를 시도했습니다.하지만 다른 도구에서 생성 된 HASH 값을 읽을 때 Ansible과의 호환성 문제가있는 것 같습니다. 그래서 마침내 ansible # 값 자체로 작동했습니다.

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

Playbook -

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

Well I'am totally late to party :) I had the need for ansible play that creates multiple local users with randoms passwords. This what I came up with, used some of examples from top and put them together with some changes.

create-user-with-password.yml

---
# create_user playbook

- hosts: all
  become: True
  user: root
  vars:
#Create following user
   users:
    - test24
    - test25
#with group
   group: wheel
  roles:
    - create-user-with-password

/roles/create-user-with-password/tasks/main.yml

- name: Generate password for new user
  local_action: shell pwgen -s -N 1 20
  register: user_password
  with_items: "{{ users }}"
  run_once: true

- name: Generate encrypted password
  local_action: shell python -c 'import crypt; print(crypt.crypt( "{{ item.stdout }}", crypt.mksalt(crypt.METHOD_SHA512)))'
  register: encrypted_user_password
  with_items: "{{ user_password.results }}"
  run_once: true

- name: Create new user with group
  user:
    name: "{{ item }}"
    groups: "{{ group }}"
    shell: /bin/bash
    append: yes
    createhome: yes
    comment: 'Created with ansible'
  with_items:
    - "{{ users }}"
  register: user_created

- name: Update user Passwords
  user:
    name: '{{ item.0 }}'
    password: '{{ item.1.stdout }}'
  with_together:
    - "{{ users }}"
    - "{{ encrypted_user_password.results }}"
  when: user_created.changed

- name: Force user to change the password at first login
  shell: chage -d 0 "{{ item }}"
  with_items:
    - "{{ users }}"
  when: user_created.changed

- name: Save Passwords Locally
  become: no
  local_action: copy content={{ item.stdout }} dest=./{{ item.item }}.txt
  with_items: "{{ user_password.results }}"
  when: user_created.changed

참고URL : https://stackoverflow.com/questions/19292899/creating-a-new-user-and-password-with-ansible

반응형