Pluggable Authentication Modules (PAM) serve as the primary defensive layer for local and remote authentication across critical network infrastructure and cloud environments. In high-availability settings such as smart-grid energy platforms or high-density data centers, the absence of an automated lockout mechanism presents a significant vulnerability to brute-force attacks. These attacks do more than jeopardize data; they increase CPU latency and power consumption by forcing the system to perform intensive cryptographic calculations for every malicious attempt. By implementing the pam_faillock module, administrators can enforce an idempotent security policy that drops malicious connection payload overhead at the kernel-userland interface. This manual provides the technical framework for implementing pam_faillock, replacing the deprecated pam_tally2 module, to ensure that repeated authentication failures trigger a controlled temporal lockout. This architectural approach maintains system integrity while preventing the signal-attenuation of legitimate administrative access during a coordinated attack.
Technical Specifications
| Requirement | Specification |
|:—|:—|
| Operating System | Linux Kernel 5.0+ (RHEL 8/9, Ubuntu 22.04+, Debian 11+) |
| Software Module | pam_faillock.so |
| Configuration Pathways | /etc/pam.d/system-auth, /etc/pam.d/password-auth |
| Protocol Standard | POSIX.1 / PAM Infrastructure |
| Impact Level | 9/10 (Critical Security Component) |
| Resource Overhead | < 15MB RAM; Negligible CPU throughput impact |
| Data Persistence | Persistent tallying in /var/run/faillock/ |
The Configuration Protocol
Environment Prerequisites:
Before execution, verify that the system is running a modern version of the PAM library. Implementation requires root-level permissions via sudo or a direct UID 0 shell. The environment must have authselect installed if operating on RHEL-based systems to ensure configuration consistency. Ensure that existing authentication services, such as sshd, are active and that backup access (such as a physical console or an out-of-band management controller) is available to prevent accidental lockout during the transition.
Section A: Implementation Logic:
The logic of pam_faillock relies on the encapsulation of authentication attempts within a stackable modular framework. Unlike previous iterations, pam_faillock functions by tracking failed attempts in specific per-user files located in the non-persistent /var/run/faillock/ directory. The module is invoked twice in the PAM stack: first as a “preauth” to check if the user is already locked out, and second as an “authfail” to increment the tally if the current attempt fails. This dual-invocation pattern ensures that the system does not waste resources processing a password hash if the account is already in a restricted state. This reduces the thermal-inertia spikes associated with high-frequency brute-force attempts on the CPU.
Step-By-Step Execution
1. Verify Module Presence
Execute ls /usr/lib64/security/pam_faillock.so or ls /lib/x86_64-linux-gnu/security/pam_faillock.so to confirm the module is available in the system library path.
System Note: This ensures the dynamic linker can resolve the module at runtime. If the module is missing, the PAM stack will fail, potentially locking all users out of the system.
2. Configure Global Lockout Parameters
Open the /etc/security/faillock.conf file using a standard text editor like vi or nano.
System Note: Modifying this centralized configuration file allows for idempotent policy application across all services that utilize PAM. Define variables such as `deny = 5` and `unlock_time = 900`.
3. Initialize Authselect Profile
On RHEL-based systems, use the command authselect create-profile hardening-policy -b sssd.
System Note: This creates a custom site-specific profile. It prevents system updates from overwriting manual changes made to the /etc/pam.d/ directory, ensuring long-term stability of the security logic.
4. Integrate Faillock into the Auth Stack
Edit /etc/pam.d/system-auth to include the lines: auth required pam_faillock.so preauth silent deny=5 unlock_time=900 and auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900.
System Note: The `preauth` call immediately terminates the authentication loop if the failure threshold is met. The `authfail` call increments the tally in the event of an incorrect credential payload.
5. Define Account Management Requirements
Add account required pam_faillock.so to the account section of the same file.
System Note: This ensures that the lockout state is verified during the transition from authentication to session establishment. It acts as a final gatekeeper within the service logic.
6. Apply and Test the Configuration
Execute authselect select custom/hardening-policy –force to activate the new logic.
System Note: This command flushes the current PAM configuration and reloads the stack. Monitor /var/log/secure or /var/log/auth.log using tail -f to observe real-time intercept signals.
7. Manage Locked Accounts
Use the faillock –user
System Note: This tool provides a direct interface to the kernel-level tally files. It allows administrators to clear lockouts manually using the –reset flag without waiting for the `unlock_time` to expire.
Section B: Dependency Fault-Lines:
The primary failure point in PAM configuration is the order of modules. If pam_unix.so is listed as “sufficient” before the pam_faillock.so authfail call, a successful login will work, but failed attempts might never reach the faillock module. This creates a bypass vulnerability where the tally is never incremented. Furthermore, if the /var/run/faillock/ directory has incorrect permissions, the module will fail to write the failure records, leading to a “fail-open” or “fail-closed” state depending on the control flag used (required vs. requisite). Ensure that the systemd-tmpfiles service is correctly generating the necessary directory structures at boot.
THE TROUBLESHOOTING MATRIX
Section C: Logs & Debugging:
When a lockout fails to trigger, the first point of inspection is the system auth log. Search for the string “pam_faillock(sshd:auth): Target user…” in /var/log/secure. If the logs indicate “permission denied,” check the SELinux context of the faillock files using ls -Z /var/run/faillock/. The context should be `faillock_var_run_t`.
If users are being locked out after a single attempt, verify the `confining` parameters in /etc/security/faillock.conf. A common error is a mismatch between the `deny` count in the config file and the manual overriding parameters in the /etc/pam.d/ templates. Use grep -r “pam_faillock” /etc/pam.d/ to identify conflicting directives that might be causing unexpected latency in the authentication handshake.
Technical Fault Code Reference:
– PAM_AUTH_ERR: Generally indicates a password mismatch but can signify a failure in the faillock stack if the module cannot reach the backend tally data.
– PAM_MAXTRIES: Explicitly indicates that the pam_faillock threshold has been reached and the account is currently throttled.
OPTIMIZATION & HARDENING
Performance Tuning:
In environments with extreme login concurrency, such as large-scale VPN concentrators, the file-based backend of pam_faillock can become a minor bottleneck. To optimize, ensure the /var/run/ filesystem is mounted as tmpfs (RAM-based). This minimizes disk I/O latency and ensures that the tally files are purged upon system reboot, preventing “stale” lockouts after a power cycle.
Security Hardening:
For high-security assets, enable the `even_deny_root` option in the pam_faillock configuration. By default, the root user is exempt from lockout to prevent permanent denial-of-service against the administrator. However, in modern infrastructure, root should be accessed via sudo rather than direct login. Enabling `even_deny_root` prevents brute-force attacks on the most privileged account, provided that an alternative recovery path (like a physical serial console) exists. Additionally, set `audit` in the module arguments to log all failed attempts to the system audit daemon (auditd), providing a forensic trail for post-incident analysis.
Scaling Logic:
As the infrastructure scales from a single node to a distributed cluster, local PAM lockouts become difficult to synchronize. In these scenarios, transition the lockout logic to a centralized directory service like FreeIPA or Active Directory. These platforms utilize a centralized “Account Lockout Policy” that propagates across the network, ensuring that a user locked out on Server A cannot immediately attempt a brute-force attack on Server B. This maintains a uniform security posture across the entire administrative throughput.
THE ADMIN DESK
How do I unlock a user immediately?
Run the command faillock –user
Why does the root user never get locked out?
The default configuration protects the root account to prevent a DoS attack against the system administrator. To change this, you must explicitly add the `even_deny_root` parameter to both the `preauth` and `authfail` lines in your PAM configuration files.
Can I exempt certain IP addresses from lockout?
PAM itself does not natively support IP-based whitelisting within the pam_faillock module. To achieve this, use pam_access.so or configure firewall rules to allow trusted subnets to bypass the authentication stack via a different entry point.
What happens to lockouts after a system reboot?
By default, pam_faillock stores records in /var/run/faillock/, which is a volatile filesystem. All lockout tallies are cleared upon reboot. This is a design feature to ensure that systems remain accessible after a major power event or system crash.
How do I log all lockout events to a remote syslog?
Ensure that the `audit` flag is present in the pam_faillock lines within /etc/pam.d/system-auth. Then, configure rsyslog or systemd-journal-remote to forward all LOG_AUTH messages to your centralized Security Information and Event Management (SIEM) platform.



