Limit Password Reuse
Requires a password history depth of at least 2 (remember>=2) so users cannot immediately reset a password back to its previous value.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.
Why this rule matters
Preventing reuse of previous passwords helps ensure that a compromised password is not reinstated by a user. Even a minimal history (2) stops the classic trick of changing a password and immediately changing it back to satisfy expiry while keeping the old secret. Note this is a baseline floor; deeper history (e.g. 24, per CIS) is stronger.
What Pavois checks
Pavois reads the effective value by scanning both /etc/pam.d/ and /etc/security/pwhistory.conf for every remember=N, keeping the highest N and requiring it to be at least 2. Evaluating the resolved configuration (PAM line plus pwhistory.conf default) reflects what is actually enforced, which a single-file read could misrepresent if one source overrides the other.
describe command('v=$(grep -RhoE \'remember[[:space:]]*=[[:space:]]*[0-9]+\' /etc/pam.d/ /etc/security/pwhistory.conf 2>/dev/null | grep -oE \'[0-9]+\' | sort -n | tail -1); { [ -n "$v" ] && [ "$v" -ge 2 ] && echo ok; } || echo ko') do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Run grep -rhoE 'remember=[0-9]+' /etc/pam.d/ /etc/security/pwhistory.conf and confirm the effective (highest) value is >= 2. Functionally, change a password then try to set it straight back to the previous value, it should be rejected.
Inspect & investigate
Reuse rejections are logged in /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL). The retained hashes are stored in /etc/security/opasswd.
Remediation
No automated remediation is wired for this rule, so it must be applied manually: add remember=N (>= 2, ideally 24) to the pam_unix.so or pam_pwhistory.so line in the password stack, or set remember = N in /etc/security/pwhistory.conf, then regenerate PAM (pam-auth-update / authselect).
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | # Either enable pam_pwhistory (preferred, see pam-remember-pwhistory-remember) OR add 'remember=5' # to the pam_unix.so line in /etc/pam.d/common-password via pam-auth-update. |
|---|---|
| reason | prefer pam_pwhistory for history; if using pam_unix remember, set it deliberately |
| resource | manual |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Setting a small history depth only affects password changes and cannot lock out a running session. The main caveat is making sure the option lands on a module that actually stores history (pam_pwhistory.so, or pam_unix.so with the right setup) so the value is honored. Precautions: keep a root session open while editing PAM and test passwd on a throwaway account before enforcing.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| ANSSI BP-028 | R31 | direct | 2.0 | high |
| CIS | 8.3.7 | direct | per OS, see the benchmark table | high |
| NIST | 3.5.8, IA-5(1)(e), IA-5(f) | supporting | 800-53 Rev 5 · 800-171 Rev 2 (pinned) | medium |
| PCI DSS | 8.3.7 | supporting | 4.0.1 | medium |
Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.