← All rules
SOCLE-CLD-IAM-038// Accounts (PAM modules)mediumpersistent config

Set number of Password Hashing Rounds - password-auth

Sets an explicit rounds= value on pam_unix.so in the password stack so password hashes use a high iteration count.

Checked against the content of a persistent configuration file, the source of truth that survives reboots.

A pass proves? running now✓ on disk✓ survives rebootthe qualified verdict →
Debian 12CIS 1.1.0Debian 13CIS 1.0.0FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0Ubuntu 22.04CIS 3.0.0Ubuntu 24.04CIS 1.0.0Ubuntu 26.04
One check, maps to 2 standards

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

The rounds= argument on pam_unix.so sets how many iterations the password hashing function (yescrypt/SHA-512) performs. A higher round count raises the CPU cost of each guess, so offline brute-force and dictionary attacks against a stolen /etc/shadow become dramatically slower and more expensive for an attacker.

What Pavois checks

Pavois greps the effective PAM tree under /etc/pam.d/ for a non-commented pam_unix.so line carrying rounds= followed by a digit. Reading the resolved stack (including @included common-password/password-auth/system-auth) confirms the option is on the line that actually hashes passwords, which a single-file check could miss.

describe command('grep -RqE \'^[^#]*\bpam_unix\\.so\b[^#]*\brounds=[0-9]\' /etc/pam.d/ 2>/dev/null && echo ok || echo ko') do
  its('stdout.strip') { should eq 'ok' }
end

How to verify it is applied

Run:

grep -rE '^[^#]*\bpam_unix\.so\b[^#]*\brounds=[0-9]' /etc/pam.d/

Expected: a password line shows pam_unix.so with e.g. rounds=65536 (or the value your policy mandates). No match means no explicit round count is set.

Inspect & investigate

Password changes are logged to /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/Fedora); follow journalctl -t passwd -f. The effect is visible in /etc/shadow: a yescrypt hash starts with $y$ and SHA-512 with $6$rounds=...$, confirming the configured cost.

Remediation

No automated harden plan ships for this rule, so it must be applied manually: add rounds=<N> (e.g. rounds=65536) to the pam_unix.so line in the password stack (/etc/pam.d/common-password, or password-auth/system-auth on RHEL/Fedora). Existing password hashes are only re-hashed at the next password change.

Pavois applies this with its own harden engine, the plan below, not a shell script:

commandsed -ri "s/(pam_unix\.so[^#]*yescrypt)( rounds=[0-9]+)?/\1 rounds=65536/" /etc/pam.d/common-password
namepam-unix-rounds
not_ifgrep -qE "pam_unix\.so.*rounds=" /etc/pam.d/common-password
resourceexec
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

Setting rounds= is safe but only protects passwords changed after the edit; existing hashes keep their old cost until the next change. A value set absurdly high adds noticeable latency to every login and password change. Precautions: pick a sane value (65536 is a common target), keep a root shell open while editing PAM via pam-auth-update/authselect, and confirm logins still work from a second session.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R68direct2.0high
DISA STIGUBTU-22-611055, UBTU-24-400220directper OS STIG releasehigh

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.

Sources & references