--- # Durcissement PAM (CIS Ubuntu 24.04 — pam_faillock, pam_pwquality, pam_pwhistory) # # IMPORTANT — à lire avant d'exécuter : # - Ce playbook touche l'authentification (sudo/su) sur TOUS les hosts ciblés. # Une erreur dans un profil pam-auth-update peut casser sudo partout. # - `serial: 1` traite un host à la fois : si un host casse, le run s'arrête # avant de toucher les suivants (any_errors_fatal). # - La dernière tâche force un reset du cache sudo (`sudo -K`) puis revalide # un `become` réel, pour détecter une casse immédiatement plutôt que de la # découvrir 15 min plus tard quand le cache sudo normal expire. # - Volontairement AUCUNE expiration de mot de passe n'est appliquée sur les # comptes existants (omnex/root) : ces comptes se connectent en SSH par clé # (jamais par mot de passe), donc le mécanisme d'expiration PAM — qui ne se # déclenche qu'au moment d'un prompt de mot de passe au login — ne se # déclencherait jamais, et une expiration silencieuse casserait `sudo` sans # aucun moyen interactif de le corriger à distance. PASS_MAX_DAYS n'est posé # que dans /etc/login.defs (valeur par défaut pour les FUTURS comptes), pas # rétroactivement via chage. # # Usage recommandé : tester d'abord sur UN seul host avant le rollout complet : # ansible-playbook infra/playbook-pam-hardening.yml --limit pre-prod-uber # - name: Durcissement PAM (CIS Ubuntu 24.04) hosts: bdd-redis-prod become: true serial: 1 any_errors_fatal: true vars: pam_faillock_deny: 5 pam_faillock_unlock_time: 900 pam_faillock_fail_interval: 900 pam_pwquality_minlen: 16 pam_pwquality_difok: 8 pam_pwhistory_remember: 24 tasks: - name: Installer libpam-pwquality ansible.builtin.apt: name: libpam-pwquality state: present update_cache: true cache_valid_time: 3600 - name: Sauvegarder l'état PAM actuel avant modification ansible.builtin.shell: | set -e BACKUP_DIR="/root/pam-backup-$(date +%Y%m%d%H%M%S)" mkdir -p "$BACKUP_DIR" cp -a /etc/pam.d "$BACKUP_DIR/" cp -a /usr/share/pam-configs "$BACKUP_DIR/" cp /etc/login.defs "$BACKUP_DIR/" 2>/dev/null || true [ -f /etc/security/faillock.conf ] && cp /etc/security/faillock.conf "$BACKUP_DIR/" || true [ -f /etc/security/pwquality.conf ] && cp /etc/security/pwquality.conf "$BACKUP_DIR/" || true echo "$BACKUP_DIR" args: executable: /bin/bash changed_when: false register: pam_backup - name: Afficher le chemin de sauvegarde (rollback manuel possible) ansible.builtin.debug: msg: "Backup PAM : {{ pam_backup.stdout }}" - name: Déployer le profil unix (retire nullok, garde use_authtok) ansible.builtin.template: src: ../templates/pam-configs-unix.j2 dest: /usr/share/pam-configs/unix owner: root group: root mode: "0644" register: pam_unix_profile - name: Déployer le profil faillock (authfail) ansible.builtin.template: src: ../templates/pam-configs-faillock.j2 dest: /usr/share/pam-configs/faillock owner: root group: root mode: "0644" register: pam_faillock_profile - name: Déployer le profil faillock_notify (preauth + account) ansible.builtin.template: src: ../templates/pam-configs-faillock-notify.j2 dest: /usr/share/pam-configs/faillock_notify owner: root group: root mode: "0644" register: pam_faillock_notify_profile - name: Déployer le profil pwquality ansible.builtin.template: src: ../templates/pam-configs-pwquality.j2 dest: /usr/share/pam-configs/pwquality owner: root group: root mode: "0644" register: pam_pwquality_profile - name: Déployer le profil pwhistory ansible.builtin.template: src: ../templates/pam-configs-pwhistory.j2 dest: /usr/share/pam-configs/pwhistory owner: root group: root mode: "0644" register: pam_pwhistory_profile - name: Déployer /etc/security/faillock.conf ansible.builtin.template: src: ../templates/faillock.conf.j2 dest: /etc/security/faillock.conf owner: root group: root mode: "0644" - name: Déployer /etc/security/pwquality.conf ansible.builtin.template: src: ../templates/pwquality.conf.j2 dest: /etc/security/pwquality.conf owner: root group: root mode: "0644" - name: Activer les profils PAM (regénère common-auth/common-account/common-password) ansible.builtin.command: cmd: pam-auth-update --enable faillock --enable faillock_notify --enable pwquality --enable pwhistory when: > pam_unix_profile.changed or pam_faillock_profile.changed or pam_faillock_notify_profile.changed or pam_pwquality_profile.changed or pam_pwhistory_profile.changed changed_when: true - name: Configurer PASS_MAX_DAYS dans login.defs (nouveaux comptes uniquement) ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_MAX_DAYS' line: "PASS_MAX_DAYS\t365" - name: Configurer PASS_MIN_DAYS dans login.defs ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_MIN_DAYS' line: "PASS_MIN_DAYS\t1" - name: Configurer PASS_WARN_AGE dans login.defs ansible.builtin.lineinfile: path: /etc/login.defs regexp: '^PASS_WARN_AGE' line: "PASS_WARN_AGE\t7" - name: Verrouillage par défaut des comptes inactifs (nouveaux comptes) ansible.builtin.command: cmd: useradd -D -f 30 changed_when: true # --- Vérification critique : la stack PAM fonctionne-t-elle toujours ? --- # On invalide le cache sudo existant pour forcer une vraie ré-authentification # PAM, sinon un sudo déjà "chaud" masquerait une stack cassée pendant 15 min. - name: Invalider le cache sudo pour forcer une vraie revalidation PAM ansible.builtin.command: cmd: sudo -K become: false changed_when: false - name: Vérifier que sudo fonctionne toujours avec la nouvelle stack PAM ansible.builtin.command: cmd: whoami register: pam_sudo_check failed_when: pam_sudo_check.stdout != "root" - name: Confirmer le succès pour cet host ansible.builtin.debug: msg: "✅ PAM durci avec succès sur {{ inventory_hostname }} — sudo toujours fonctionnel."