|FOCUS on Sun and Linux: Pluggable Authentication Modules, Part I
For the better part of its existence, Unix, and Unix machines used an authentication mechanism based on the DES algorithm, modified to be utilized as a one way hash. Crypt(3), as it is commonly referred to, has proven satisfactory for most applications.
In recent years, with the growing popularity of the Internet, many have felt a need to switch to alternate, more secure mechanisms for authentication. Several popular schemes for authentication exist; among them Kerberos, SecureID, x9.9, and S/Key/OPIE. With these new schemes came the need to replace many system supplied utilities and daemons, often at a loss of functionality, and possibly with a high degree of trauma (replacing /bin/login being a fairly traumatic experience for many).
Pluggable Authentication Modules, or PAM, represent a standard whereby different authentication mechanisms can be utilized without requiring the replacing of system binaries. Instead, a shared object can be created, and its utilization be dynamically selected based on the contents of an easily configured file. In this manner, different sites can select the authentication mechanism most appropriate for them, without sacrificing functionality or needing to depend on unsupported software.
Solaris and Linux both support PAM, albeit with slight differences. With the popularity of these two operating systems, many PAM modules are freely available. This makes it easy for the integration of new authentication mechanisms into your environment, should you be interested in trying something other than crypt(3).
PAM is a fairly simple standard from administration perspective. Installing a PAM module requires the selection of a module, its placement somewhere on the file system, and the modification of the /etc/pam.conf file on Solaris, or the /etc/pam.d/<appname> in Linux. Any further requirements are specific to the module.
So that we can go step by step, we need to select a module to utilize. In the next part of this article, we'll write a simple PAM module, but for the time being, we're going to take advantage of a feature of PAM. PAM allows for what they call "stacking" of modules. This means it is possible to define multiple modules for a application requiring authentication. For the purpose of demonstration, a simple module is used, which only stubs each of the required functions, printing out any arguments passed, and being as unintrusive as possible (this will all be more easily understood when we write our own module in the next article). The module is available at pam_stub.tar.gz. It works for both Solaris and Linux, and does not require the use of the Linux PAM toolkit under Solaris. Simply untar it, type 'make' in the directory created (pam_stub/) and build for the appropriate operating system.
As configuring PAM is somewhat different between Solaris and Linux, we'll discuss the basic file format, and then look at specifically configuring our test module on Solaris and Linux.
The PAM configuration file has a number of consistent fields between implementations. They each specify the type of action to use a given pam module on, on a given program. These types are as follows:
- auth : Auth is use to specify the module to use when performing authentication
- account : Account is used to specify the module for account management. This would include things such as user limits, account expiration, or access restrictions.
- session : Session performs tasks associated with the specific login session. There are, internally, two functions associated with session, an open and a close session function. These might be used to obtain single sign on credentials, and remove them upon logout.
- password : Password is used for things like password changes.
The disposition of the module and its use is specified via a control flag. This flag is one of the following:
- required : required dictates that this module must return a successful value for the operation to succeed. However, in the case of stacking, the failure will not be reported until all modules have completed.
- requisite : requisite modules must return successfully for authentication to succeed. However, it will return control immediately to the program, rather than continue execution of the PAM stack.
- sufficient : sufficient modules report whether or not the succeed. If previous required modules have succeeded, no more subsequent modules for this type will be executed. If it fails, subsequent modules will be applied.
- optional : modules of the optional type are non-critical. Therefore, whether they succeed or fail has no bearing on the success of a PAM module stack.
The configuration file also list the path to a module, and any options passed to that module. Under Solaris, default modules exist in /usr/lib/security/, and under Linux, in /lib/security/.
- Configuring PAM for Solaris
Configuration information for PAM is stored in the /etc/pam.conf file. The file is broken in to five fields
login auth required /usr/lib/security/pam_unix.so.1 debug (service name) (module type) (control flag) (module path) (options)
The service name field specifies the service utilizing PAM; this is coded in to the program using PAM. Auth, control flag, module path, and options are all as discussed above.
To add the stub module to login, prior to the execution of other modules, for the auth module type, you would add:
login auth optional /export/home/jrauch/pam_stub/pam_stub.so
where the path field is the actual path to the pam_stub.so file. I placed the pam_stub module as the first module in the /etc/pam.conf file. I elected to make it optional, since it has no bearing on the authentication being successful or not. The same module can be used for the account, session and password module types.
NOTE: The module specified must be owned by root. The module will not be used if it is not.
- Configuring PAM for Linux
Configuration information for PAM is stored in the /etc/pam.d/ directory. Each application using PAM will have a separate file in the /etc/pam.d directory, which is coded in to the application using PAM. For login, for instance, the file is named login. The file contains four fields.
auth required /usr/lib/security/pam_unix.so.1 debug (module type) (control flag) (module path) (options)
Each of these fields was discussed above.
To add the stub module to login, you would edit the /etc/pam.d/login file, and add the following entry:
auth optional /lib/security/pam_stub.so
where the path field is the actual path to the pam_stub.so file. I placed the pam_stub module as the first in the /etc/pam.d/login. I elected to make it optional, since it has no bearing on the authentication being successful or not. The same module can be used for the account, session and password module types.
To test the module, simply use the login program. If its configured for each of the module types, you can see each internal function being called. Try configuring the passwd and su programs for the stub module to see what happens under the hood when each is called.
Really using PAM
Toy examples may make for an easy way to explain configuration, but this case is not useful for much besides debugging. There are dozens of modules out there to fill a variety of roles. In the next part to this article, we'll go step by step, and write a module that will run under both Linux and Solaris, to perform x9.9 based authentication. For those of you more interested in actually using PAM, what follows is a list of some of the more interesting and popular PAM modules out there. The first list is of modules included with Solaris, followed by a list of modules included with RedHat Linux. Finally, a list of other interesting modules is presented.
- pam_dial_auth : This module will authenticate a user according to the /etc/dialups and /etc/d_passwd file. This is used, normally, to further authenticate a dialup user for a given shell type.
- pam_krb5 : Kerberos 5 authentication
- pam_ldap : This is a relatively new module that allows the use of ldap instead of something like NIS or NIS+ to do distributed authentication
- pam_rhosts_auth : This module implements rhosts authentication. This is the mechanism usually used with rlogin and rsh
- pam_role : This is part of the new RBAC implementation on Solaris 8. It checks for the authorization to perform a role.
- pam_sample : A simple sample module. Similar to the pam_stub included with this article.
- pam_unix : This module implements the basic Unix authorization scheme.
- pam_access : checks for basic access information, like account expiration, and other system based limits
- pam_console : implements a console permission scheme similar to Solaris' logindevperms. Allows for the permissioning of certain devices and files at login and logout time.
- pam_cracklib : implements rigorous checks for password changes
- pam_deny : deny all access
- pam_filter : filter all IO for a process
- pam_ftp : used for anonymous access to ftp.
- pam_group : sets group permissions based on both /etc/group, as well as additional configurable options based on factors such as login location, etc
- pam_issue : issues the /etc/issue file
- pam_lastlog : lists the information for the users last login
- pam_limits : set resource limits
- pam_listfile : authenticate users based on a files content
- pam_nologin : deny login based on the presence on /etc/nologin
- pam_permit : always allow access
- pam_pwdb : a replacement for the standard Unix authentication scheme that uses the Password Database library
- pam_radius : RADIUS based authentication
- pam_rhosts_auth : standard rlogin/rsh authentication
- pam_securetty : use the /etc/securetty file for authentication
- pam_shells : check for the existence of a user's shell in /etc/shells
- pam_stress : a stress testing PAM module
- pam_tally : keeps track of login attempts, and optionally lock an account after a certain number of failures.
- pam_time : time based authentication to specific services.
- pam_unix : standard Unix authentication
- pam_wheel : does authentication based on a user being in the wheel group
- pam_xauth : X11 xauthority based authentication
Other Cool Modules
- PAM SecureID : Implements the SecureID authentication mechanism
- PAM S/Key : Implements the S/KEY authentication scheme
- PAM RADIUS : Implements RADIUS authentication in a PAM module
- LDAP PAM : Implements LDAP based authentication in PAM
- OPIE PAM : Implements the OPIE authentication scheme in a PAM module
In the next article on PAM, we'll discuss writing a PAM module, and write an example module to cleanly, generically, and correctly implement x9.9 based authentication in PAM. This is the type of authentication used with CryptoCards, SNK cards, and other DES based token cards. We'll implement it with an eye on portability and security.
- http://www.kernel.org/pub/linux/libs/pam/modules.html is a great resource for PAM information in general -- not just for Linux! A good, comprehensive list of modules out there, programming information, and just about all the questions you could come up with when looking for PAM information
- http://docs.sun.com is the ultimate resource for Sun information. If you're wondering how to do something under Solaris, you should definitely consult here. As Sun was the original designer of PAM, its a good place for general PAM information as well.
- The pam and pam.conf man pages on Solaris
To read Pluggable Authentication Modules, Part II, click here.