Ensure PAM Enforces Password Requirements - Enforcing
enforcing = 0 must appear nowhere in the pwquality configuration or the PAM stack. With that setting, pam_pwquality degrades to advisory mode: it still reports a weak password, but accepts it, so the whole complexity policy becomes decorative.
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
Use of a complex password helps to increase the time and resources required to compromise the password. Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts at guessing and brute-force attacks. Using enforcing=1 ensures "pwquality" enforces complex password construction configuration and has the ability to limit brute-force attacks on the system.
What Pavois checks
Pavois greps for enforcing = 0 across three locations at once: /etc/security/pwquality.conf, the /etc/security/pwquality.conf.d/ drop-ins and the whole /etc/pam.d/ stack, because the option can be set either as a config directive or as a pam_pwquality.so module argument on the password line. The control passes only when the string is found nowhere: pwquality enforces by default, so the compliant state is the absence of the directive, not its presence set to 1. A check limited to pwquality.conf would miss an enforcing=0 argument added directly to /etc/pam.d/common-password.
describe command('grep -RqE \'enforcing[[:space:]]*=[[:space:]]*0\' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/ /etc/pam.d/ 2>/dev/null && echo ko || echo ok') do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Run the same three-way search and expect no output:
grep -RE 'enforcing[[:space:]]*=[[:space:]]*0' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/ /etc/pam.d/
The behavioural confirmation: as an unprivileged user, run passwd and submit a weak password. It must be rejected (BAD PASSWORD: ... followed by a retry prompt), not merely flagged before being accepted.
Inspect & investigate
Both modes log the same PAM line in /var/log/auth.log (Debian/Ubuntu) or journalctl (RHEL family):
passwd[8899]: pam_pwquality(passwd:chauthtok): bad password: The password is shorter than 14 characters
The log therefore does not reveal whether the password was refused or merely reported: only the outcome of the passwd command distinguishes advisory mode (enforcing = 0, password changed anyway) from enforcement (change refused).
Remediation
Pavois classifies this as a manual remediation: the delivered script only lists the files containing enforcing = 0 (same three-way search as the check), and you delete the offending line(s) after review. Nothing needs to be added in its place, since pwquality enforces as soon as the directive is absent. On Debian and Ubuntu, if the option sits on the pam_pwquality.so line of /etc/pam.d/common-password, editing that file is not durable: pam-auth-update regenerates it from /usr/share/pam-configs/ at the next libpam-runtime upgrade or reconfiguration and can bring the argument back. Remove it from the pam-config profile, or from pwquality.conf, so the fix survives regeneration.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | grep -rl 'enforcing[[:space:]]*=[[:space:]]*0' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/ /etc/pam.d/ 2>/dev/null # delete the 'enforcing = 0' line(s) so pwquality enforces (it does by default when absent) |
|---|---|
| reason | removing enforcing=0 makes pwquality reject weak passwords, verify your policy first |
| resource | manual |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
With enforcing = 0, minlen, minclass and the dictionary checks are pure documentation: users keep choosing weak passwords, and a compliance report based on those directives alone would wrongly declare the host hardened. Restoring enforcement is low-risk for availability: existing passwords stay valid, sessions are untouched and nobody is locked out. The friction is at the next password change, which will be refused until it satisfies the policy. Before removing the option, review the policy actually in force (grep -vE '^\s*#|^\s*$' /etc/security/pwquality.conf, plus the drop-ins) so users are not faced with an unexpectedly strict rule; consider enforce_for_root as a separate matter, and warn the users whose password is close to expiry, since they will hit the new rule first.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 5.3.3.2.7 | direct | per OS, see the benchmark table | high |
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.