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:

  1. Open a terminal on the server with an account that can use sudo.
    $ whoami
    root
  2. 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.

  3. 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.

  4. 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.

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

  6. 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.

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

  8. 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.

  9. 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.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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.

  17. 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.