Security

Controlling passwords with PAM

Password authentication is essential to the security of any network. In this Daily Feature, Jim McIntyre explains how a system administrator can use Pluggable Authentication Modules to enforce a password policy on a Linux system.


Password authentication is essential to the security of any network. If password protection is weak, it is probably just a matter of time before the system is hacked. In this Daily Feature article, I’ll explain how a system administrator can use Pluggable Authentication Modules (PAM) to enforce a password policy on a Linux system. PAM provides the administrator with discretion over password length, the choice of passwords, and password aging. I’ll also discuss ways to use PAM for protection of the user login process.

The /etc/pam.d/passwd file
Table A shows a typical /etc/pam.d.passwd file from a Linux system. By examining each entry in this file in detail, you’ll get a much better understanding of PAM administration.
PAM modules normally use the file extension .so. For this article, I will be referring to these modules without this extension. Therefore, pam_pwdb.so will be referred to as pam_pwdb.
Table A
auth required /lib/security/pam_pwdb.so shadow
account required /lib/security/pam_pwdb.so
password required /lib/security/pam_cracklib.so retry=3
password required /lib/security/pam_pwdb.so use_authtok md5 shadow

The password database library
The /lib/security/pam_pwdb module uses the /lib/lib_pwdb file as a password database library. The purpose of /lib/lib_pwdb is to act as a source of passwords for pam_pwdb.

The pwdb library in turn uses the /etc/pwdb.conf file as its configuration file. A typical /etc/pwdb.conf file is shown below.
user:
    unix+shadow
    nis+unix+shadow
group:
    unix+shadow
    nis+unix+shadow


The /etc/pwdb.conf file has two sections. The first section is preceded by the keyword user:, which pertains to individual users. The second section is preceded by the keyword group:, which pertains (of course) to groups.

After the keyword at the top of each section, there are keywords grouped together by plus (+) signs. The groupings are referred to as lists. The unix+shadow list in the user: section is a list containing the /etc/passwd file and the /etc/shadow file. The nis+unix+shadow list contains the NIS records, in addition to the /etc/passwd and /etc/shadow files. The lists for the group section contain identical lists.

When pam_pwdb is read, it in turn reads the pwdb library. The pwdb library looks for the first match for the user or group name sent to it by pam_pwdb, according to entries in /etc/pwdb.conf. The first list in /etc/pwdb.conf is searched first, and pwdb satisfies itself with the first match. If a user tries to access a service on the system, the /etc/passwd file and the /etc/shadow files are searched first for a match for the username and password. Depending on the results of this search, one of the following actions will occur:
  • If a match is found, the search terminates, and the user is given the appropriate access.
  • If a match is not found, the second list is searched.
  • If no match is found on the second list, the user will receive a prompt stating that access is denied.

The auth module-type
Look at the first line in the /etc/pam.d/passwd file in Table A.
auth  required  /lib/security/pam_pwdb.so shadow

You will notice the auth module-type performs the actual user authentication. An auth module-type is typically used to force a user to provide a password for authentication. The auth module-type may use the following arguments:
  • debug—This enables logging to syslog.
  • use_first_pass—This module uses the password from the previous module. If this module fails, the user is not prompted for another password. It is used with auth and password module-types only.
  • try_first_pass—This is similar to use_first pass, but if the password fails here, the user is prompted for another password.
  • nullok—This allows accounts with no passwords to be used. (This argument, however, should never be used.)
  • ndelay—On failure, this forces the module to return immediately. (Do not use this module. It will allow hackers to have more attempts at guessing passwords on your system.)

Any other argument which may be used with pam_pwdb, but which is not supported by the auth module-type, is ignored. Any argument that is ignored will be logged by syslog as an error, but the performance of the module will not be affected.

Here is a simple example of the auth module-type at work. Any time a user wants to change his/her password on a Linux system, the following command is run:
passwd

The next line prompts you for your current password. Think of what could happen to a network if there were no prompt for the user's current password. Anyone with access to a shell on your system could simply run the passwd command, and change the password for any user on the system. This could result in any user on the system being locked out.

After entering the current password, the user is prompted for the new password by the following line:
Passwd   required  /lib/security/pam_cracklib.so retry 3

The password module-type
Apassword module-type is used to update the user's password. When a user runs the passwd command, pam_cracklib is used to determine if the new password meets the criteria set out by the system administrator. The password may be checked for length, characters used (numerical, special characters, etc), and the ease with which the password may be guessed.

If pam_cracklib accepts the new password, pam_pwd is used to update the password database.

The following arguments may be used with a password module-type.
  • use_first_pass
  • nullock
  • bigcrypt
  • use_authtok
  • try_first_pass
  • md5
  • shadow
  • radius
  • not_set_pass
  • debug
  • unix

Now look at the /etc/pam.d/passwd file in Table 3. Line 4 reads as follows:
password required  /lib/security/pam_pwdb.so use_authtok

Notice the use of the use_authtok argument in this line. Using this argument ensures that the PAM password database, pam_pwdb, will use the new password sent to it from the PAM crack library, pam_cracklib.

Simply stated, pam_cracklib determines if a password is acceptable using the system rules for passwords, and pam_pwdb is used to update the password database.

The account module-type
An account module-type is typically used to confirm that a user has satisfied the requirements for access. An account module may be used to determine if the user is accessing the system from a remote host or if the user is subject to time-of-day login restrictions.

The only argument the account module-type will accept is the debug argument
session module-type

The session module-type is used to log the username and service type to syslog. This logging occurs once at log in, and at log out. The session module-type accepts no arguments.

The pam_cracklib module
The pam_cracklib module is used to check whether a user's password meets the system requirements. There are only two criteria checks:
  • Is the password long enough?
  • Is the password easy to guess?

The pam_cracklib module will only work when it is part of a module stack. This is because it does not have password updating capabilities. This module requires two external components to function:
  • The libcrack library (/usr/lib/libcrack)
  • The cracklib_dict dictionary (usr/lib/cracklib_dict)

Table B lists the options available for use with pam_cracklib.

Table B
Option Function
debug Used to write module information to syslog.
type=string Replaces the string UNIX with "STRING" when a user uses the passwd command.
retry=n Specifies how many times a user may retry to change a password.
difok=n Specifies the number of characters in the new password that must be different from the current password. A new password with at least half the characters different from the current password is accepted.
minlen=n Specifies the minimum password length +1. A minlen value of 9 would actually set a minimum password length of 10 characters.
icredit=n Specifies the number of characters by which the minlen value is reduced by having at least one lowercase character in the new password. If minlen is 7, the minimum password length would be 4 + 1, or 5 characters. Disabled by setting icredit to 0.
Ucredit Specifies the number of characters by which the password length is reduced by having at least one uppercase character in the new password.
dcredit=n Specifies the number of characters by which the password length is reduced by having at least one numeric character in the new password.
ocredit=n Specifies the number of characters by which the password length is reduced by having at least one numeric character in the new password.

Checking password strength
Password strength refers to the ability of a cracker to guess a password. The stronger the password, the harder it is to guess. The password strength is tested by pam_cracklib, which performs three checks:
  • The new password is checked to see if it is in the cracklib_dict dictionary. If the password is in cracklib_lib, the user is issued a warning, but is not forced to change the password.
  • The new password is checked to confirm that it is not the reverse of the old password.
  • The new password is checked to confirm that it is not the old password with the case of the characters reversed.

Stacking pam_cracklib and pam_pwdb with password module-types
Now, let’s look at how pam_cracklib and pam_pwdb interact with each other in the /etc/pam.d/passwd file.

Table C shows a typical /etc/pam.d/passwd file with stacked entries.

Table C
auth required /lib/security/pam_pwdb.so shadow
account required /lib/security/pam_pwdb.so
password required /lib/security/pam_cracklib.so retry=3
password required /lib/security/pam_pwdb.so use_authtok md5 shadow

The following interactions take place when the user Joe wants to change his password:
  1. When Joe executes the passwd command, PAM is invoked.
  2. PAM then reads the /etc/pam.d/passwd file, and executes each module sequence.
  3. The pam_pwdb is first run as an auth module, and the Joe is prompted for his current password.
  4. The pam_pwdb is then run as an account module, and the authentication request is checked to ensure that the access rules for this user are satisfied.
  5. If the access rules for Joe are satisfied, the third invokes pam_cracklib, and Joe is prompted for his new password.
  6. After the new password has been entered, pam_cracklib prompts the user to repeat it for verification.
  7. When the new password has been reentered, pam_cracklib checks the password to ensure it complies with the password rules for this system.
  8. If the new password is acceptable, the fourth entry in /etc/pam.d/passwd calls pam_pwdb.
  9. The authtok argument in the fourth entry ensures that pam_pwdb will accept the new password and will send the new information to the pwdb library, so that the password database may be updated.
  10. Once the password database library is updated, Joe's new password is in effect.

PAM and login
Whenever a user attempts to login to a Linux system, the /bin/login program is run. Whenever /bin/login is run, PAM reads the /etc/pam.d/login configuration file. Now that we've discussed PAM in some detail, we are able to take a close look at the actions each module in the /etc/pam.d/login file performs.

Table D shows a typical /etc/pam.d/login file.

Table D
#%PAM-1.0    
auth required /lib/security/pam_securetty.so
auth required /lib/security/pam_pwdb.so shadow nullok
auth required /lib/security/pam_nologin.so
account required /lib/security/pam_pwdb.so
password required /lib/security/pam_cracklib.so
password required /lib/security/pam_pwdb.so nullok use_authtok md5 shadow
session required /lib/security/pam_pwdb.so
session optional /lib/security/pam_console.so

The first three lines of this file, (excluding the #%PAM-1.0 line), represents a stack of three auth module-types. The first module is the pam_securetty module. This module:
  • May be used only as an auth module-type.
  • Accepts no arguments.
  • Checks the login device being used against the list of allowed login devices listed in /etc/securetty if the user is attempting to login as root.
  • Will fail if the login device is not listed in /etc/securetty. (If this module fails, the login attempt will fail.)
  • Uses the required control-flag. (If this module fails, other modules in the stack will still execute, but access will not be denied until all three modules in the stack have failed.)

The second module used is pam_pwdb. The purpose of pam_pwdb is to authenticate the user. The third module used is pam_nologin. This module is an auth only module-type. It will not accept arguments. It’s used to check for the presence of the /etc/nologin file. If the /etc/nologin file exists, no users, except root, are allowed to log into the system. The /etc/nologin is used normally when a system is down for administrative reasons. If this is the case, a message may be placed in the nologin file, which will be displayed whenever a non-root login is attempted. If the file /etc/nologin does not exist, the modules listed in /etc/pam.d/login are run.

The next line is used to invoke pam_pwdb as an account module-type. This module is used to check the user's account. If the user is using an invalid password, or if the user's password has expired, this module detects the problem, and the next two lines in /etc/pam.d/login file will be called. The procedure described in the PAM and passwords section will then take place. The last line in the /etc/pam.d/login file uses the pam_pwdb module as a session module-type. This module is used to logging connection information to syslog.

Any application on your system that requires a password will use some or all of the modules listed in this /etc/pam.d/login file. These applications include:
  • su
  • ftp
  • chfn
  • ppp
  • rsh

A change to the configuration file for any application is usually reflected in the configuration files for all applications requiring passwords. By providing this continuity in PAM configuration files, the system administrator reduces the risk of security problems arising from conflicting PAM configuration files.

Summary
In this article, I’ve explained ways to use PAM to administer and protect the system password policy and the user login process. I discussed the module-types and the configuration necessary to enforce security policies, and how to use multiple modules in a stack. I also explained ways of using PAM to administer the user login process.

Jim McIntyre, retired from the Canadian navy, has a total of 12 years of IT training and experience, as well as extensive technical support experience. Jim completed the Novell CNE program, the Adult Education program at Saint Francis Xavier University, and the Webmaster Program at Dalhousie University. His hobbies include golf and hiking.

The authors and editors have taken care in preparation of the content contained herein but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any damages. Always have a verified backup before making any changes.

Editor's Picks