pam_faillock, A Lockout Proven To Lock And To Let Go
An account lockout on EL 10, put into the authentication stack through authselect because /etc/pam.d/system-auth is a generated symlink. The live test fails one account past the limit and watches the RIGHT password be refused, fails a second one short of the limit and watches it keep working, then resets the first and watches it come back. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-09-26 · podman 4.9.3 · ansible 2.21.4 · how we verify
Cite it in your README
badge · attributionPaste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.
[](https://www.iac-bazaar.com/catalog/ansible-pam-faillock?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
Ansible role 1.0.0, live-tested on IaC Bazaar: [pam_faillock, A Lockout Proven To Lock And To Let Go](https://www.iac-bazaar.com/catalog/ansible-pam-faillock?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
```yaml
# pam_faillock, A Lockout Proven To Lock And To Let Go: https://www.iac-bazaar.com/catalog/ansible-pam-faillock (download from your IaC Bazaar account)
```Preview:
Documentation
pam-faillock
A lockout that is proven to lock, and proven to let go. The role writes the
faillock policy and puts pam_faillock into the authentication stack through
authselect, which is the only supported way in on EL 10. The live test fails one
account past the limit and watches the RIGHT password get refused, fails a second
account one short of the limit and watches it keep working, then resets the first
and watches it come back.
No download, and no version to pin. PAM and authselect are part of EL 10, so the role installs them by name and works through the tooling the distribution provides. What the role owns is the policy: how many failures, in what window, for how long, and whether root is included.
/etc/pam.d/system-auth is a symlink into /etc/authselect. Editing it is
editing a generated file, and the next authselect apply-changes discards the
edit without a word. The role uses authselect enable-feature with-faillock,
keeps whatever profile the host already has, and runs authselect check on
every pass rather than only after a change - because a stack that does not apply
cleanly is a host that cannot authenticate at all.
Nothing validates faillock.conf, and a typo fails OPEN. With
deny = notanumber, PAM printed "Bad number supplied for deny argument", let
the authentication through, and applied no lockout at all. There is no checker to
run and no error to notice: the policy is simply absent. That is the reason this
role's live test exists in the form it does, and why it counts to the limit
rather than asserting that the file contains the right words.
even_deny_root can lock an operator out of a host. It is on by default
here because a lockout that exempts the account everyone attacks is not a
lockout, but root_unlock_time is then the only way back in that does not need
a console. Decide that before rolling it out, not after.
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
ansible-lynis
Lynis from EPEL on a systemd timer, with the units the package keeps only in its docs, your skipped tests in custom.prf, and a minimum hardening index below which the audit unit fails, so a falling score shows as a failed unit. The live test runs the audit, reads the index and the tests that ran, and finds the timer enabled. Original role, live-tested on Rocky Linux 10.
ansible-suricata
Suricata from EPEL watching the default-route interface as the suricata user, ET Open fetched at install and refreshed daily, plus a canary rule that proves the sensor is alive. A root-run check left root-owned logs and a daemon recording nothing; the role prevents it. The live test raises the canary alert while a second lookup is logged, not alerted. Original role, live-tested on Rocky Linux 10.
ansible-aide
AIDE from AppStream on EL 10: a watched tree, a baseline database built once, and the oneshot unit and timer the package does not ship. The live test passes on an unchanged host, FAILS when a file appears inside a watched path and names it, ignores one inside an excluded path, and passes again once the change is gone. Original role, live-tested on Rocky Linux 10.
ansible-389-ds
389 Directory Server from AppStream. A fresh instance listens on every interface and lets anonymous clients read the tree; this role binds both listeners to loopback and limits anonymous clients to the rootDSE. The live test adds a user who binds, sees a wrong password and an anonymous search refused, and reads the LDAPS certificate. Original role, live-tested on Rocky Linux 10.
ansible-krb5-kdc
An MIT Kerberos KDC: the realm created once with a stash, kadmind behind an ACL, a default policy that locks an account after five wrong passwords, every listener on loopback. The KDC starts on a broken config without a word, so the live test proves each setting by behaviour: the ticket lifetime, the refusals, the lockout. Original role, live-tested on Rocky Linux 10.
ansible-authelia
Authelia from the upstream release (sha256-verified) as a hardened system service on loopback with file users and sqlite; its secrets are generated once on the host and reach the service as AUTHELIA_*_FILE variables. The live test hashes a password with Authelia's hasher, logs in, sees a wrong password refused and an anonymous visitor sent to the portal. Original role, live-tested on Rocky 10.