← All rules
SOCLE-CLD-IAM-009// Accounts (faillock)mediumpersistent config

Set Lockout Time for Failed Password Attempts

Configures pam_faillock so a locked account stays locked for at least 900 seconds (15 minutes) before it can be used again (unlock_time ≥ 900).

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 5 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

A lockout threshold only slows an attacker if the lock lasts long enough to make repeated guessing futile. Holding the account locked for at least 15 minutes after the limit is reached drastically cuts the number of passwords that can be tried per hour, defeating online brute-force and password-spraying while letting a legitimate user retry after a short wait.

What Pavois checks

Pavois reads the effective faillock setting by merging /etc/security/faillock.conf with every drop-in under /etc/security/faillock.conf.d/ and taking the last unlock_time value (the one PAM actually applies), then requires it to be ≥ 900. Honoring drop-in precedence matters: a short unlock_time in a .d file would override a longer value in the main config, and only reading the effective merged result catches it.

describe command('v=$(grep -rh \'^[[:space:]]*unlock_time[[:space:]]*=\' /etc/security/faillock.conf /etc/security/faillock.conf.d/ 2>/dev/null | tail -1 | grep -oE \'[0-9]+\'); { [ -n "$v" ] && [ "$v" -ge 900 ] && echo ok; } || echo ko') do
  its('stdout.strip') { should eq 'ok' }
end

How to verify it is applied

Inspect the merged value with grep -rh '^[[:space:]]*unlock_time' /etc/security/faillock.conf /etc/security/faillock.conf.d/ | tail -1 (expect unlock_time = 900 or higher). Live lock status per user is shown by faillock --user <name>. Re-running the InSpec command should print ok.

Inspect & investigate

Failed attempts and lockout events are recorded in /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL family), or via journalctl -t sshd -t login. Inspect or clear a user's counters with faillock --user <name> and faillock --user <name> --reset.

Remediation

pavois harden apply uses the keyval resource to write unlock_time = 900 into the drop-in /etc/security/faillock.conf.d/99-Pavois.conf. Read last, that drop-in deterministically overrides any shorter value in the main file, enforcing the minimum lockout duration for all PAM-based logins.

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

file/etc/security/faillock.conf
keyunlock_time
resourcekeyval
value900
pavois harden plan local

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

Impact & precautions

A locked-out user must wait 15 minutes (or have an admin run faillock --user <name> --reset) before retrying. Combined with a strict deny threshold, this can lock real accounts after a few typos, so ensure you keep an out-of-band console or a second privileged account to avoid an admin lockout. Setting unlock_time = 0 would keep accounts locked until manually reset, usable but operationally heavier.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R31direct2.0high
CIS5.3.3.1.2, 8.3.4directper OS, see the benchmark tablehigh
NIST3.1.8, AC-7(b), CM-6(a)supporting800-53 Rev 5 · 800-171 Rev 2 (pinned)medium
PCI DSS8.3.4supporting4.0.1medium
DISA STIGUBTU-22-411045, UBTU-24-200610directper 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