Skip to content

Login Definitions

/etc/login.defs sets the password aging defaults every new account inherits. It's the Linux equivalent of the maximum and minimum password age settings on Windows, and an image usually ships with them at "never".

The values

Setting Meaning Value Why
PASS_MAX_DAYS Days a password stays valid 30 to 90 (use 90, or 60 for a STIG baseline, UBTU-22-411030; CIS 5.3.1.1 accepts up to 365, Level 2) A stolen hash has a shelf life. 99999 (the default) means forever.
PASS_MIN_DAYS Days before a password can be changed again 10 to 30 (use 10; CIS 5.3.1.2 and STIG UBTU-22-411025 ask for at least 1) Stops a user from changing their password ten times in a row to get back to the old one, which defeats history
PASS_WARN_AGE Days of warning before expiry 7 to 14 (use 14; CIS 5.3.1.3 asks for at least 7) People change it on time instead of getting locked out
ENCRYPT_METHOD Hash used by passwd when PAM doesn't say YESCRYPT or SHA512 (CIS 5.3.1.4) Anything else is crackable
UMASK Default permissions for new files 027 (CIS 5.3.3.3), or 077 for a STIG baseline (UBTU-22-412035) New files aren't world-readable (077: not readable by anyone but the owner)

Apply

sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS\t90/' /etc/login.defs
sudo sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS\t10/' /etc/login.defs
sudo sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE\t14/' /etc/login.defs

Or sudo nano /etc/login.defs, find the three lines (they're about a third of the way down), and change the numbers. Each line is the name, whitespace, the number, nothing else, and it must not start with #.

sudo sed -i 's/^ENCRYPT_METHOD.*/ENCRYPT_METHOD YESCRYPT/; s/^UMASK.*/UMASK\t\t027/' /etc/login.defs

The inactive-account default lives in a different file: sudo useradd -D -f 45 sets INACTIVE=45 in /etc/default/useradd (CIS 5.3.1.5, Level 2; the STIG says 35, UBTU-22-411035), so a new account whose password expires locks 45 days later.

Existing accounts

login.defs only affects accounts created after the change. Everyone already on the machine keeps their old values until chage fixes them, which is on the Passwords and Shells page.

Verify

grep -E '^(PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE|ENCRYPT_METHOD|UMASK)' /etc/login.defs

Five lines, none commented.

Example

grep -E '^PASS_' /etc/login.defs shows PASS_MAX_DAYS 99999, PASS_MIN_DAYS 0, PASS_WARN_AGE 7. Set 90, 10, 14. Then sudo chage -l bob still shows Maximum 99999, because bob existed before the change; run the chage loop from the accounts page.

Try it

  1. Set the three PASS values, create a new user, and confirm chage -l on the new user shows them.
  2. Change UMASK to 027, log in again, create a file, and read its permissions.

Build it

A logindefs.sh that uses sed -i to set each value and then greps them back. Five lines, and the pattern transfers to every key value config file.

Next

Password Quality and Hashing