Sections du handbook

Durcir PAM

Revu le

PAM est le poste de garde par lequel passe chaque connexion. Réglez ses modules pour que mots de passe faibles, réutilisation et brute-force n'atteignent jamais un shell, et verrouillez les comptes après des échecs répétés.

La menace : une pile permissive et chaque connexion est ouverte

PAM (Pluggable Authentication Modules) est la couche d'authentification partagée qu'appellent login, sshd, sudo, su, cron et le gestionnaire d'affichage. Chaque vérification d'identifiant traverse les piles de /etc/pam.d/, ce qui en fait l'endroit où la politique d'authentification est appliquée ou silencieusement absente. Les menaces qu'il doit émousser sont intemporelles : mots de passe faibles qui tombent en quelques secondes face à un dictionnaire, brute-force en ligne qui essaie jusqu'à réussir, réutilisation où l'utilisateur revient à un secret déjà fuité, et hachage trop rapide qui permet de casser hors ligne un /etc/shadow volé. Une pile PAM par défaut n'oppose presque rien à tout cela : aucun plancher de complexité, aucun verrouillage, aucun historique.

Pourquoi le durcir

PAM est l'unique point de passage où imposer une politique à tous les services à la fois, et les valeurs par défaut sont délibérément permissives. Le durcir transforme l'authentification d'une correspondance oui/non en une barrière à plusieurs étages : le secret doit être assez robuste (pam_pwquality), il ne doit pas répéter un secret récent (pam_pwhistory), les échecs répétés doivent verrouiller le compte (pam_faillock), et le hachage stocké doit être coûteux à casser (pam_unix rounds=, yescrypt/SHA-512). Chaque étage augmente le coût pour l'attaquant. Cela correspond aux recommandations ANSSI R31 (mots de passe), R67 (authentification PAM) et R68 (stockage des mots de passe).

L'ordre fait tout

PAM est une pile, évaluée de haut en bas, et le control de chaque module décide du flux :

Control Effet
required doit réussir ; l'échec est retenu mais la pile continue (aucun indice précoce donné à l'attaquant)
requisite doit réussir ; l'échec renvoie immédiatement
sufficient un succès court-circuite le reste de la pile
optional résultat ignoré sauf si c'est le seul module

Un module robuste placé après une ligne sufficient permissive ne s'exécute jamais. Ainsi pam_pwhistory doit venir avant pam_unix et porter use_authtok, sinon il vérifie le mauvais jeton. Le comportement effectif est le résultat fusionné de toutes les lignes, pas d'une directive isolée.

Ce que Pavois audite : les piles PAM effectives

Pavois audite les piles PAM effectives sous /etc/pam.d/, les fichiers réellement consultés au moment de l'authentification, y compris les includes common-* (Debian) / *-auth (RHEL) qu'appellent les fichiers de service, plutôt qu'un extrait isolé. Ses règles confirment que les bons modules sont présents et activés (pam_pwquality, pam_faillock, pam_pwhistory, pam_unix) puis vérifient leurs options : even_deny_root sur faillock pour que le verrouillage couvre root, l'option audit pour journaliser les verrouillages, use_authtok sur pwhistory pour imposer le nouveau jeton, un rounds= non par défaut sur pam_unix, et que l'historique n'est pas délégué à l'option obsolète remember= de pam_unix. Chaque contrôle lit la pile en vigueur et ne retient que les lignes actives et non commentées, donc une directive derrière un # ou éclipsée par l'ordre est signalée non conforme.

Comment le configurer et le vérifier ?

Les réglages vivent dans des fichiers dédiés, mais l'activation du module diffère selon la distribution, c'est le piège central :

  • Debian / Ubuntu : la pile est dans /etc/pam.d/common-auth et common-password, gérée par pam-auth-update ; pam_faillock doit être référencé en preauth et authfail. Les réglages vont dans /etc/security/faillock.conf et /etc/security/pwquality.conf.
  • RHEL / AlmaLinux / Rocky : n'éditez jamais system-auth / password-auth à la main, ils sont régénérés par authselect et vos modifications seraient écrasées. Activez proprement : authselect enable-feature with-faillock && authselect apply-changes.

Vérifiez l'état en vigueur : faillock --user alice affiche le compteur d'échecs, faillock --user alice --reset débloque. Une politique typique : deny=3, unlock_time=600 (faillock) ; minlen=12, minclass=3 (pwquality) ; remember=5 (pwhistory, historique dans /etc/security/opasswd).

Doctrine moderne des mots de passe (NIST 800-63B, ANSSI 2024)

Le NIST SP 800-63B et l'ANSSI déconseillent désormais la rotation périodique forcée et la complexité imposée, qui poussent vers des mots de passe faibles et prévisibles. La priorité va à la longueur, à une liste de bannissement des mots de passe connus, et à la limitation des essais (pam_faillock). La rotation forcée est réservée aux comptes privilégiés ou à une exigence de conformité : certains profils CIS imposent encore les crédits de complexité, à traiter comme une exigence d'audit, pas comme un idéal de sécurité.

Pièges

  • Une erreur de syntaxe dans un fichier PAM bloque toute l'authentification d'un coup, sudo et SSH compris. Sauvegardez le fichier, gardez une session root ouverte, et testez la connexion dans une seconde session avant de valider. La récupération passe par le mode rescue.
  • pam_tally2 a disparu : supprimé de Linux-PAM depuis 1.5.0 (2020) ; une ligne pam_tally2.so provoque aujourd'hui une erreur de chargement PAM. Utilisez pam_faillock.
  • even_deny_root peut verrouiller root lui-même ; si vous l'utilisez, ajoutez root_unlock_time=60.
  • Les compteurs ne sont pas persistants par défaut (/var/run/faillock, effacé au reboot) ; ajoutez dir=/var/log/faillock pour les conserver.

FAQ

Pourquoi Pavois lit-il tous les includes common-* / *-auth ? Parce que la pile effective est la fusion du fichier de service et de ses includes ; un module activé seulement dans un include est actif, et Pavois audite ce que PAM évalue réellement.

Faut-il forcer la rotation des mots de passe ? Pas pour les utilisateurs ordinaires (NIST/ANSSI le déconseillent). Priorisez la longueur, une liste de bannissement et le verrouillage ; réservez la rotation aux comptes privilégiés ou à une exigence de conformité.

Ma ligne pam_tally2 casse la connexion. Pourquoi ? Elle a été supprimée dans Linux-PAM 1.5.0. Remplacez-la par pam_faillock.