Wie bereits in diesem Beitrag erwähnt, beschäftige ich mich aktuell mit der Evaluierung von Ansible.
In diesem Artikel dokumentiere ich ein Beispiel, wie das Modul user zur Administration von Linux-Benutzerkonten verwendet werden kann. Der Link zur offiziellen Dokumentation des user-Moduls befindet sich am Ende dieses Artikels.[1. Ansible Module: user – Manage user accounts {en}]
Hinweis: Die folgende Konfiguration ist nicht zur Nachahmung empfohlen. Es handelt sich dabei um meine ersten Schritte mit Ansible. Es ist daher wahrscheinlich, dass die Konfiguration noch Fehler enthält, nicht optimiert ist und ein großes Verbesserungspotenzial besitzt. Die Nachahmung erfolgt ausdrücklich auf eigene Gefahr. Über Hinweise, wie man es besser machen kann, freue ich mich jederzeit.
Anforderungen
- Es soll ein lokales Benutzerkonto angelegt werden
- Der Benutzer soll Mitglied der Gruppe „wheel“ werden
- Es soll ein initiales Passwort für das Benutzerkonto gesetzt werden
- Ein öffentlicher SSH-Schlüssel soll in die Datei
authorized_keysdes zu erstellenden Benutzers eingetragen werden - Konfiguration des SSH-Daemons
Vorbereitung
Abgeleitet aus den „Best Practices“[2. Ansible Best Practices – Directory Layout] verwende ich auf meiner Spielwiese folgende Verzeichnisstruktur:
ansible/ |-- autoupdate.txt # ignore |-- autoupdate.yml # ignore |-- check_reboot. # playbook which sets the repos |-- group_vars | `-- e-stage # variables for group e-stage |-- hosts # inventory file |-- host_vars # for system specific variables |-- roles | |-- common # this hierarchy represents a "role" | | |-- defaults | | |-- files | | |-- handlers | | | `-- main.yml # handlers file | | |-- meta | | |-- tasks | | | `-- main.yml # tasks file can include smaller files if warranted | | `-- vars | `-- e-stage | |-- defaults | |-- files | |-- handlers | |-- meta | |-- templates | `-- vars |-- create_johnd.yml # playbook which creates user johnd |-- site.yml # master playbook file `-- staging # inventory file for staging environment 17 directories, 11 files
Um das Passwort für den neuen Benutzer erstellen zu können, muss zuerst der passende Passwort-Hash generiert werden[3. How do I generate crypted passwords for the user module?]:
python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"
Der generierte Hash wird auf der Standardausgabe ausgegeben. Dieser wird für das Playbook benötigt.
Playbook und Tasks
Das Playbook ist sehr kurz gehalten und gibt im Wesentlichen nur an, welche Hosts auf welche Rolle gemapped werden sollen.
# create_johnd.yml
---
- hosts: all
roles:
- common
Bei Verwendung dieses Playbooks werden die Tasks aus der Datei roles/common/tasks/main.yml ausgeführt, welche wie folgt aufgebaut wurde:
---
# Configure sshd_config on target system
- name: Enable Public-Key-Authentication
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PubkeyAuthentication"
line: "PubkeyAuthentication yes"
state: present
notify:
- reload sshd
- name: Set AuthorizedKeyFile
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^AuthorizedKeysFile"
line: "AuthorizedKeysFile .ssh/authorized_keys"
state: present
notify:
- reload sshd
- name: Disable PasswordAuthentication
lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PasswordAuthentication"
line: "PasswordAuthentication no"
state: present
notify:
- reload sshd
# Add user johnd with specific uid in group 'wheel'
- user: name=johnd comment="John Doe" uid=100 groups=wheel password="PASSWORDHASH" shell=/bin/bash append=yes state=present
notify:
- deploy ssh-pub-keys
Die hier spezifizierten Tasks setzen die folgenden Aufgaben um:
- Aktivierung der Public-Key-Authentication
- Spezifikation des Standard-AuthorizedKeysFile
- Deaktivierung der Password-Authentication
Was in dieser Datei noch nicht zu sehen ist, ist die Verteilung eines öffentlichen SSH-Schlüssels. Dies wird von dem Handler[4. Ansible Handlers – Running Operations On Change] deploy ssh-pub-keys übernommen.
Der Handler ist in der Datei roles/common/handlers/main.yml definiert. Es handelt sich dabei um einen Task, welcher nur ausgeführt wird, wenn der Benutzer erfolgreich erstellt wurde.
Fazit
Soweit zu meinen ersten Gehversuchen mit Ansible Playbooks. Meine Anforderungen können mit dem hier dokumentierten Playbook erfüllt werden.
In dem hier beschriebenen Beispiel habe ich angenommen, dass es sich bei dem zu erstellenden Benutzer um das erste lokale Benutzerkonto neben root handelt. Dieses soll über die Berechtigung verfügen, Kommandos mit sudo auszuführen und primär für die Arbeit auf dem System verwendet werden.
Die Verteilung des SSH-Schlüssels über einen Handler anzustoßen erscheint mir jedoch nicht optimal. Der Handler wird nur dann ausgeführt, wenn durch das user-Modul Änderungen am Zielsystem vorgenommen wurden. Weitere SSH-Schlüssel bzw. Änderungen an bereits vorhandenen SSH-Schlüsseln lassen sich auf diesem Weg nicht vornehmen.
Daher erscheint es mir sinnvoll, die Verteilung von SSH-Schlüsseln über das Modul authorized_key[5. Ansible Module: authorized_key – Adds or removes an SSH authorized key] in ein eigenes Playbook auszulagern.