Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Enforce a Linux VPS password policy through PAM: use pam_pwquality for password strength, a history module such as pam_pwhistory where supported, chage for per-account aging, and pam_faillock for failed-login lockouts. The exact include file and supported management tool depend on whether the server runs Ubuntu/Debian or RHEL 8, 9 or 10. Keep a working privileged session and a VPS-console recovery path open before changing PAM.

What a Linux VPS password policy controls

A policy is not one setting or one file. It is a set of PAM modules and account attributes applied at different points in the authentication and password-change process.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Strength: pam_pwquality checks length, character classes, dictionary words, username use, similarity to the old password, repeated characters and sequential characters.
  • History: a history module prevents reuse. RHEL identifies pam_pwhistory for this job.
  • Aging: chage stores minimum age, maximum age, inactivity and expiration values for each local account.
  • Lockout: pam_faillock counts consecutive authentication failures, records them per user and can temporarily lock an account.

PAM is the enforcement layer, but the active PAM include file is distribution-specific. A rule in a file that is not included by the active stack has no effect. Likewise, local PAM rules apply to local Unix password changes; they do not automatically govern every external identity system.

Prepare safely before editing PAM

Keep two recovery paths

Leave your current root or sudo session open while editing. Also confirm that your VPS provider’s out-of-band console works, or that another already-authorized administrator can log in. A syntax error or misplaced PAM control flag can deny both login and sudo, so do not test a lockout policy without a recovery route.

#1 Best Overall

Identify the operating system and release

Run:

cat /etc/os-release

Record the distribution and major release. Ubuntu and Debian normally assemble the local password stack through /etc/pam.d/common-password. RHEL 8, 9 and 10 use release-managed PAM profiles; their supported authentication-management method should be used instead of making untracked edits to generated files.

Test with a non-administrative account

Create or select a test user that has no sudo privilege. Change its password, inspect its aging values, and deliberately produce a controlled number of failed logins only after you know how to reset the resulting lock. Do not begin by changing the root account or your only administrator.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Ubuntu and Debian: configure password strength

Install the quality module

On systems where it is not already installed, install the package that supplies pam_pwquality:

sudo apt update
sudo apt install libpam-pwquality

Ubuntu’s documented local password stack is /etc/pam.d/common-password. Open it and locate the existing pam_pwquality.so or password-quality line rather than blindly appending a second competing rule:

sudo editor /etc/pam.d/common-password

The documented Ubuntu example raises the minimum from the six-character default to eight characters by adding minlen=8 to the pam_unix.so line. On a current installation, follow the line and control flags already generated for that release. PAM arguments placed directly on a module line override the corresponding values in the configuration file.

Set reusable rules in pwquality.conf

For rules that should be maintained centrally, edit:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo editor /etc/security/pwquality.conf

Common options include:

Option What it controls How to choose it
minlen Minimum password length. Set the length required by your threat model and service constraints. Ubuntu’s documentation shows minlen=8 as an example and describes six characters as the documented default.
dcredit, ucredit, lcredit, ocredit Digits, uppercase, lowercase and other-character requirements or credits. Use negative values when you require a class; avoid demanding complexity that encourages predictable substitutions.
dictcheck Dictionary-word checking. Keep it enabled unless you have a documented reason to disable it.
usercheck Rejects passwords containing the account name or a recognizable form of it. Keep it enabled for local accounts.
difok How different a new password must be from the old one. Use it with history controls so a user cannot make a trivial change to bypass policy.
maxrepeat Limits repeated consecutive characters. Set only when repeated-character passwords are a concern; document the value.
maxsequence Limits monotonic sequences such as ascending or descending runs. Use a value appropriate to your users and applications.

Exact option behavior is defined by the installed module version. If a module line contains an option also present in pwquality.conf, the line wins. After editing, change the test user’s password and confirm that an intentionally weak candidate is rejected while a compliant one succeeds.

Verify the active stack

Do not assume that editing a file changed every authentication path. Review the complete password stack and look for the quality module:

grep -n pam_pwquality /etc/pam.d/common-password
sudo chage -l USERNAME

The second command does not test complexity; it displays the account’s aging state. Test strength by performing an actual password change for the test user.

RHEL 8, 9 and 10: use the supported PAM profile

Assign each control to the correct module

Red Hat documents three separate modules for the usual policy components:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Requirement Module Purpose
Password complexity pam_pwquality Checks length, character classes, dictionary use, username use and related quality rules.
Password reuse pam_pwhistory Stores and checks previous passwords according to the configured history policy.
Failed-login lockout pam_faillock Counts failures, records them per user and applies lockout decisions.

Change the profile through the release’s management tool

RHEL uses a supported authentication-management method for its PAM profiles. Use that method for your release, then verify the generated result. Avoid hand-editing files that the profile manager may overwrite during an update or profile change. The exact profile command and available options differ by RHEL release and selected authentication source, so inspect the active profile before changing it.

After applying the profile, verify that the resulting stack contains the intended pam_pwquality, pam_pwhistory and, if enabled, pam_faillock entries in the correct auth and password sections. A module in the wrong section, or in the wrong order, can either fail to enforce the policy or lock users out unexpectedly.

Centralize quality and history values

RHEL installations commonly keep quality settings in the system password-quality configuration and history settings in the profile-managed history configuration. Use the files and profile controls supplied by your installed release, then perform a real password change with a test account. Module arguments on the PAM line take precedence over file values, so inspect both when a setting appears to be ignored.

Set password aging with chage

Password quality is checked when a password is set or changed. Aging is a separate, per-account policy. Inspect an account before changing it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo chage -l USERNAME

The listing shows the last change, minimum days between changes, maximum lifetime, warning period, and inactivity state. Apply only the controls your policy requires:

Command form Effect Operational consequence
sudo chage -m DAYS USERNAME Sets the minimum number of days before the password may be changed again. Prevents immediate cycling through passwords to evade history.
sudo chage -M DAYS USERNAME Sets the maximum password age. After the interval, the user must change the password.
sudo chage -W DAYS USERNAME Sets the warning period before expiration. Gives interactive users time to change the password before access is restricted.
sudo chage -I DAYS USERNAME Sets the inactivity period after expiration. Disables an account that remains unused after its password expires.
sudo chage -d 0 USERNAME Marks the password as changed on day zero. Forces a change at the next password-based login.

Apply aging to named human accounts rather than blindly applying it to service accounts. A daemon, deployment key owner or emergency account may not perform an interactive password change. If an account is intended to use SSH keys only, disable password authentication for that service separately instead of relying on an untested expiration workflow.

Re-run sudo chage -l USERNAME after each change. The values shown are the account’s effective settings, not merely the defaults in a login configuration file.

Configure failed-login lockout with pam_faillock

Understand the counters and timing

pam_faillock keeps failed-authentication records for each user. It locks an account after more than the configured number of consecutive failures within the configured interval. The upstream configuration reference lists these defaults:

Setting Documented default Meaning
deny 3 failures Number of consecutive failures that triggers a lock decision.
fail_interval 900 seconds (15 minutes) Window in which failures are counted.
unlock_time 600 seconds (10 minutes) How long a locked account remains unavailable when automatic unlocking is used.

These are upstream defaults, not a guarantee that every VPS image uses them. Check the effective configuration on your host and choose values deliberately. A low threshold reduces guessing opportunities but increases the chance that a mistyped password or an automated stale credential locks a user.

Decide how root is treated

even_deny_root determines whether root is subject to the failure limit. root_unlock_time controls the root-specific unlock period when root lockout is enabled. Locking root can improve resistance to guessing, but it also removes a critical recovery path. Make that choice only after confirming console access and another administrator account.

Enable it without breaking the stack

On RHEL, enable pam_faillock through the release’s supported authentication-management method and verify the resulting PAM stack. On Ubuntu or Debian, availability and the vendor-supported integration vary by release; inspect the active PAM files and follow that release’s documented method rather than copying RHEL lines into common-auth. The order of pre-authentication, authentication and account checks matters, so a seemingly correct line can still produce an unusable stack if inserted in the wrong place.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Once enabled, test with the non-privileged account. Use a failure count below the threshold first, then stop and confirm the account’s state before proceeding. Never test by repeatedly guessing the password for your only administrator.

Inspect and reset a lock

Use the faillock utility to inspect records and, when the operator has confirmed that the lock is expected and the account should be released, reset them:

sudo faillock --user USERNAME
sudo faillock --user USERNAME --reset

Resetting the record does not repair a bad PAM configuration. If the account immediately locks again, stop authentication testing, use the console or another administrator, and review the effective module order and thresholds.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Ubuntu/Debian and RHEL compared

Policy area Ubuntu/Debian RHEL 8, 9 and 10
Typical local password include /etc/pam.d/common-password is documented by Ubuntu. Release-managed PAM profile; the exact generated include depends on the selected profile.
Strength module libpam-pwquality supplies pam_pwquality where not already installed. pam_pwquality.
History module Not stated as one universal implementation; inspect the active stack. pam_pwhistory.
Lockout module Availability and vendor integration are release-specific; verify the active stack. pam_faillock.
Profile management Edit the documented include and quality configuration, preserving the existing stack structure. Use the release’s supported authentication-management method and verify generated files.
Password aging chage. chage.
Lock inspection and reset faillock when that module is enabled. faillock.

Validate the policy as an operator

  1. Confirm the target account. Check the username and whether it is local, federated or a service identity.
  2. Check the active files. Confirm that the relevant PAM include is actually referenced by the login and password-change services you care about.
  3. Test strength. Attempt a password that violates one rule at a time, then set a compliant password. Record the exact rejection behavior.
  4. Check aging. Run sudo chage -l USERNAME and verify the dates, minimum, maximum, warning and inactivity values.
  5. Test lockout conservatively. Use a test account, stay below the threshold initially, and keep the console session available.
  6. Inspect the counter. Run sudo faillock --user USERNAME and confirm that failures are recorded as expected.
  7. Recover deliberately. Reset only the intended test record with sudo faillock --user USERNAME --reset, then verify that a legitimate login works.
  8. Document the effective policy. Record the distribution release, module versions, values, profile-management method and recovery procedure so an update does not silently change the result.

Common failure modes and fixes

The rule has no effect

Most often, the edited file is not in the active PAM path, a second module line overrides it, or the service uses a different PAM stack. Confirm the include chain and search for duplicate pam_pwquality.so entries. Remember that module-line arguments override pwquality.conf.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Users cannot change passwords after an edit

Keep the existing privileged session open. Compare the edited line with the distribution’s original control flags and module order, then restore the last known-good configuration from the console if necessary. Do not repeatedly attempt sudo or SSH logins while diagnosing a possible lockout.

A locked account remains locked

Inspect its record with faillock --user, check whether an automated process is still submitting an old password, and verify the configured interval and unlock behavior. Reset the record only after confirming the cause.

Password expiration breaks automation

Review accounts used by scheduled jobs, deployment tools and daemons before enforcing maximum age or inactivity. Use non-interactive authentication designed for that service and document exceptions; do not give a service account an unmanaged, never-expiring interactive password as a quick workaround.

Federated users are unaffected

Local libpwquality settings govern local Unix password changes. Ubuntu’s authd documentation states that they do not apply to Entra ID passwords authenticated through the Entra flow. That password policy must be enforced by the identity provider’s tenant. Treat other external identity paths the same way: identify where the password is actually changed and enforce policy there.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose policy values deliberately

Start by writing the requirement in plain language, then map it to a module or account setting. For example, “reject short or dictionary-based local passwords” belongs to pam_pwquality; “remember previous passwords” belongs to the history module; “force a change after a defined lifetime” belongs to chage; and “block repeated guesses for a period” belongs to pam_faillock.

  • Set a minimum length that users can satisfy with unique passphrases, and test it against the applications that accept the password.
  • Use dictionary and username checks to stop predictable choices rather than relying only on a long list of mandatory character substitutions.
  • Pair minimum age and history so users cannot rotate through old values immediately.
  • Set maximum age and inactivity only where the operational owner can perform timely changes.
  • Choose lockout thresholds and intervals with the expected typo rate, automation and support response in mind.
  • Decide explicitly whether root is covered, and make the recovery route part of the policy document.
  • Separate local accounts from federated identities; one PAM file cannot enforce a password rule at an external identity provider.

Practical command checklist

# Identify the release
cat /etc/os-release

# Ubuntu/Debian quality package and files
sudo apt update
sudo apt install libpam-pwquality
sudo editor /etc/security/pwquality.conf
sudo editor /etc/pam.d/common-password

# Inspect or set per-account aging
sudo chage -l USERNAME
sudo chage -m DAYS USERNAME
sudo chage -M DAYS USERNAME
sudo chage -W DAYS USERNAME
sudo chage -I DAYS USERNAME
sudo chage -d 0 USERNAME

# Inspect or clear a faillock record when pam_faillock is enabled
sudo faillock --user USERNAME
sudo faillock --user USERNAME --reset

Replace USERNAME and DAYS with real values only after reviewing the account and the change window. The commands inspect or alter local accounts; they do not change passwords held by an external identity provider.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.