Cover V10, I08

Article

aug2001.tar
pam_strong.tar.gz


Locking the Front Door of Password Security

Victor Burns

Systems administrators commonly log network events and scan log files for suspicious activity. We often focus on watching our backs while the perpetrator walks right in the front door. In this article, I will focus on closing this front door. If a password is the barrier between an intruder and your system, then this password must be strong. One of the easiest methods to gain access to systems and data is to crack a list of encrypted passwords. The Internet has a whole suite of programs and large dictionaries with special algorithms that employ obvious checks derived from known human behavior.

The Old Solution

Testing the password during the process of setting it is the best method of password strength checking. Rejecting suspect passwords before they are used saves CPU resources and also reduces time spent by administrators checking for weak passwords. Providing stronger tests during the creation of new passwords is easier and provides better results. Therefore, my group started using the passwd command replacement program called npasswd. When we first started using npasswd, it included many strength tests that frustrated our previous cracking efforts. Not a single password could be cracked after the installation and use of npasswd on our systems. If you want to know more about npasswd, visit: http://www.utexas.edu/cc/unix/software/npasswd/.

The Solaris and HP-UX operating systems, however, now use PAM authentication modules, which have made the npasswd program incompatible in our environment. More than four years ago, we started using the new Network Information Service (NIS+) in order to have one password database for all servers installed in our offices across North America, to allow password aging, and to no longer have to edit /etc/files on every system. After our conversion to NIS+, however, we lost the ability to ensure the quality of user passwords. We also gave up on running password-cracking applications. Without testing for weak passwords, we now have some users creating weak ones.

The New Solution

There is a new solution to the loss of npasswd. The passwd replacement program npasswd has two special features that are notable and important to this discussion. The newest password-checking feature in npasswd is a history database that stores users' encrypted passwords. During the checks to ensure that a user's password is strong, it also makes sure the password has not been recently used by the same account. A recently used password will not be allowed. This is a great test, because some users who had their passwords cracked would change their passwords and then change them right back to the old one. While testing passwords using the old method of trial and error, we found that if a cracked password were not an old password, it would often be the same with minor changes. These and other checks to ensure strong passwords are included in npasswd. The history check was the last test on my wish list, and it has been granted. Ensuring that passwords are strong and uniquely different will slow down would-be intruders.

The passwd replacement program npasswd is still not PAM compatible -- that is, until now. Clyde Hoover and the other contributors designed npasswd in two parts. The user front-end that prompts the user and collects passwords is incompatible with PAM, primarily because other PAM modules and other system libraries already provide these features. There is also a back-end that performs all the checks for strength. This back-end can be used independently of the npasswd front-end.

This modularity of npasswd allowed me to replace the front-end with a PAM module that works with the standard Solaris and HP-UX PAM environment. None of the PAM security functionality is lost, but much is gained. I have tested this new PAM module with HP-UX 11, Solaris 2.6, 7, and 8, Sparc, and x86. I have not tested it on Linux flavors, but I think that with small code enhancements it would work.

The new password strength enhancer works as two distinct parts. A server daemon incorporates the strength module from npasswd. This strength enhancer is redesigned as a system daemon. This daemon processes commands sent via the network. Only one server is needed to run this password strength application daemon. The client portion is a PAM module that communicates to the server daemon using network commands to check a password for strength, store a password in the database for future checks, and process other required actions. The network datagrams communicated between the PAM client and server strength daemon are encrypted and never sent in clear text.

The best part of this solution is that it lets the operating system change the password no matter what the database (files, NIS, NIS+, etc.). It can also change password database fields, like the login shell, but leaves the changing of gcos and shell values to the passwd command and PAM framework.

Npasswd Strength Modules

The password-checking features of npasswd are numerous, but I want to mention one interesting feature I've used. The strength checker is written in modules, and adding more modules is easy. I have added additional checks of my own as a separate module, and we have used this module since we first installed npasswd on our systems. This module rejects passwords based on rules that I coded into it. You can change my module, or you can add checks or rules to the pwck_local.c module.

One interesting aspect of this feature is that some modules you write could be used for special testing purposes or logging information. The use of each module is configurable in the configuration file. The use of the module I added is optional. Just make a change to the configuration file to turn off the use of any given module. Some modules are required because their usage is hard-coded into the checking software of the author. If you disable a required module, the software will complain. The npasswd documents detail this behavior.

The documents of npasswd can be found in the directory /usr/lib/passwd/src/npasswd-2.05/doc after the installation is complete. There are many html and text document files that provide information about npasswd. The history section in the document Main.html will persuade you of the need for strong passwords if you aren't convinced already.

The modules that come with npasswd are:

pwck_crack.c -- Dictionary checker

pwck_history.c -- History of old passwords checker

pwck_lexical.c -- Perform lexical analysis of password

pwck_local.c -- Looks for obvious bad passwords

pwck_passwd.c -- Check against password information

At the expense of denying some good passwords, my module helps eliminate weak passwords that even the above modules miss. I've added:

pwck_vicb.c -- Miscellaneous tests that I like

How Does This Work?

The "New Password Strength PAM Module" provides the interface and communication between the Pluggable Authentication Module (PAM) framework and the strength check daemon running on a network-attached server. The New PAM module sends commands to the strength daemon using the network module. All data and commands are encrypted before using the network, and decrypted upon reception.

The "Server Daemon" listens for commands received via the network. The received network data grams are decrypted and then processed. Strength check and history commands are processed by the code borrowed from the npasswd program. Results are encrypted and returned to the client.

Installation

The installation of the password strength-checking daemon is done by selecting a single Solaris server and installing the files as indicated in the table below. The server daemon and other commands are placed in the /usr/lib/passwd/bin directory. I have written and tested the server daemon on Sparc Solaris only. However, you could make it work on HP-UX. The configuration instructions of npasswd provide details about how to set up search dictionaries. Other directories listed below are self-explanatory. The source code to the recompiled binaries is included. To install a client machine, only the client PAM module is required for proper installation. Use the table for your host type to install properly.

Configuration changes are made to the /usr/lib/passwd/etc/passwd.conf file and are given in detail below. This file is the heart of configuration for this software. Use the listings to install all files and to make changes to system files. Currently, an installation tarball can be used for easy installation of required files and binaries. A tar xvf will place the files in the correct location and set proper security on them when installed by the root account. All listings for this article are available at: http://www.sysadminmag.com/code/.

After the tarred and zipped software file is downloaded, you are ready to proceed with the installation. The installation of the server is completed by making the directory /usr/lib/passwd. Next, unzip and untar the files into the new directory. Run the commands as root to ensure file ownership and rights are correct. To be sure that the files you are untarring are what you expect, use tar tvf to make a dry run. Replace the "PATH" with the real location of the tar file. Here are some examples:

server# mkdir /usr/lib/passwd
server# cd    /usr/lib/passwd
server# gunzip < /PATH/pw_strong.tar.gz | tar tvf -
A listing of the tarball file will be displayed. Now do the real untar command:

server# gunzip < /PATH/pw_strong.tar.gz | tar xf -
When this command has completed, the new directory should contain contents that look like the listing for "Server Daemon Installation Files" provided later in this article.

Each client is installed by copying a precompiled PAM module into the client's /usr/lib/security directory as provided in the table labeled as "Client PAM Module Installation Files". Using the tar command, put the PAM module into place and create a symbolic link. Apparently, the pam.conf file is configured so that the symbolic links are not used. I create the link to follow the convention found in the security directory. Here are the example commands for installing on a Solaris 7 Sparc server. I use the tar command to copy the file and preserve its creation date. There are other methods, but I prefer this one. The example is provided to help understand the location and setup process of shared libraries installed into the PAM environment. After these examples, I provide an example installation script:

server# cd /usr/lib/passwd/pam_client.SunOS.5.7
server# tar cf - pam_strongpw.so.1 | ( cd /usr/lib/security; tar xf - )
server# ln -s pam_strongpw.so.1 /usr/lib/security/pam_strongpw.so
server# ls -ald /usr/lib/security/pam_strongpw.*
lrwxrwxrwx   ....... /usr/lib/security/pam_strongpw.so -> \
  pam_strongpw.so.1
-rwxr-xr-x   ....... /usr/lib/security/pam_strongpw.so.1
The above installation is simplified by using the client installation script. It is located in the bin directory. This installation script takes the guesswork out of the client installation by detecting and installing the correct client version of PAM module. Here is an example of its output during an install:

server# /usr/lib/passwd/bin/client-install
 Client PAM Module installer

 Shared Library [ pam_strongpw.so.1    ]
 Version        [ SunOS.5.6            ]

-rwxr-xr-x   1 root     root       36272 Feb  2 09:17
/usr/lib/security/pam_strongpw.so.1

Reminder: The PAM module can be activated by editing the PAM \
          configuration file.  /etc/pam.conf
server#
The installation is now complete except for the configuration file. The configuration file is explained in more detail within the configuration section below:

Server Daemon Installation Files (Solaris Only)
-----------------------------------------------
/usr/lib/passwd/bin/makedict         (for making dictionaries)
/usr/lib/passwd/bin/packer           (used by makedict)
/usr/lib/passwd/bin/unpacker           ""
/usr/lib/passwd/bin/pwstrongd        (server daemon)
/usr/lib/passwd/bin/pwstrongchk      (Helps test server daemon)
/usr/lib/passwd/bin/client-install   (installs pam module on client)

/usr/lib/passwd/dictionaries/*       (dictionaries [obvious])

/usr/lib/passwd/etc/history.dir      (passwd history data base)
/usr/lib/passwd/etc/history.pag        ""
/usr/lib/passwd/etc/passwd.conf      (configuration file)
/usr/lib/passwd/etc/db-empty         (delete all DB contents)
/usr/lib/passwd/etc/db-print         (print  all DB contents)
/usr/lib/passwd/etc/init.d/pwstrongd (Startup file)

/usr/lib/passwd/lib/lib*             (pre-compiled code libraries)

/usr/lib/passwd/pam_client.*         (pre-compiled client PAM modules)

/usr/lib/passwd/include/             (source code include files)
/usr/lib/passwd/source/              (source code)

Server /etc/syslog.conf
-----------------------
user.info                       /var/log/sysinfo
auth.info                       /var/log/sysinfo

Client Pam Module Installation Files
------------------------------------
/usr/lib/security/pam_strongpw.so.1
/usr/lib/security/pam_strongpw.so -> pam_strongpw.so.1 (link)

Note: This PAM module supports these module options.
use_first_pass, try_first_pass, update_db and  debug. Use the debug more than 
once to increase debugging messages sent to syslog. For more details about PAM 
module options, please see Sun's Answerbook2 for details.

Solaris Setup: /etc/pam.conf
----------------------------
other password requisite /usr/lib/security/pam_strongpw.so.1
other password required  /usr/lib/security/pam_unix.so.1     use_first_pass
other password requisite /usr/lib/security/pam_strongpw.so.1 use_first_pass
update_db

HP-UX   Setup: /etc/pam.conf
----------------------------
passwd password required /usr/lib/security/pam_strongpw.sl.1
passwd password required /usr/lib/security/libpam_unix.1     use_first_pass
passwd password required /usr/lib/security/pam_strongpw.sl.1 use_first_pass
update_db

All clients/server   Setup: /etc/services  OR other service database
--------------------------------------------------------
pwmaint pwmaint udp 5404 Password Strength Checker
Configuration

Once a Solaris Sparc-based server has been chosen and the files have been installed, evaluate the following changes before implementation:

/.../rc3.d/S99pwstrongd -- Optional: Install /usr/lib/passwd/etc/init.d/pwstrongd as a startup file to run the daemon at boot time. Installation is done by copying my startup file as /.../init.d/pwstrongd and using a hard or soft link from the rc3.d directory so that the startup script will be run at system boot.

/etc/services -- Required: All servers and clients must have the database entry listed in the table above. If your site uses NIS or NIS+, the process will be simpler. Your system may require a different port setting.

/etc/syslog.conf -- Optional: For logging details and debugging. See tables above for suggested change.

/usr/lib/passwd/etc/passwd.conf -- Required: This file has several configuration options. Most of which are to configure the npasswd strength checks. See the documentation files provided with npasswd for changing the defaults. There are just a few options in this configuration file that are specific to the PAM module client and server daemon. These options are as follows:

# Directive/option       value
authorize.Passcode       000000-000000-000000-000000
This entry is used as part of an authorization key to grant or deny server requests. Change the zeros to a random value from this character set [0-9A-F]. The string value must be four sets of six hex characters separated by hyphens '-'. The encryption of network data is based on the time of day. Communication between client and server machines is dependent on system clocks being within 90 seconds. I do not know how realistic this window of time is, but I never found any errors or issues during my testing phase. During tests, I used servers all across North America in many time zones. We keep our system clocks on time using NTP and rdate. The service NIS+ uses a window of 15 seconds. From this point of view, 90 seconds looks large enough.

# Directive/option       value
authorize.Server         host.my.domain host     #The Server
There should only be one such line. In my design, you can include both the full DNS name and the host. This can be useful, depending on how your local hostnames are defined and which service is used to query for these names.

# Directive/option       value
authorize.Client         host.my.domain host     #A Client
This entry can be placed in the configuration file as many times as needed to define and authorize all clients. More than one client can be specified per line. In this example, I list only one host with both the full and short names. Granting client access to the server daemon by domain would be a good feature. It is not supported in this release. The ability to check for just a domain would be easy to add to a future release of this software. We use NIS+ for hostname lookups first, so we always get short names. In some cases, our HP servers do lookups using DNS first. The double host name setup in the configuration file covers this issue easily.

The configuration file needs to be read by all clients and the server daemon. The clients use the configuration file to learn who the server host is and the secret key. The server uses the configuration file to learn the names of the clients. Make sure it is configured as the server, and learn what the secret key is. The npasswd strength-check modules also read the settings that configure it from the configuration file. There are two methods for making the configuration file available to all clients. These are listed below. In a future release, the client could be changed to test for a working NIS+ environment and search the local name space for the server name and the secret key code. This change would help clean up this untidy configuration file installation dilemma.

1. Use the server host to NFS export to the clients or use a central NFS server for the export of the configuration file to clients. Mount the exported directory on each client such that the configuration file can be found at: /usr/lib/passwd/etc/passwd.conf.

2. Install a copy of /usr/lib/passwd/etc/passwd.conf on every client (most secure/hardest to administer).

Only three options are needed for configuring the network authorization by host name and secret key. Because the key in this configuration file is in clear text, make sure the key code is kept secret by verifying that the configuration file is owned and readable only by root. The configuration of the npasswd checks is documented in the file Reference.html under the source/npasswd-2.05/doc directory.

Starting and Testing the Server Daemon

To begin, log in to the Solaris server that has the server software loaded and configured. Provide yourself with two windows. The first window will be used to run the daemon in debug mode. Change your directory to /usr/lib/passwd/bin and run the daemon in debug mode. Here is an example:

server# cd /usr/lib/passwd/bin
server# ./pwstrongd --debug 5
Send a command to the server using the client test program pwstrongchk that can send commands to the daemon. This test program uses all the same code as the PAM module except for the PAM API-specific code. It provides a good test of machine and environment compatibility. This program is located in the bin directory with the daemon we started above. Below are some examples you can run to make sure the server is working as it should. Run these commands from the second window. This is the output, if run as root and successful:

server# cd /usr/lib/passwd/bin
server# ./pwstrongchk --ping

UDP Client: (Test Program)

 User Information
 (getspnam)uid[     0 ] = uname[ root ] x
 (getpwnam)uid[     0 ] = uname[ root ] x

 status = PW_STAT_READY         [ 3 ]

 [ (Returned Message) ]
The quick brown fox jumped over the lazy dogs back!  client:( HOST )
server:( HOST )
Here is the output if the daemon is not running correctly or cannot be contacted:

server# ./pwstrongchk --ping

 UDP Client: (Test Program)

 User Information
 (getspnam)uid[     0 ] = uname[ root ] x
 (getpwnam)uid[     0 ] = uname[ root ] x

 status = PW_STAT_NOSERVICE     [ -3 ]

 [ (Returned Message) ]
 Strong: Service not available [recv()]
If the ping test was successful, you are ready to test it using the PAM client. If using NIS+, make sure you are authenticated and properly set up to change the NIS+ name space. You should get this response if it is working correctly. If you do not use NIS+, do not be alarmed by the message. This PAM infrastructure is only asking for the login password and assumes that the passwords may also be used to decrypt your secure RPC password.

If the test was unsuccessful, review the messages displayed in the first window that is running the daemon for reasons that the error occurred. By enabling syslog messages as defined in the installation section of this text, you may find resolution to the problem by looking at the messages in the log file. The log file should be located at /var/log/sysinfo. I have had no trouble setting this up and don't know what special issues might arise.

server# /bin/passwd

INFO: This server is equipped with a password strength enhancer and history manager. 
The server has been detected as "UP" and ready for service.

(Strong)Enter login(NIS+) password:
If you receive a message like the one above, the test was successful and the server is working. Be sure to read the documentation accompanying the npasswd release that provides details about configuring the password strength checks.

Summary

Before I developed this Pluggable Authentication Module, I had no experience with the PAM Application Programming Interface. This PAM module demonstrates that code development can happen with only man pages and header files. I also used Sun Microsystems (http://www.sun.com) Answer Book 2 documents to learn about PAM module programming API. I plan to rewrite the daemon to use threads, rather than forking a child process when possible. I hope the use of this PAM module will help ensure your site's passwords are strong and that your company's trade secrets will be kept safe from willful destruction.

Victor Burns has more than 16 years with Texas Instruments -- ASIC Design, Programmer, Network UNIX Admin. Before that he served four years as USAF Airborne Command Post Electronics Technician. He is the full-time father of six children.