How to Harden and Secure a Linux Server: Part 2

In the previous post we looked at how to configure the OpenSSH config file to make it more secure. In this post I'll explain ways to enforce a secure password policy for users of a Linux server.

Password Policies

A password policy is a set of rules regarding user passwords that must be satisfied. It can include specifications and requirements such as password complexity, age, number of login failures, and if reusing old passwords is allowed or denied.

You can find password length and age settings in /etc/login.defs.

Note that all the parameters in login.defs are applicable only for new accounts and not for the existing ones. Open the file with vim and search for the following password aging controls:

# 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.
#
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_WARN_AGE   7

These values are the defaults; be sure to set these values to your desired password policy.

Another password setting is password minimum length. you can edit this in the file (it’s not there by default), by adding this line:

PASS_MIN_LEN <number>

The chage command

The chage command is used to view and modify a user's account and password expiry information. Some of its uses includes manually setting the number of days between password changes, changing the date of the last password change, and setting the account expiry date. This information is used by the system to determine when a user must change their password.

For example, to see a user's account agin information, run the following:

sudo chage -l user

You can expect to see this output:

root@ubuntu:~# chage -l dion
Last password change                    : Nov 25, 2022
Password expires                    : Feb 23, 2023
Password inactive                   : never
Account expires                     : never
Minimum number of days between password change      : 0
Maximum number of days between password change      : 90
Number of days of warning before password expires   : 7

PAM

A strong password should consist of a combination of upper, lower, numeric and special characters. and should be at least 10 characters long. PAM, or Pluggable Authentication Module, is used to enforce password complexity on most Linux distros.

The config file location is slightly different based on distribution:

  • Ubuntu
    /etc/pam.d/common-password
  • Redhat/CentOS
    /etc/pam.d/system-auth

I'm using Ubuntu, so to outline a couple of the options we have to set password requirements, I open the common-password file in vim, and find this line:

# here are the per-package modules (the "Primary" block)
password        requisite                       pam_pwquality.so

I then add the following attributes:

# here are the per-package modules (the "Primary" block)
password        requisite                       pam_pwquality.so retry=3 minlen=8 difok=3 
ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1

These attributes implement the following password requirements:

  • retry=3 means the system will prompt the user three times before exiting and returning an error.
  • minlen=8 will require the password to be no less than 8 characters.
  • difok=3 means there must be a minimum of three characters that are different from the old password.
  • ucredit=-1 requires at least one uppercase character in the password.
    * lcredit=-1 requires at least one lower case character in the password.
  • dcredit=-1 requires at least one numeric value (a digit).
  • ocredit=-1 requires at least on special character. (The "o" stands for "other value").