October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Set a Password Policy on a Linux VPS: Ubuntu, Debian and RHEL

Configure password strength, history, aging and failed-login lockout on Ubuntu, Debian and RHEL VPSs using the correct PAM files and safe recovery procedures.
Length11 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Enforce a Linux VPS password policy through PAM: use pam_pwquality for password strength, pam_pwhistory for reuse prevention where supported, chage for per-account aging, and pam_faillock for failed-login lockout. The files and supported management tools differ between Ubuntu/Debian and RHEL-family systems, so identify the distribution and active PAM stack before changing anything.

What a Linux VPS password policy actually controls

“Password policy” is not one setting. It is a group of controls applied at different points in authentication and account administration:

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Strength checks: PAM evaluates a new password for length, character classes, dictionary words, username content, similarity to the old password, repeated characters and monotonic sequences. The pam_pwquality module performs these checks.
  • Password history: A history module rejects recently used passwords. On RHEL 8, 9 and 10, Red Hat documents pam_pwhistory for this job.
  • Password aging: The chage command sets minimum and maximum intervals, inactivity after expiration and an account-expiration date for each local account.
  • Failed-login lockout: pam_faillock counts consecutive authentication failures, records them per user and locks an account when the configured threshold and time window are reached. The faillock command displays and clears those records.

PAM is the enforcement layer for local Unix password changes and local authentication. The include file that PAM reads is distribution-specific; editing a file that is not in the active stack has no effect, while editing the wrong line can prevent logins. Keep a second, already-authorized administrative session open throughout the work.

Before editing PAM: identify the system and create a recovery path

Confirm the distribution and release

Read the release information and note whether the VPS runs Ubuntu or Debian, or a RHEL-family release such as RHEL 8, 9 or 10. Package names, include files and vendor-supported PAM management differ by release. Do not copy an Ubuntu PAM line into a RHEL configuration or vice versa.

cat /etc/os-release
uname -a

Keep an administrative escape route

  • Leave your current root or sudo-capable SSH session connected while testing.
  • Confirm that the VPS provider’s out-of-band console works before testing lockout or password changes.
  • Have another authorized administrator available if the only privileged account is being changed.
  • Use a non-privileged test account first. Do not test a new PAM policy by repeatedly failing the only administrator’s login.

Back up and record the current state

Copy every PAM file you will edit and record the current account-aging and lockout state. A backup lets you restore the exact previous configuration from the console if SSH authentication breaks.

sudo cp -a /etc/pam.d/common-password /etc/pam.d/common-password.before-policy 2>/dev/null || true
sudo cp -a /etc/security/pwquality.conf /etc/security/pwquality.conf.before-policy 2>/dev/null || true
sudo cp -a /etc/security/faillock.conf /etc/security/faillock.conf.before-policy 2>/dev/null || true
sudo chage -l USERNAME
sudo faillock --user USERNAME

The backup commands tolerate a file that is not present on a particular distribution. Store the copies somewhere protected from ordinary users and document who can restore them.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Ubuntu and Debian: configure password strength with PAM

Find the active password stack

Ubuntu documents the local password stack in /etc/pam.d/common-password. Debian derivatives can use a similar common include, but inspect the file on the actual VPS rather than assuming the path. Look for a line invoking pam_unix.so and, if present, pam_pwquality.so.

sudo grep -nE 'pam_(unix|pwquality|pwhistory)' /etc/pam.d/common-password

Ubuntu’s current Server documentation describes a six-character minimum in its documented default stack. That is a distribution-documentation default, not a requirement that every Ubuntu image or cloud image has identical contents.

Install the quality module when necessary

Install the package if the module is not already available:

sudo apt update
sudo apt install libpam-pwquality

Package installation may add or update PAM entries. Re-open /etc/pam.d/common-password after installation and verify the resulting order before making further edits.

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

Put strength rules in the policy file

The maintainable location for site-wide quality settings is /etc/security/pwquality.conf. Create a backup, open the file, and set only the controls your security requirement justifies:

sudo editor /etc/security/pwquality.conf

The module supports a minimum length, required character classes, dictionary checking, rejection of passwords containing the username, similarity checks, repeated-character limits and monotonic-sequence limits. A policy might require a longer minimum than Ubuntu’s documented six-character default and enable checks for username, dictionary and obvious repetition. Treat those values as your organization’s policy choices; the operating system does not supply one universally correct combination.

Common options include minlen for minimum length, class-credit settings for uppercase, lowercase, digits and other characters, and checks such as dictcheck, usercheck, maxrepeat and maxsequence. Read the installed module’s manual page before selecting a value, because credit options can change how a length requirement is calculated.

Ensure the module is called by the active stack

Open the common password file and verify that a pam_pwquality.so line appears before the password is committed by pam_unix.so. If you add module arguments directly on that line, those arguments override the corresponding values in pwquality.conf. Keeping policy values in one file avoids a hidden line-level override.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo editor /etc/pam.d/common-password
sudo grep -n 'pam_pwquality.so' /etc/pam.d/common-password

Do not delete unrelated use_authtok, control flags or include lines without understanding their purpose. PAM control syntax determines whether a failed quality check stops the password change or is ignored.

RHEL 8, 9 and 10: use the documented module roles and vendor tooling

Understand the separation of responsibilities

Red Hat documents three separate PAM modules for this policy:

Requirement RHEL module or command What it does
Password complexity pam_pwquality Checks the proposed password against quality rules.
Password reuse history pam_pwhistory Rejects passwords that match a configured number of previous passwords.
Failed-login lockout pam_faillock Counts failures and applies the lockout policy.
Account aging chage Sets and reports per-account password dates and intervals.

Use the release’s supported PAM management method

RHEL releases provide a vendor-supported authentication-management method. Use that method for the release instead of making an unmanaged hand edit that a later authentication update could replace. After applying a change, inspect the generated or active PAM stack and confirm that the expected pam_pwquality, pam_pwhistory and pam_faillock entries are present in the correct password or authentication sections.

sudo grep -R -nE 'pam_(pwquality|pwhistory|faillock)' /etc/pam.d

The exact include files vary by release and authentication profile. If a file is generated by the vendor tool, edit the profile or configuration source that the tool documents, then regenerate the stack and verify it. Direct edits to generated files can disappear during a profile change.

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

Configure password history deliberately

Choose how many previous passwords must be remembered and set that value through the supported RHEL mechanism for your release. History improves resistance to cycling through a small set of familiar passwords, but it does not make a short or predictable password strong; keep the quality checks enabled as well.

Set password aging with chage

Password aging is per account. A system-wide quality rule does not automatically set expiration dates for users that already exist. First inspect the account:

sudo chage -l USERNAME

The report shows the last password change, minimum and maximum days between changes, warning period, inactivity period and account-expiration date. Set only the fields your policy requires:

Goal Command form Effect
Require a waiting period before another change sudo chage -m DAYS USERNAME Sets the minimum number of days between password changes.
Force periodic changes sudo chage -M DAYS USERNAME Sets the maximum password age in days.
Disable after expiration sudo chage -I DAYS USERNAME Sets the inactivity period after the password expires.
Expire the account on a date sudo chage -E YYYY-MM-DD USERNAME Sets the account expiration date.
Require a change at the next login sudo chage -d 0 USERNAME Sets the last-change date to the epoch so the password is immediately considered expired.

For example, the following sets a 24-hour minimum and a 90-day maximum for a local account; replace those figures with the interval approved for your environment:

sudo chage -m 1 -M 90 USERNAME
sudo chage -l USERNAME

A maximum age that is too short can encourage users to write passwords down or make predictable variations. Balance expiration against stronger passwords, multifactor authentication and the risk profile of the account. Apply aging to local accounts individually, including service accounts only after confirming that an automated process can handle the change.

Configure failed-login lockout with pam_faillock

How the counter works

pam_faillock keeps failed-authentication records per user. When failures exceed the configured threshold within the configured interval, the account is locked. The faillock command lets an operator inspect the record and reset it after confirming that the lockout is expected.

The Linux-PAM upstream faillock.conf reference lists these defaults:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Setting Documented upstream default Meaning
deny 3 failures Lock after more than the configured number of consecutive failures.
fail_interval 900 seconds (15 minutes) Time window in which failures are counted.
unlock_time 600 seconds (10 minutes) Automatic unlock period when configured.

These are upstream defaults, not a guarantee that every VPS image has the same effective settings. Inspect the active configuration and vendor profile. The even_deny_root and root_unlock_time settings determine whether root is subject to the policy and how root can be released. Locking root without a tested console path can turn a small test into a full administrative outage.

Choose a lockout policy

Set the threshold, interval and unlock behavior according to the threat model and support process. A short threshold limits password guessing but increases the chance that a mistyped password or an attack against a shared account causes a denial of service. Decide explicitly whether root should be protected, whether automatic unlocking is acceptable, and who may reset a lock.

On systems that use the standard configuration file, the relevant settings are maintained in /etc/security/faillock.conf or through the distribution’s supported PAM management method. Avoid placing conflicting arguments on individual PAM lines and in the configuration file: a module argument can override the file value.

Inspect and reset a lock safely

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

Use --reset only after confirming the account owner, the cause of the failures and the authorization to release the account. If the failures are malicious, reset the record only as part of incident response and change the credential or disable the account as appropriate. Keep the provider console or another authorized administrator available before deliberately triggering a lockout.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Test the policy without locking yourself out

  1. Create a temporary local account. Give it no unnecessary privileges and record its username so its aging and lockout records are easy to identify.
  2. Test strength rejection. Attempt a password that is below the configured length, contains the username or violates a selected class, dictionary, repetition or sequence rule. Confirm that the password change is rejected with a useful error.
  3. Test an acceptable password. Change the test account to a password that meets every selected rule and confirm that a new login succeeds.
  4. Inspect aging. Run sudo chage -l TESTUSER and verify the dates and intervals match the intended values.
  5. Exercise lockout carefully. Make only the planned number of failed attempts from a controlled client, then check sudo faillock --user TESTUSER. Do not perform this test against the sole administrator.
  6. Verify recovery. Confirm the account remains inaccessible while locked, then reset it with sudo faillock --user TESTUSER --reset or wait for the configured unlock period and verify the documented behavior.
  7. Review real authentication paths. Test SSH, console access and any service that changes passwords. A policy attached only to one PAM service does not automatically cover every other service.
  8. Remove the test account. Delete it and its home directory after the results are recorded.
sudo useradd --create-home TESTUSER
sudo passwd TESTUSER
sudo chage -l TESTUSER
sudo userdel --remove TESTUSER

Use a separate terminal for each test and leave the original privileged session untouched. If a password change unexpectedly succeeds, inspect the active PAM include chain rather than assuming the policy is enforced.

Troubleshooting common failures

The rule has no effect

  • Confirm that the edited file is included by the PAM service handling the operation.
  • Check that the relevant module is installed and that the line names the correct shared object.
  • Look for module arguments on the PAM line; they override values in pwquality.conf.
  • On RHEL, determine whether a vendor-managed profile regenerated the file after your edit, then change the supported source and regenerate it.

SSH access fails after a PAM edit

Do not close the surviving session. Use the provider console or another administrator to restore the backup, check PAM syntax and review authentication logs for the failing module. Reapply one change at a time and retest with the temporary account.

The account remains locked after the password is corrected

A correct password does not necessarily clear the failure record. Inspect it with sudo faillock --user USERNAME, verify that the lockout interval has elapsed or that automatic unlocking is configured, and reset it explicitly only after authorization.

Users authenticate through an external identity provider

Local libpwquality settings govern local Unix password changes. Ubuntu’s authd documentation states that these settings do not apply to Entra ID passwords authenticated through the Entra flow; that password policy is enforced by the identity provider’s tenant. Treat federated identities separately and do not claim that a local PAM rule protects a password that the VPS never changes or validates.

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

Ubuntu/Debian and RHEL at a glance

Policy area Ubuntu/Debian approach RHEL 8–10 approach
Primary password include Ubuntu documents /etc/pam.d/common-password; verify the equivalent on Debian. Use the release’s vendor-managed PAM profile and verify generated include files.
Strength module Install libpam-pwquality when absent; configure /etc/security/pwquality.conf and the active stack. pam_pwquality, configured through the supported RHEL authentication method.
Password history Depends on the modules enabled by the image and administrator; inspect the active stack. Red Hat documents pam_pwhistory.
Account aging chage for inspection and per-account settings. chage for inspection and per-account settings.
Lockout Use the lockout module and configuration present on the image; verify rather than assuming upstream defaults. pam_faillock with the release’s supported configuration method.
Recovery Keep an existing sudo session and VPS console; inspect or reset with faillock where enabled. Keep an existing administrative session and console; inspect or reset with faillock.

Production checklist

  • Distribution and release identified; active PAM include files confirmed.
  • Privileged SSH session and VPS console recovery tested.
  • Configuration backups created and protected.
  • pam_pwquality strength rules selected and tested.
  • Password-history behavior enabled and verified where required.
  • chage -l reviewed for every affected local account.
  • Lockout threshold, interval, unlock period and root treatment documented.
  • faillock inspection and authorized reset procedure documented.
  • Local and federated authentication paths distinguished.
  • Test account removed only after successful strength, aging, lockout and recovery tests.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.