Skip to main content

Exemple de Playbook pour Générer un Hash Sécurisé - Playbook 2



1 - Playbook 2 - Génération de Hash à l’exécution


- name: Générer des utilisateurs avec des mots de passe hashés

hosts: all
tasks:
- name: Générer un sel sécurisé
ansible.builtin.set_fact:
secure_salt: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=16') }}"

- name: Vérifier si l'UID existe déjà sur le système
shell: "id -u {{ item.uid }} || echo 'not found'"
register: uid_check
changed_when: false
failed_when: false
loop:
- { username: "alice1", uid: 1001 }
- { username: "bob1", uid: 1002 }
- { username: "charlie1", uid: 1003 }

- name: Afficher les UID existants
debug:
msg: "UID {{ item.item.uid }} déjà utilisé : {{ item.stdout }}"
loop: "{{ uid_check.results }}"
when: item.stdout is not search('not found')

- name: Créer des utilisateurs avec des mots de passe hashés
ansible.builtin.user:
name: "{{ item.username }}"
password: "{{ item.password }}"
uid: "{{ item.uid }}"
loop:
- { username: "alice1", password: "{{ 'password1' | password_hash('sha512', secure_salt) }}", uid: 1001 }
- { username: "bob1", password: "{{ 'password2' | password_hash('sha512', secure_salt) }}", uid: 1002 }
- { username: "charlie1", password: "{{ 'password3' | password_hash('sha512', secure_salt) }}", uid: 1003 }
when:
- "item.uid not in uid_check.results | map(attribute='stdout') | list"


2 - Explication


  1. Génération d'un sel sécurisé (set_fact)

    • Un sel aléatoire est généré pour le hachage des mots de passe.
  2. Vérification des UID existants (shell: id -u ...)

    • Vérifie si chaque UID est déjà utilisé.
    • Stocke le résultat dans uid_check.
  3. Affichage des UID en conflit (debug)

    • Affiche une alerte si un UID est déjà pris.
  4. Création des utilisateurs (ansible.builtin.user)

    • Crée les utilisateurs uniquement si leur UID n'existe pas déjà.

3 - Avantages

Évite les conflits d'UID en vérifiant avant de créer les utilisateurs.
Utilisation sécurisée des mots de passe grâce à password_hash.
Meilleure gestion des erreurs avec des messages explicites.



4 - Playbook Final : UID Dynamique


- name: Générer des utilisateurs avec des mots de passe hashés

hosts: all
tasks:
- name: Générer un sel sécurisé
ansible.builtin.set_fact:
secure_salt: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=16') }}"

- name: Vérifier si l'UID existe déjà sur le système
shell: "id -u {{ item.uid }} || echo 'not found'"
register: uid_check
changed_when: false
failed_when: false
loop:
- { username: "alice1", uid: 1001 }
- { username: "bob1", uid: 1002 }
- { username: "charlie1", uid: 1003 }

- name: Générer un UID unique si nécessaire
shell: "shuf -i 2000-65000 -n 1"
register: unique_uid
when: item.stdout is not search('not found')
loop: "{{ uid_check.results }}"

- name: Associer les UID dynamiques aux utilisateurs
set_fact:
user_list: >-
[{% for item in uid_check.results %}
{
"username": "{{ item.item.username }}",
"password": "{{ ('password' ~ loop.index) | password_hash('sha512', secure_salt) }}",
"uid": "{{ unique_uid.results[loop.index0].stdout if item.stdout is not search('not found') else item.item.uid }}"
}
{% if not loop.last %},{% endif %}
{% endfor %}]
loop: "{{ uid_check.results }}"
loop_control:
extended: true

- name: Créer des utilisateurs avec UID dynamiques si nécessaire
ansible.builtin.user:
name: "{{ item.username }}"
password: "{{ item.password }}"
uid: "{{ item.uid }}"
loop: "{{ user_list }}"


5 - Avantages


Empêche tout conflit d'UID.
Génère un UID unique dynamiquement si nécessaire.
Utilise des mots de passe sécurisés avec un sel dynamique.



6 - Génération du Hash à l’Exécution


Une approche alternative consiste à générer les mots de passe hashés avant d’exécuter le playbook en utilisant mkpasswd.
Cette méthode permet d'éviter de stocker les mots de passe en clair dans les fichiers Ansible.

Exemple de commande pour générer un hash sécurisé :

mkpasswd --method=SHA-512 --rounds=5000 'password1'

(Cette solution dépasse le cadre de ce cours.)



7 - Conclusion


Solution 1 : Supprimer password_hash fonctionne, mais ce n'est pas sécurisé.

Solution 2 : Utiliser password_hash avec un sel est une approche plus sécurisée.
Solution 3 : Générer un UID unique dynamiquement évite tout conflit.
Solution 4 : Utiliser mkpasswd est la méthode la plus sécurisée.

💡 Recommandation :

Utilisez mkpasswd pour générer des mots de passe sécurisés et ne stockez jamais de mots de passe en clair dans vos fichiers Ansible.