Limiting how many times an account can fail to authenticate before being blocked is a core hardening control on Linux servers. Account lockout policies reduce the window for brute‑force password guessing on services like SSH, console login, and remote administration tools, especially when hosts are reachable from untrusted networks.
Linux distributions implement this control through Pluggable Authentication Modules (PAM) using the pam_faillock module and the /etc/security/faillock.conf configuration file. pam_faillock tracks failed authentication attempts per user in a tally directory and denies access once a configurable threshold of consecutive failures is reached, integrating with the auth and account phases of the PAM stack.
Incorrect PAM ordering or thresholds that are too strict can lock legitimate users out of critical systems, including administrative accounts, so configuration changes must be applied cautiously and tested on non‑privileged users first. On Ubuntu and Debian, enabling pam_faillock in /etc/pam.d/common-auth and /etc/pam.d/common-account applies the policy to most login paths, while values in /etc/security/faillock.conf tune how aggressively failures are counted and how long accounts remain locked.
Steps to automatically lock accounts after failed login attempts:
- Open a terminal on the server with an account that can use sudo.
$ whoami root
- Open a second privileged shell or console session for recovery before changing PAM configuration.
$ sudo -i
Misordered PAM entries can block all interactive logins, so a spare root session is essential for restoring backups if authentication fails.
- Create backups of the existing /etc/pam.d/common-auth and /etc/pam.d/common-account files.
$ sudo cp /etc/pam.d/common-auth /etc/pam.d/common-auth.backup $ sudo cp /etc/pam.d/common-account /etc/pam.d/common-account.backup
Backups allow quick rollback by copying the saved files back into place from the recovery shell if logins stop working.
- Open or create the /etc/security/faillock.conf policy file.
$ sudo nano /etc/security/faillock.conf
/etc/security/faillock.conf is the preferred location for pam_faillock options on modern Linux systems.
- Define a lockout policy such as five failed attempts within fifteen minutes and a ten‑minute lockout period.
# /etc/security/faillock.conf deny = 5 fail_interval = 900 unlock_time = 600
deny is the number of consecutive failures allowed, fail_interval is the window in seconds in which those failures are counted, and unlock_time is the lock duration in seconds.
- Open the /etc/pam.d/common-auth file for editing.
$ sudo nano /etc/pam.d/common-auth
Only change the auth block for local password authentication and leave distribution‑managed comments and include statements intact to avoid breaking other authentication methods.
- Add a pre‑authentication pam_faillock check as the first auth entry in the Primary block.
auth required pam_faillock.so preauth
The preauth call checks the current tally before prompting for a password and immediately denies access if the account is already locked.
- Adjust the main pam_unix.so password line so that a successful login skips later failure handlers.
auth [success=2 default=ignore] pam_unix.so nullok
The success=2 control value jumps over the next two auth lines when authentication succeeds, avoiding unnecessary deny and lock processing.
- Insert a failure handler using pam_faillock immediately before the pam_deny.so line in the same block.
auth [default=die] pam_faillock.so authfail
This entry increments the failure tally when authentication fails and terminates the stack with an error once the configured threshold is exceeded.
- Add a success handler at the end of the Primary auth block to clear counters after valid logins.
auth sufficient pam_faillock.so authsucc
Placing the success handler at the end of the block allows normal authentication modules to run first and then resets the tally when the overall result is successful.
- Save /etc/pam.d/common-auth and close the editor.
If logins fail during testing, restore the backup by copying /etc/pam.d/common-auth.backup back over /etc/pam.d/common-auth from the recovery shell.
- Open the /etc/pam.d/common-account file for editing.
$ sudo nano /etc/pam.d/common-account
The account phase enforces lockouts even if password checks succeed, so pam_faillock must also participate in this part of the stack.
- Add a pam_faillock account line near the end of the Primary block.
account required pam_faillock.so
Using the required control flag ensures that account evaluation fails when the tally indicates the user is locked.
- Save /etc/pam.d/common-account and close the editor.
Keep the backup file until the configuration has been validated across all login paths used on the system.
- From a separate session, generate several failed logins for a non‑privileged test account to trigger the lockout threshold.
$ sshpass -p "badpass" ssh appuser@localhost Permission denied, please try again.
Using a dedicated test account avoids unintentionally locking an administrator out of the system during validation.
- Inspect the failure tally for the test account with faillock to confirm the account is locked after the configured number of attempts.
$ sudo faillock --user appuser appuser: When Type Source Valid 2025-12-28 21:00:02 RHOST 127.0.0.1 V 2025-12-28 21:00:04 RHOST 127.0.0.1 V 2025-12-28 21:00:07 RHOST 127.0.0.1 V 2025-12-28 21:00:10 RHOST 127.0.0.1 V 2025-12-28 21:00:13 RHOST 127.0.0.1 V
faillock reads per‑user tally files from the failure directory and shows recent invalid attempts that contribute to the lockout state.
- Reset the tally for the test account to unlock it and verify that the entry disappears.
$ sudo faillock --user appuser --reset $ sudo faillock --user appuser appuser: When Type Source Valid
Use the reset command to clear the failure count after investigating suspicious activity so that legitimate users can log in again.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
