Password Security
Start course

In this course, you'll learn about account security in Linux including pluggable authentication modules (PAM), password security, account access controls, and account types.

Learning Objectives

  • Learn about PAM and how to configure pluggable authentication modules
  • Understand the different types of accounts you'll find on a Linux system and the special precautions you need to take with each account type
  • Learn how to enforce good password security practices on your Linux systems
  • Learn how to make an account's password expire, how to expire an account itself, and how to lock and unlock accounts
  • Understand how to monitor log files and use intrusion detection systems
  • Learn about multi-factor authentication and how it can be implemented in Linux

Intended Audience

This course is intended for anyone who wants to understand how to secure their Linux systems.


To get the most out of this course, you should already have a good working knowledge of Linux. If you want to brush up on your Linux skills, consider taking our Learn Linux in 5 Days learning path first.


Before we go any further I wanna talk about the three different types of accounts that are found on a Linux system. The most powerful account on a Linux system is the root account, also known as the superuser. Root can do anything. If you're I walked into the root account you can see all the files on the system, you can install or remove software. You can change the network configuration. You can create, modify and delete users and everything else you can do on a Linux system. This special account always has a UID or user ID of zero. The account name like root or jason is just for the convenience of us humans. The Linux system doesn't care about account names it looks at the UID of an account. This is an important concept because if I were to set the UID of another account on the system to be zero, then that account would have super user privileges because the Linux system looks at the UID not the account name. All other accounts on the system that do not have a UID of zero are normal accounts. However, for organization and administrative purposes accounts that are used for system services have UIDs lower than 1000. That number is configurable and system accounts used to have UIDs lower than 500 by default. That configuration lives in the /etc/login.defs file. When you create an account with useradd for example, you specify the -r our flag to create an account in the system account range. Otherwise the user account command will create an account in the normal user account range. As far as the Linux system is concerned there is no real difference between an account that has a UID of 999 and one that has a UID of 1000. However, there is a big difference between an account that has a UID of zero and one that does not. But for system accounts and user accounts this UID range simply helps us system administrators quickly determine if an account is likely to be used by a human or if it's intended to be used by a service or an application. Before we get into the specifics of securing each type of account let's look at some concepts and security measures that can be used for all account types. If you don't enforce password policies on your system then users may use weak passwords like one, two, three. Four, five, six or letmein. Allowing weak passwords increases the odds of an attacker breaking into a system using a brute force attack where they systematically try a series of common passwords, dictionary words and frequently used patterns. To protect against weak passwords use of PAM module such as pam_pwquality. It's based on pam_cracklib which was the older method of ensuring password quality. If you're looking at the PAM configuration of an older system you might see pam_cracklib instead of pam_pwquality. You would use this module as part of a directive in a PAM configuration file. To see all the available options and arguments for the module you can run man pam_pwquality. Historically passwords were stored in an encrypted or hashed format in the /etc/passwd file. The first field and /etc password contains the account name. The second field contains the encrypted password, the third field is the UID and so on. The downside to storing passwords and etc password is that the file is required to be readable by all users on the system, as many programs and utilities use it to convert UIDs into usernames. This meant that anyone could view the encrypted passwords of any other user including root. Those encrypted passwords were susceptible to dictionary or brute force attacks. The encrypted passwords could be copied to another system and cracked. This way an attacker wouldn't have to actually attempt authentication on the system and risk being detected by the log file noise that failed login attempts with generate. When shadow passwords are enabled the encrypted password and the etc password file is replaced with an x and the actual encrypted password is stored in etc shadow. The etc shadow file is only readable by the root user thus reducing the likelihood of brute force attacks. If you encounter a system that is not using shadow passwords you can convert it by running the pwconv command as root. If you wanna stop using shadow passwords you can run the pwunconv command. Each line of the etc shadow file contains field separated by colons. The first field is the username, the second is for the encrypted password, the third field is the day since the epoch of the last password change. The epoch for Linux and Unix systems is January 1st, 1970. The next field represents the number of days until another password change is allowed. Next is the number of days before password change is required. The sixth field is how many days before a password expires to one the user of that password expiration. Next is the days before the account becomes inactive. Next is the day since epoch when the password expires. The last field is reserved for a future. Use all these additional fields in the etc shadow file allow us to have greater control over the accounts on the system. Use chage -l followed by an account to display the aging information for the given account. In this example the password was last changed on April 1st, 2016 for the jason account. The password is set to never expire as the account itself is set to never expire. When the value for the number of days between password changes is zero, that allows the user to change their password at any time. The existing password on the account is good for 99,999 days. If this account's password were to expire, the user would be warned seven days in advance. You can also use the chage command to change the expiry configuration for an account. For example, you can use the -M option followed by a number, which represents the maximum number of days during which a password is valid. If you want to force a user to change their password every 30 days, you would run chage -N 30 followed by the account name. To set a date on which a user's account will expire and no longer be accessible, use -E option followed by the number of days since epoch, or a day in year, year, year, year dash month, month. Dash day, day format. To unexpired or unlock an account use negative one as the expiration date. Use the -d option to set the last day the password was changed. At first thought this might not make much sense but you can use this option to force a user to change their password at their next login. The easiest way to do this is to use zero as the date. Just like many other commands these options can be combined. For example, you could force a password reset with a -d option and set the number of days that a password remains valid with a dash -M option. For a complete set of options refer to the man-page for chage. You can set the default account aging options in the /etc/login.defs file. The PASS_MAX_DAYS setting controls the maximum number of days a password may be used. PASS_MIN_DAYS sets the minimum number of days allowed between password changes. PASS_MIN_LEN the minimum acceptable password length. Finally PASS_WARN_AGE controls the number of days a warning is given before a password expires. If you wanna keep users from reusing their previous passwords use the password interface to the pam_pwhistory module. By default it stores the previous 10 passwords used by each account in the etc security0 password file. If you wanna change the default number of passwords to remember, use remember equals followed by the number of passwords to remember as an argument to the pam_pwhistory module.

About the Author
Learning Paths

Jason is the founder of the Linux Training Academy as well as the author of "Linux for Beginners" and "Command Line Kung Fu." He has over 20 years of professional Linux experience, having worked for industry leaders such as Hewlett-Packard, Xerox, UPS, FireEye, and Nothing gives him more satisfaction than knowing he has helped thousands of IT professionals level up their careers through his many books and courses.