How To Setup Strong Password Policy On Ubuntu 18.04 | 16.04

Step 1: Ensure Passwords Expire

In most cases, passwords are configured to expire every 60 to 90 days.

If you want to configure Ubuntu to force users to change password regularly, you can run the commands below to open the login.defs file.

sudo vi /etc/login.defs

For example, if you want account password to be changed every 60 days, and the number of days before it changes again, edit the highlighted lines in the file.

You can also set the number of days warning is given before a password expires.

# Password aging controls:
#       PASS_MAX_DAYS   Maximum number of days a password may be used.
#       PASS_MIN_DAYS   Minimum number of days allowed between password changes.
#       PASS_WARN_AGE   Number of days warning given before a password expires.

Save the file and exit.

Step 2: Configure PAM Password Module

There is a PAM module called pam_pwquality that can be included with Ubuntu to require strong passwords for system users. pam_pwquality performs a number of basic checks, just like the old pam_cracklib module, including not allowing password to including username from the GECOS field, reject password with more than N number of characters, and many other password related checks.

To install and use pam_pwquality module, run the commands below:

sudo apt install libpam-pwquality cracklib-runtime

pam_pwquality main configuration file is at /etc/pam.d/common-password. Run the commands below to edit the file.

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

A good password requirement will follow similar guidelines.

  • Allow N number of retries before returning error [retry=3]
  • Set a minimal password length [minlen=8]
  • Set N number of repeated characters [maxrepeat =3]
  • Password must have uppercase characters [ucredit = -1]
  • Password must have lowercase characters [dcredit=-1]
  • Reject password with account name found in GECOS [gecoscheck=1]

Edit the highlighted line and add some of the requirements above to enforce.

# here are the per-package modules (the "Primary" block)
password        requisite              retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 difok=3 gecoscheck=1 reject_username enforce_for_root

password        [success=1 default=ignore] obscure use_authtok try_first_pass sha512
# here's the fallback if no module succeeds
password        requisite             
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around