wake-up-neo.net

Einen neuen Benutzer und ein neues Passwort mit Ansible erstellen

Ich habe eine Ansible-Aufgabe, die einen neuen Benutzer in Ubuntu 12.04 erstellt.

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

der Vorgang wird wie erwartet abgeschlossen, aber wenn ich mich als Benutzer anmelde und Sudo mit dem Kennwort versuche, sage ich, dass es falsch ist. Was mache ich falsch?

77
raphael_turtle

Wenn Sie das Handbuch von Ansible für user module lesen, werden Sie zu den Ansible-Beispielen github repo weitergeleitet, um zu erfahren, wie Sie den password-Parameter verwenden.

Dort sehen Sie, dass Ihr Passwort gehasht werden muss.

- 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}}

Wenn für Ihr Playbook oder Ihre Befehlszeile das Kennwort in Klartext vorhanden ist, bedeutet dies, dass der in Ihrer Datei shadow aufgezeichnete Kennwort-Hash falsch ist. Das heißt, wenn Sie versuchen, sich mit Ihrem Kennwort zu authentifizieren, wird sein Hash niemals übereinstimmen.

Siehe auch Ansible FAQ bezüglich einiger Nuancen der Passwortparameter und deren korrekte Verwendung.

81
Mxx

Ich kann zu spät sein, um dies zu beantworten, aber kürzlich habe ich herausgefunden, dass Jinja2-Filter die Möglichkeit haben, verschlüsselte Passwörter zu generieren. In meinem main.yml generiere ich das verschlüsselte Passwort als:

- 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" und "upassword" werden als --extra-vars an das Playbook übergeben, und ich habe hier den jinja2-Filter verwendet, um das übergebene Passwort zu verschlüsseln.

Ich habe im Folgenden ein Tutorial zu meinem Blog hinzugefügt

118
thinkingmonster

Ich möchte noch eine andere Lösung vorschlagen:

- 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

Warum ist es besser? Wie bereits hier erwähnt, sollten Ansible-Spiele idempotent sein. Sie sollten sie nicht als eine Abfolge von Aktionen im imperativen Stil, sondern als gewünschten Zustand, als deklarativen Stil betrachten. Als Ergebnis sollten Sie in der Lage sein, es mehrmals auszuführen und dasselbe Ergebnis und denselben Serverstatus zu erhalten.

Das hört sich alles gut an, aber es gibt einige Nuancen. Einer von ihnen verwaltet Benutzer. "Gewünschter Zustand" bedeutet, dass jedes Mal, wenn Sie ein Spiel ausführen, bei dem ein Benutzer erstellt wird, dieser aktualisiert wird, um genau diesem Status zu entsprechen. Mit "aktualisiert" meine ich, dass auch sein Passwort geändert wird. Aber höchstwahrscheinlich ist es nicht das, was Sie brauchen. Normalerweise müssen Sie nur einmal einen Benutzer erstellen, sein Kennwort festlegen und ablaufen lassen. Weitere Durchläufe sollten sein Kennwort nicht aktualisieren.

Glücklicherweise hat Ansible das update_password-Attribut in user module , das dieses Problem löst. Wenn Sie dies mit registrierten Variablen mischen, können Sie sein Kennwort nur dann verwerfen, wenn der Benutzer tatsächlich aktualisiert wird.

Wenn Sie die Shell des Benutzers manuell ändern (wenn Sie die Shell, die der böse Administrator in seinem Spiel erzwungen hat, nicht mögen), wird der Benutzer aktualisiert. Das Kennwort ist daher ungültig.

Beachten Sie auch, wie Sie in Spielen problemlos Klartext-Anfangspasswörter verwenden können. Sie brauchen sie nicht irgendwo anders zu kodieren und fügen Hashes ein. Sie können dafür Jinja2 filter verwenden. Dies kann jedoch ein Sicherheitsfehler sein, wenn sich jemand vor dem ersten Anmelden anmeldet. 

36
madhead

Das Ansible-Modul 'user' verwaltet Benutzer auf die Art idempotent. Im Playbook darunter erklärt die erste Aufgabe state = present für den Benutzer. Beachten Sie, dass 'register: newuser' in der ersten Aktion der zweiten Aktion hilft, festzustellen, ob der Benutzer neu ist (newuser.changed == True) oder vorhanden (newuser.changed==False), um das Kennwort nur einmal zu generieren.

Das Ansible-Spielbuch hat:

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
10
bbaassssiiee

versuchen Sie es so

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"
9
Artem Feofanov

Der Zweck der Rolle in dieser Antwort besteht darin, ein zufälliges Passwort für new_user_name zu generieren und das Passwort sofort abzulaufen. Der neue_Benutzername ist erforderlich, um das Kennwort bei seiner ersten Anmeldung zu ändern.

create_user.yml:

---
# create_user playbook

- hosts: your_Host_group
  become: True
  user: ansible

  roles:
    - create_user

rollen/create_user/task/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

Wenn Sie einen neuen Benutzer erstellen möchten:

ansible-playbook -i hosts.ini create_user.yml --extra-vars "new_user_name=kelvin"
5
McKelvin

Dies ist der einfache Weg:

---
- 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
3
Lightmed

So hat es für mich funktioniert

- 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
3
hecbuma

Sie können Ansible Vault für die Verwendung geheimer Schlüssel in Playbooks verwenden. Definieren Sie Ihr Passwort in yml. 

ex. pass: geheim oder 

user:
  pass: secret
  name: fake

verschlüsseln Sie Ihre Geheimdatei mit: 

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

ansible fragt nach einem Passwort, um es zu verschlüsseln. (Ich werde erklären, wie man diesen Pass benutzt)

Und dann können Sie Ihre Variablen verwenden, wo Sie möchten. Niemand kann sie ohne Tresorschlüssel lesen.

Vault-Schlüsselverwendung: 

Übergabe von Argumenten beim Ausführen eines Spielbuchs.

--ask-vault-pass: secret

oder Sie können sie wie password.txt in einer Datei speichern und irgendwo verstecken. (nützlich für CI-Benutzer)

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

In Ihrem Fall: Include vars yml und verwenden Sie Ihre Variablen.

- include_vars: /path/credential.yml

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

Ich kombinierte ein paar Lösungen von oben und erstellte ein Playbook, das automatisch korrekte Passworthashes generiert, basierend auf Klartextpasswörtern, die in einer verschlüsselten, lokal ansässigen Tresordatei gespeichert sind:

---
- 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}}"

Führen Sie diesen Befehl mit der Option "--ask-vault-pass" aus, um Ihre Tresordatei zu entschlüsseln (Informationen zum Verwalten eines verschlüsselten Tresors finden Sie unter ansible-vault).

2
Steve Midgley

Die Aufgabendefinition für das Modul user sollte sich in der neuesten Version von Ansible unterscheiden.

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

Der Vollständigkeit halber werde ich den Ad-hoc-Befehl mit ansible posten, da es dort auch einen Haken gibt.

Versuchen Sie zuerst, ein verschlüsseltes Kennwort zu generieren, indem Sie das Dienstprogramm mkpasswd verwenden, das auf den meisten Linux-Systemen verfügbar ist:

mkpasswd --method=SHA-512

Dann probieren Sie den Ansible Ad-Hock-Befehl:

ansible all -m user -a 'name=testuser Shell=/bin/bash \
     comment="Test User" password=$6$XXXX' -k -u admin --Sudo

Aber sicher stellen:

  1. Der Befehl ist in einfache Anführungszeichen gesetzt und darf nicht doppelt verwendet werden, da sonst Ihr Passwort niemals funktioniert
  2. Sie führen es mit --Sudo aus oder Sie erhalten einen Fehler wie (useradd: cannot lock /etc/passwd; try again later).
2
pgaref

Ich habe ein Ansible-Playbook erstellt, mit dem Sie ein Linux-Konto erstellen können, das die Kennwortauthentifizierung ermöglicht.

Siehe CreateLinuxAccountWithAnsible .

Das Hash-Passwort wird mit dem Befehl mkpasswd generiert. Ich habe die Möglichkeiten bereitgestellt, mkpasswd auf verschiedenen Betriebssystemen zu installieren.

Hier sind die Schritte, die zur Verwendung meines Skripts erforderlich sind:

  1. Ersetzen Sie <your_user_name> und <your_password> in run.sh durch Ihren gewünschten Benutzernamen und Ihr gewünschtes Passwort.

  2. Ändern Sie die Verbindungsinformationen in inventory, sodass ansible eine Verbindung zum Computer herstellen kann, um einen Benutzer zu erstellen.

  3. Führen Sie ./run.sh aus, um das Skript auszuführen.

1
Brian

Die Antwort von Mxx ist korrekt, aber die Python crypt.crypt()-Methode ist nicht sicher, wenn verschiedene Betriebssysteme betroffen sind (bezogen auf den auf Ihrem System verwendeten glibc-Hash-Algorithmus.) 

Zum Beispiel funktioniert es nicht, wenn Sie Ihren Hash von MacOS generieren und unter Linux ein Playbook ausführen. In diesem Fall können Sie passlib (pip install passlib zur lokalen Installation) verwenden. 

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

Keine der Lösungen funktionierte direkt auf meinem Mac, der Ubuntu steuert. Für andere, die Mxx- und JoelB-Antworten kombinieren, ist hier die aktuelle Python 3-Lösung:

pip3 install passlib

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

Das Ergebnis ist $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI. wie in der Antwort von Mxx.

Besser noch, benutze SHA512 anstelle von MD5:

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

Ergebnis:

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

1
texnic

Zufälliges Passwort für Benutzer generieren

zuerst müssen Sie die Benutzervariable definieren, dann folgen Sie unten

aufgaben:

- 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 }}'
1
Apuri Srikanth

So erstellen Sie ein verschlüsseltes Kennwort für die Übergabe an password var an den Task Ansible user (aus dem Kommentar von @Brendan Wood):

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

Das Ergebnis wird wie folgt aussehen:

$1$some_pla$lmVKJwdV3Baf.o.F0OOy71

Beispiel für eine user-Aufgabe:

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

UPD: Verschlüsselung mit SHA-512 siehe hier und hier :

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/

Rubin

$ Ruby -e 'puts "password".crypt("$6$saltsalt$")'

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

Versuchte viele Dienstprogramme, einschließlich mkpasswd, Python usw. Es scheint jedoch ein Kompatibilitätsproblem mit Ansible beim Lesen von HASH-Werten zu geben, die von anderen Tools generiert wurden. Also funktionierte es endlich mit dem ansiblen Wert selbst.

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

Spielbuch -

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

Ich weiß, dass ich zu spät zur Party komme, aber es gibt eine andere Lösung, die ich verwende. Für Distros, die --stdin nicht in passwd binary enthalten, kann dies praktisch sein.

- 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 }}"

Das Etikett in loop_control ist für das Drucken von only username verantwortlich. Das gesamte Playbook oder nur Benutzervariablen (Sie können vars_files: verwenden) sollten mit Ansible-Vault verschlüsselt werden.

0
Alex Baranowski

Meine Lösung verwendet das automatische Suchen und Generieren von Passwörtern.

---
- 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') }}"
0
alex naumov

Wenn Sie dies als Ansible-Ad-hoc-Befehl ausführen möchten, haben Sie folgende Möglichkeiten

$ 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') }}\""

Ausgabe vom obigen Befehl:

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
}
0
slm