Set SHA_CRYPT minimum rounds in login.defs
Raise SHA_CRYPT_MIN_ROUNDS in /etc/login.defs to at least 10000 (Pavois writes 65536), so that SHA-256/SHA-512 password hashes are computed with far more iterations than the glibc default of 5000. Each additional round multiplies the cost of an offline brute-force attack on a stolen /etc/shadow.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
What Pavois checks
Pavois uses the InSpec login_defs resource and asserts SHA_CRYPT_MIN_ROUNDS >= 10000. The resource parses the directives as the shadow suite reads them (last non-commented assignment wins), so a value left commented out counts as absent and fails. The effective proof of the setting is not in the file but in the resulting hash: a password set after the change is stored in /etc/shadow as $6$rounds=65536$..., whereas the default produces a $6$ hash with no rounds= prefix.
describe login_defs do
its('SHA_CRYPT_MIN_ROUNDS') { should cmp >= 10000 }
endHow to verify it is applied
Check the directive, then the hash it actually produces:
grep -i '^SHA_CRYPT_MIN_ROUNDS' /etc/login.defs
SHA_CRYPT_MIN_ROUNDS 65536
Change a test user's password, then confirm the stored hash carries the round count:
sudo getent shadow testuser | cut -d: -f2 | cut -c1-16
$6$rounds=65536$
Inspect & investigate
The setting itself is not logged, and neither is the number of rounds used for a given hash. A password change is logged by PAM in /var/log/auth.log (Debian/Ubuntu) or journalctl (RHEL family), without any hashing detail:
passwd[3210]: pam_unix(passwd:chauthtok): password changed for alice
The only reliable evidence of the applied cost factor remains the $6$rounds= prefix in the shadow entry.
Remediation
The Pavois harden plan uses a conf_line remediation on /etc/login.defs with the key SHA_CRYPT_MIN_ROUNDS, the value 65536 and a space separator (sep: space), because login.defs uses the KEY VALUE syntax and not key = value. The generated step rewrites an existing line in place with sed and appends it if absent; a not_if guard on the already-correct line makes the apply idempotent.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| file | /etc/login.defs |
|---|---|
| key | SHA_CRYPT_MIN_ROUNDS |
| resource | conf_line |
| sep | space |
| value | 65536 |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
With the glibc default of 5000 rounds, a leaked /etc/shadow is cracked an order of magnitude faster. Two caveats before applying. First, SHA_CRYPT_MIN_ROUNDS only applies when ENCRYPT_METHOD is SHA512 or SHA256: on Debian 12+ and Ubuntu 24.04, whose default is YESCRYPT, the directive is inert until the method is switched back to SHA-512, and the control is then purely a defence-in-depth setting. Second, it applies only to passwords hashed after the change; existing hashes keep their original cost until each user renews their password. A very high round count also lengthens every authentication (a few tens of milliseconds at 65536), which is negligible for interactive logins but measurable on a host doing thousands of PAM authentications per second. There is no lockout risk: existing passwords remain valid.