1. Overview

Password policies are one of the security pillars in system administration even if a system has a single user. Especially when talking about aging options, users are required to update their passwords regularly to avoid any kind of threat or data violation.

On the other hand, the latest version of NIST password guidelines comes with changes to password requirements. One of the most important guidelines is to avoid frequent password updates. The cause is that it’s common to create passwords that are oddly similar to those already used in the past, making them predictable.

In this tutorial, we’ll focus on passwords without any age limits in Linux systems. First, we’ll go through command line utilities: passwd and chage to create or update passwords and manage aging parameters. Then, we’ll look at configurations that can be applied to the /etc/shadow and /etc/login.defs system files. For the most part, we’ll need superuser access to run these commands and edit system files.

2. Using chage and passwd Commands

The name of the chage command stands for “change age”. It tracks user account and password aging data such as expiry dates, maximum and minimum password ages, warning ages, and other details.

Let’s run chage with the -l flag to list the aging details for the baeldung user, supplied as an argument:

$ chage -l baeldung    
Last password change                    : Feb 19, 2023
Password expires                    : Mar 21, 2023
Password inactive                    : never
Account expires                        : never
Minimum number of days between password change        : 0
Maximum number of days between password change        : 30
Number of days of warning before password expires    : 7

We see the maximum number of days until a password expires after being updated is 30. To modify this, it’s enough to use the -M (maximum password age) option along with the number of days:

$ chage -M -1 baeldung
$ chage -l baeldung    
Last password change                    : Feb 19, 2023
Password expires                    : never
Password inactive                    : never
Account expires                        : never
Minimum number of days between password change        : 0
Maximum number of days between password change        : -1
Number of days of warning before password expires    : 7

We can choose either a negative value or a huge number representing hundreds of years for example.

By default, chage performs in an interactive version, displaying to the user the current values for all the attributes. The user can enter a new value for each attribute or leave a blank line to keep the existing value.

While chage simply controls how the system treats password expiration, passwd updates the password itself or defines it if it’s not already created. However, it’s also possible to use passwd for the password aging parameters:

$ passwd -x -1 baeldung 
Adjusting aging data for user baeldung.
passwd: Success

With the -x option, we can use -1 to turn off the aging without a password change. If we use 0, the user must update the password on the next login.

3. Setting  System Files /etc/login.defs and /etc/shadow

The configuration file /etc/login.defs contains the default configuration parameters of newly-created user accounts. Many user management utilities, such as useradd, usermod, userdel, and groupadd, rely on it to get the default configuration.

The lines in /etc/login.defs contain two columns: the configuration name and an associated value. It’s enough to change the parameter PASS_MAX_DAYS by any means to turn off the password expiration:

# Password aging controls:
[...]
PASS_MAX_DAYS   999990
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7

Let’s create a new user with the command useradd and set a password for that user:

$ useradd linuxuser                                                                                                                  
$ passwd linuxuser                                                                                                                   
New password:                                                                                                                                       
Retype new password:                                                                                                                                
passwd: password updated successfully

Now, we can check the aging data with chage to see the default values assigned to the new user:

$ chage -l linuxuser                                                                                                                 
Last password change                                    : Feb 22, 2023                                                                              
Password expires                                        : never                                                                                     
Password inactive                                       : never                                                                                     
Account expires                                         : never                                                                                     
Minimum number of days between password change          : 0                                                                                         
Maximum number of days between password change          : 999990                                                                                     
Number of days of warning before password expires       : 7 

On the other hand, the /etc/shadow file stores the hashed passwords of the already-created user accounts. Each line in it begins with the username then the hashed password and then the associated aging parameters, all separated by the : colon character:

For baeldung, the associated line in /etc/shadow looks like this:

$ cat /etc/shadow | grep baeldung
baeldung:$1$V[...]ZF.:19407:0:-1:7:::

Here, we see the maximum age is -1, which refers to a no-expiration date for baeldung‘s password. Any changes in the aging data can be applied directly to the file, but it’s best to use vipw. In any case, it’s mandatory to master the file’s structure: a simple error in /etc/shadow can lead to the loss of system access.

4. Conclusion

In this article, we concentrated on ways to turn off password expiration in Linux. We discussed the related commands, chage and passwd, and system files, /etc/login.defs and /etc/shadow.

To emphasize, password expiration differs from account expiration. In fact, once expired, the user must update the password at the next login. Meanwhile, an expired account prevents the user from connecting to the system even with the right password.