How to Enforce Strong Password Policies on a Linux Server Using pam_pwquality

Use the pam_pwquality PAM module by installing libpam-pwquality, configuring /etc/pam.d/common-password with complexity requirements like minimum length and character classes, and applying the changes with a sed one-liner to reject weak passwords automatically.

According to the imthenachoman/How-To-Secure-A-Linux-Server repository, enforcing strong password policies is essential for securing user credentials against brute-force attacks. The recommended approach leverages pam_pwquality, a pluggable authentication module that validates passwords against configurable quality rules before allowing changes. This guide covers the exact implementation steps, configuration parameters, and commands used in the source repository to harden password requirements on Debian-based systems.

Install the Required PAM Module

First, install the pam_pwquality package. On Debian and Ubuntu systems, this is provided by libpam-pwquality:

sudo apt-get install -y libpam-pwquality

This installs the pam_pwquality.so plugin that integrates with the Linux PAM framework to enforce policy during password creation or modification.

Configure the PAM Password Stack

The password policy is enforced by modifying /etc/pam.d/common-password, which controls how password changes are processed by the system's authentication stack.

Backup the Original Configuration

Before editing system authentication files, create a timestamped backup to ensure you can restore the original settings:

sudo cp /etc/pam.d/common-password \
    /etc/pam.d/common-password.bak.$(date +%Y%m%d%H%M%S)

Insert the pam_pwquality Configuration

According to the repository's README (around line 1269), the module must be loaded in the password stack with the requisite control flag. The basic entry structure is:

password        requisite                       pam_pwquality.so

However, to enforce a truly robust policy, you must append specific quality parameters to this line.

Define Strong Password Parameters

To enforce a high-security baseline, configure the module with strict complexity requirements. The repository recommends the following configuration (see README line 1275):

password        requisite                       pam_pwquality.so \
    retry=3 minlen=10 difok=3 \
    ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 \
    maxrepeat=3 gecoscheck

Parameter breakdown:

  • retry=3 – Allows three attempts before aborting the password change operation.
  • minlen=10 – Requires passwords to be at least 10 characters in length.
  • difok=3 – Mandates that at least three characters must differ from the previous password.
  • ucredit=-1 – Requires at least one uppercase letter.
  • lcredit=-1 – Requires at least one lowercase letter.
  • dcredit=-1 – Requires at least one digit.
  • ocredit=-1 – Requires at least one special (other) character.
  • maxrepeat=3 – Prevents any character from appearing more than three times consecutively.
  • gecoscheck – Rejects passwords containing the user's full name or account name as listed in the GECOS field.

Apply Changes Idempotently

To ensure the configuration is applied consistently without creating duplicate entries, the repository provides a sed command that comments out any existing pam_pwquality.so line and appends the new hardened policy (see README line 1294):

sudo sed -i -r -e \
  's/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2\

\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoscheck/' \
  /etc/pam.d/common-password

This command preserves the original line (commented out for reference) and inserts the comprehensive policy, ensuring the changes survive configuration management runs.

Verify the Policy Implementation

After applying the configuration, test the enforcement by attempting to set a weak password:

sudo passwd someusername

The system should reject passwords that violate the complexity requirements—such as "password", "123456", or any string containing the username—and display an informative error explaining which specific rule was breached.

Summary

  • Install libpam-pwquality to provide the pam_pwquality.so authentication module.
  • Modify /etc/pam.d/common-password to load the module with the requisite control flag.
  • Configure minlen, ucredit, lcredit, dcredit, and ocredit values to enforce minimum length and mandatory character diversity.
  • Use difok, maxrepeat, and gecoscheck to prevent password similarity to old passwords and personal information.
  • Apply changes using the idempotent sed command from the imthenachoman/How-To-Secure-A-Linux-Server repository to maintain clean, auditable configuration files.

Frequently Asked Questions

What is the difference between pam_pwquality and pam_cracklib?

pam_pwquality is the modern replacement for pam_cracklib, offering additional checks like maxrepeat and gecoscheck along with tighter integration with the pwquality library. According to the repository documentation, pam_pwquality provides more granular control over password complexity and should be used on current Debian and Ubuntu systems instead of the deprecated pam_cracklib.

How do I verify that the password policy is active without changing my current password?

Attempt to change a test user password using sudo passwd testuser and try entering a weak password like "abc" or the username itself. If the configuration is correct, the system will reject the attempt immediately with a specific error message indicating the policy violation, such as "BAD PASSWORD: The password contains the user name in some form" or requirements for character complexity.

Can I relax the password policy for specific service accounts or groups?

While /etc/pam.d/common-password applies system-wide policies, you can create exceptions by modifying the PAM stack to use different control flags (like sufficient instead of requisite) for specific services. However, the repository recommends maintaining uniform strong policies across all interactive accounts to prevent credential-based attacks, as weak service account passwords often become entry points for lateral movement.

Where does pam_pwquality log failed password attempts?

Failed password change attempts are typically logged to /var/log/auth.log on Debian-based systems. You can audit policy violations by running grep pwquality /var/log/auth.log, which will show rejected attempts along with the specific rule that triggered the rejection, helping administrators monitor compliance with the enforced strong password policies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →