Linux Authentication Systems

Contents

In this document I will discuss the various user authentication systems, and how they relate to system security.

How User Information is Stored on Your System

/etc/passwd

On almost all linux distributions (and commercial *nixes as well), user information is stored in /etc/passwd, a text file which contains the user's login, their encrypted password, a unique numerical user id (called the uid), a numerical group id (called the gid), an optional comment field (usually containing such items as their real name, phone number, etc.), their home directory, and their preferred shell. A typical entry in /etc/passwd looks something like this:


bozo:x:1000:1000:Bozo the Clown:/home/bozo:/bin/ bash

What follows is a discussion of various authentication and authorization methods. This isn't as simple as simply choosing one. Several can interact with each other, for example:

And different authentication schemes can be used for different applications on the same machine. You could, for example, store username and passwords for ftp in LDAP, authenticate IMAP clients using SASL from username password pairs stored in sasldb, and authenticate ssh clients from the standard /etc/passwd and /etc/shadow files and/or stored public keys. While this presents some complexity, like many things in Linux it also provides flexibility.

PAM Pluggable Authentication Modules

Traditionally user authentication is programmed directly into applications. With this method each developer has to write his own authentication functions. Using PAM (Pluggable Authentication Modules), applications can be developed with a PAM interface, and the system administrator can choose any number of PAM modules to do authentication and other tasks. This seperates user authentication from the application, and allows ``plugging in'' of different authentication methods, without the need to rewrite the application.

PAM is built into many Linux distributions, including Caldera 1.3, 2.2 and later; Debian 2.2 and later; Turbo Linux 3.6 and later; Red Hat 5.0 and later; and SuSE 6.2 (partial support). FreeBSD supports PAM from version 3.1.

PAM (Pluggable Authentication Modules) is a suite of shared libraries that enable the local system administrator to choose how applications authenticate users.

The function of the configuration file(s) is to provide a mapping from the application's service name to a selection of modules that provide authentication services to the raw application. When a pam aware application with a file in /etc/pam.d starts, the PAM library loads the configuration for the specified service and constructs four module chains (one for each facility.) If the configuration does not specify any modules for one or more facilities, the configuration for the other service is used instead for these facilities.

Linux as a server, can provide several different services (e.g., web, ftp with areas restricted by password control). Through the use of modules, PAM can enable a program to search through several different password databases, even if that program is not explicitly coded for that particular database.

Here are some examples of the possibilities that this enables.

PAM configuration files, located in /etc/pam.d and named for the service which they control have three fields, with optional fourth and greater fields. The first field in the configuration file is the module-type indicatiing which of four PAM management services the correspoding module will provide to the application. PAM deals with four separate types of management services. The type token tells PAM what type of authentication is to be used for this module. Modules of the same type can be "stacked", requiring a user to meet multiple requirements to be authenticated. The four types of management services are: authentication management; account management; session management; and password management.
auth

Determines whether the user is who they claim to be, usually by a password, but perhaps by a more sophistcated means, such as biometrics.

account

Determines whether the user is allowed to access the service. This is different from establishing whether the user is who they say they are. Account management deals with enforcing the expiration of passwords and preventing logins during system time.

password

Provides a mechanism for the user to change their authentication. Again, this usually their password.

session

Things that should be done before and/or after the user is authenticed. This might included things such as mounting/unmounting the user home directory, logging their login/logout, and restricting/unrestricting the services available to the user.

Control:

PAM modules can be stacked - there can be any number of modules of the same module type for a single application. The application is not told of the individual success or failure of any module, only of the success or failure of the stack. The control flags determine how each module affects the success or failure of the stack. Modules in the stack are executed in the order they are listed in the configuration file.

The second field in the configuration file is the control token, which tells PAM what should be done in if authentication by this module fails. PAM recognizes four control types: required, requisite, sufficient, and optional.

requisite

The module must succeed for the stack of this module type to succeed. Failure to authenticate via this module results in immediate denial of authentication.

required

The module must succeed for the stack of this module type to succeed. Failure also results in denial of authentication, although PAM will still call all the other modules listed for this service before denying authentication.

sufficient

Success of this module is sufficient for the stack of this module type to succeed. If authentication by this module is successful, PAM will grant authentication.

optional

Not critical to the success or failure of the stack. If at least one non-optional module succeeds or fails, the result of this module is ignored when calculating the success or failure of the stack. Whether this module succeeds or fails is only significant if it is the only module of its type for this service.

Module Path:

The module-path tells PAM which module to use and (optionally) where to find it. Most configurations only contain the module's name. Since Linux-PAM-0.56 was released there is support for a default authentication-module directory, and a full path is no longer required, only the name of the module. PAM looks for the modules in the default PAM module directory, normally /usr/lib/security. However, if your linux distribution conforms to the Linux Filesystem standard, PAM modules can be found in /lib/security.

Module Arguments:

Any further fields contain any arguments to the module. Each module has its own arguments. For example, in our login configuration, the "nulok" ("null ok", argument being passed to pam_unix.so module, indicating the a blank ("null") password is acceptable ("ok").

The following are a list of module options that are likely to be recognize by all modules:

Example configuration file entries

Let's look at some examples of pam configuration files. The first example is for the other or default service. If there is not a specific pam configuration file in /etc/pam.d for a service, this is the configuration file that can be used to ease the integration of new services by providing a default selection of modules appropriate to the local security policy. Or, it can be used to deny access to any application that does not have a specific /etc/pam.d entry. The fields in the configuration file are module-type, control-flag and module-filename. Any other fields are optional arguments that are specific to the individual modules.

Default policy

If a system is to be considered secure, it had better have a reasonably secure other entry. The following is a paranoid setting (which is not a bad place to start!):

#
# default configuration: /etc/pam.d/other
#
auth required pam_deny.so
account required pam_deny.so
password required pam_deny.so
session required pam_deny.so

While fundamentally a secure default, this won't give the administrator any feedback about a misconfigured system. For example, such a system is vulnerable to locking everyone out should the configuration file for a specific service be badly written.

The module pam_deny is not very sophisticated, it logs no information when it is invoked. Unless the users of a system contact the administrator when failing to execute a service application, the administrator may go for a long not knowing that his system is mis-configured.

By changing the configuration to the example below would provide a suitable warning to the administrator. Notice the the stacking of pam_warn.so and pam_deny.so.

#
# default configuration: /etc/pam.d/other 
#
auth required pam_deny.so 
auth required pam_warn.so 
account required pam_deny.so
account required pam_warn.so 
password required pam_deny.so 

password required pam_warn.so 
session required pam_deny.so
session required pam_warn.so

With this configuration, whenever an unknown service attempts to access any of the four configuration types, PAM denies authentication (via the pam_deny.so module) and then logs a syslog warning (via the pam_warn.so module). Short of a bug in PAM, this configuration is brutally secure. The only problem with that brutality is it may cause problems if your accidentally delete the configuration of another service. If your /etc/pam.d/login was mistakenly deleted, no one would be able to login!

Here's a little gentler configuration

#
# default configuration: /etc/pam.d/other 
# 
auth requisite pam_securetty.so
auth required pam_unix.so 
auth required pam_warn.so 
account required pam_unix.so
account required pam_warn.so 
password required pam_unix.so 
password required pam_warn.so 
session required pam_unix.so
session required pam_warn.so.

The first module (pam_securetty.so) checks to see if the user is root and prevents root from logging in from an insecure terminal. The value requisite for control-flag is used to force immediate authentication failure if the securetty module fails. If this occurs, no more of the auth modules are executed. This has the benefit of preventing root from mistakenly typing a password over an insecure terminal line. This configuration will allow an unknown service to authenticate (via the pam_unix.so module), although it will not allow it to change the user's password. Although it allows authentication by unknown services, it logs a syslog warning whenever such a service attempts authentication.

A word on null passwords

On many linux systems there are a number of accounts used to assign privileges to system services like ftp, apache, news, and databases. These accounts allow services to run as unprivileged users, providing a level of security, because an intruder that compromises the service only has the limited privileges available to that service, rather than the privileges of root. However, allowing these accounts login privileges is a security risk, as they usually have blank (null) passwords. The nullok options-argument allows passwordless accounts. It is recommended you remove this argument from any modules of auth type for services that allow login. This is usually the login service, may also include services like rlogin and ssh. So the following line in /etc/pam.d/login:

auth required pam_unix.so nullok

Should be changed to:

auth required pam_unix.so 

Disable unused services

If you find you have pam configuration files in /etc/pam.d/ that you're not using, you may want to rename or remove them to prevent their unauthorized use. For example, if you're not using graphical login (Red Hat runlevel 5) then you might want to rename /etc/pam.d/xdm to /etc/pam.d/noxdm. Not finding the file named after the service requesting authentication, PAM will fall back to the /etc/pam.d/other. If you later want to enable the service, rename to it's original name and everything will work as it was intended.

Basic PAM modules

pam_unix.so

This module provides traditional Unix authentication, password management, and user account setup. It uses standard system calls to retrieve and set password and account information, and relies on /etc/shadow and /etc/passwd.

pam_access.so
This module intercepts the user's name and password. If the name is ftp or anonymous, the user's password is broken up at the @ delimiter into a PAM_RUSER and a PAM_RHOST part; these pam-items being set accordingly. The username is set to ftp. In this case the module succeeds. Alternatively, the module sets the PAM_AUTHTOK item with the entered password and fails.

The behavior of the module can be modified with the following flags:

pam_chroot.so
This module is intended to provide a transparent wrapper around the average user, one that puts them in a fake file-system (eg, their / is really /some/where/else).

Useful if you have several classes of users, and are slightly paranoid about security. Can be used to limit who else users can see on the system, and to limit the selection of programs they can run.

pam_console.so
This module 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.so
This module can be plugged into the password stack of a given application to provide some plug-in strength-checking for passwords.

This module works in the following manner:
it first calls the Cracklib routine to check the strength of the password; if crack likes the password, the module does an additional set of strength checks. These checks are:

This module with no arguments will work well for standard unix password encryption. With md5 encryption, passwords can be longer than 8 characters and the default settings for this module can make it hard for the user to choose a satisfactory new password. Notably, the requirement that the new password contain no more than 1/2 of the characters in the old password becomes a non-trivial constraint. For example, an old password of the form the quick brown fox jumped over the lazy dogs would be difficult to change... In addition, the default action is to allow passwords as small as 5 characters in length. For a md5 systems it can be a good idea to increase the required minimum size of a password. One can then allow more credit for different kinds of characters but accept that the new password may share most of these characters with the old password.

pam_deny.so

This module can be used to deny access. It always indicates a failure to the application through the PAM framework. As is commented in the overview section above, this module might be suitable for using for default (the OTHER) entries.

pam_env.so

This module allows you to (un)set arbitrary environment variables using fixed strings, the value of previously set environment variables and/or PAM_ITEMs.

All is controlled via a configuration file (by default, /etc/security/pam_env.conf but can be overriden with conffile argument). Each line starts with the variable name, there are then two possible options for each variable DEFAULT and OVERRIDE. DEFAULT allows an administrator to set the value of the variable to some default value, if none is supplied then the empty string is assumed. The OVERRIDE option tells pam_env.so that it should enter in its value (overriding the default value) if there is one to use. OVERRIDE is not used, "" is assumed and no override will be done.

VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]
(Possibly non-existent) environment variables may be used in values using the ${string} syntax and (possibly non-existent) PAM_ITEMs may be used in values using the @{string} syntax. Both the $ and @ characters can be backslash-escaped to be used as literal values (as in \$. Double quotes may be used in values (but not environment variable names) when white space is needed the full value must be delimited by the quotes and embedded or escaped quotes are not supported.

This module can also parse a file with simple KEY=VAL pairs on separate lines (/etc/environment by default). You can change the default file to parse, with the envfile flag and turn it on or off by setting the readenv flag to 1 or 0 respectively.

The behavior of this module can be modified with one of the following flags:

pam_filter.so

Each component of the module has the potential to invoke the desired filter. The filter is always execv(2)d with the privilege of the calling application and not that of the user. For this reason it cannot usually be killed by the user without closing their session.

The behavior of the module can be significantly altered by the arguments passed to it in the Linux-PAM configuration file:

In the case of the authentication and session components there are actually two separate functions. For the case of authentication, these functions are _authenticate and _setcred - here run1 means run the filter from the _authenticate function and run2 means run the filter from _setcred. In the case of the session modules, run1 implies that the filter is invoked at the _open_session stage, and run2 for _close_session.

For the case of the account component. Either run1 or run2 may be used.

For the case of the password component, run1 is used to indicate that the filter is run on the first occasion _chauthtok is run (the PAM_PRELIM_CHECK phase) and run2 is used to indicate that the filter is run on the second occasion (the PAM_UPDATE_AUTHTOK phase).

pam_ftp.so
This module intercepts the user's name and password. If the name is ftp or anonymous, the user's password is broken up at the @ delimiter into a PAM_RUSER and a PAM_RHOST part; these pam-items being set accordingly. The username (PAM_USER) is set to ftp. In this case the module succeeds. Alternatively, the module sets the PAM_AUTHTOK item with the entered password and fails.

The behavior of the module can be modified with the following flags:

pam_group.so
This module does not authenticate the user, but instead it grants group memberships (in the credential setting phase of the authentication module) to the user. Such memberships are based on the service they are applying for. The group memberships are listed in text form in the /etc/security/group.conf file.

pam_issue.so
This module allows you to prepend an issue file to the username prompt. It also by default parses escape codes in the issue file similar to some common getty's (using \x format).

Recognized escapes:

The behavior of this module can be modified with one of the following flags:

pam_krb5.so
pam_krb5.so is designed to allow smooth integration of Kerberos 5 password- checking with applications built using PAM. It also supports session-specific ticket files (which are neater), and Kerberos IV ticket file grabbing. Its main use is as an authentication module, but it also supplies the same functions as a session-management module to better support poorly-written applications, and a couple of other workarounds as well. It also supports account management and password-changing.

When a user logs in, the module's authentication function performs a simple password check and, if possible, obtains Kerberos 5 and Kerberos IV credentials, caching them for later use. When the application requests initialization of credentials (or opens a session), the usual ticket files are created. When the application subsequently requests deletion of credentials or closing of the session, the module deletes the ticket files.

pam_lastlog.so
This module can be used to provide a Last login on ... message. when the user logs into the system from what ever application uses the PAM libraries. In addition, the module maintains the /var/log/lastlog file.

The behavior of this module can be modified with one of the following flags:

pam_ldap.so
This is a relatively new module that allows the use of ldap instead of something like NIS or NIS+ to do distributed authentication.

pam_limits.so
Through the contents of the configuration file, /etc/security/limits.conf, resource limits are placed on users' sessions. Users of uid=0 are not affected by this restriction.

The behavior of this module can be modified with the following arguments:

pam_listfile
The module gets the item of the type specified - user specifies the username, PAM_USER; tty specifies the name of the terminal over which the request has been made, PAM_TTY; rhost specifies the name of the remote host (if any) from which the request was made, PAM_RHOST; and ruser specifies the name of the remote user (if available) who made the request, PAM_RUSER - and looks for an instance of that item in the file filename. filename contains one line per item listed. If the item is found, then if sense=allow, PAM_SUCCESS is returned, causing the authorization request to succeed; else if sense=deny, PAM_AUTH_ERR is returned, causing the authorization request to fail.

If an error is encountered (for instance, if filename does not exist, or a poorly-constructed argument is encountered), then if onerr=succeed, PAM_SUCCESS is returned, otherwise if onerr=fail, PAM_AUTH_ERR or PAM_SERVICE_ERR (as appropriate) will be returned.

An additional argument, apply=, can be used to restrict the application of the above to a specific user (apply=username) or a given group (apply=@groupname). This added restriction is only meaningful when used with the tty, rhost and shell items.

Besides this last one, all arguments should be specified; do not count on any default behavior, as it is subject to change.

No credentials are awarded by this module.

Classic ftpusers authentication can be implemented with this entry in /etc/pam.d/ftp

auth required pam_listfile.so onerr=succeed item=user sense-deny
file=/etc/ftpusers

Note, users listed in /etc/ftpusers file are (counterintuitively) not allowed access to the ftp service.

pam_mail.so
This module provides the you have new mail service to the user. It can be plugged into any application that has credential hooks. It gives a single message indicating the newness of any mail it finds in the user's mail folder. This module also sets the Linux-PAM environment variable, MAIL, to the user's mail directory.

The behavior of this module can be modified with one of the following flags:

pam_mkhomedir.so
This module is useful for distributed systems where the user account is managed in a central database (such as NIS, NIS+, or LDAP) and accessed through multiple systems. It frees the administrator from having to create a default home directory on each of the systems by creating it upon the first successfully authenticated login of that user. The skeleton directory (usually /etc/skel/) is used to copy default files and also set's a umask for the creation.

The behavior of this module can be modified with one of the following flags:

pam_motd.so
This module allows you to have arbitrary motd's (message of the day) output after a successful login. By default this file is /etc/motd, but is configurable to any file.

The behavior of this module can be modified with one of the following flags:

pam_nologin.so

Provides standard Unix nologin authentication. If the file /etc/nologin exists, only root is allowed to log in; other users are turned away with an error message (and the module returns PAM_AUTH_ERR or PAM_USER_UNKNOWN). All users (root or otherwise) are shown the contents of /etc/nologin.

If the file /etc/nologin does not exist, this module defaults to returning PAM_IGNORE, but the successok module argument causes it to return PAM_SUCCESS in this case.

The administrator can override the default nologin file with the file=pathname module argument.

pam_permit.so
No matter what management group, the action of this module is to simply return PAM_SUCCESS - operation successful.

In the case of authentication, the user's name will be acquired. Many applications become confused if this name is unknown.

pam_pwdb.so
This module is a pluggable replacement for the pam_unix_.. modules. It uses the generic interface of the Password Database library libpwdb.

The debug argument makes the accounting functions of this module syslog(3) more information on its actions. (Remaining arguments supported by the other functions of this module are silently ignored, but others are logged as errors through syslog(3)).

Based on the following pwdb_elements: expire; last_change; max_change; defer_change; warn_change, this module performs the task of establishing the status of the user's account and password. In the case of the latter, it may offer advice to the user on changing their password or, through the PAM_AUTHTOKEN_REQD return, delay giving service to the user until they have established a new password. The entries listed above are documented in the Password Database Library Guide (see pointer above). Should the user's record not contain one or more of these entries, the corresponding shadow check is not performed.

pam_rhosts_auth.so
his module performs the standard network authentication for services, as used by traditional implementations of rlogin and rsh etc.

The authentication mechanism of this module is based on the contents of two files; /etc/hosts.equiv (or _PATH_HEQUIV in #include ) and /.rhosts. Firstly, hosts listed in the former file are treated as equivalent to the localhost. Secondly, entries in the user's own copy of the latter file is used to map remote-host remote-user pairs to that user's account on the current host. Access is granted to the user if their host is present in /etc/hosts.equiv and their remote account is identical to their local one, or if their remote account has an entry in their personal configuration file.

Some restrictions are applied to the attributes of the user's personal configuration file: it must be a regular file (as defined by S_ISREG(x) of POSIX.1); it must be owned by the superuser or the user; it must not be writable by any user besides its owner.

The module authenticates a remote user (internally specified by the item PAM_RUSER) connecting from the remote host (internally specified by the item PAM_RHOST). Accordingly, for applications to be compatible this authentication module they must set these items prior to calling pam_authenticate(). The module is not capable of independently probing the network connection for such information.

In the case of root-access, the /etc/host.equiv file is ignored unless the hosts_equiv_rootok option should be used. Instead, the superuser must have a correctly configured personal configuration file.

The behavior of the module is modified by flags:

pam_rootok.so
This module is for use in situations where the superuser wishes to gain access to a service without having to enter a password.

This module authenticates the user if their uid is 0. Applications that are created setuid-root generally retain the uid of the user but run with the authority of an enhanced effective-uid. It is the real uid that is checked.

pam_securetty.so
Provides standard Unix securetty checking, which causes authentication for root to fail unless PAM_TTY is set to a string listed in the /etc/securetty file. For all other users, it succeeds.

For canonical usage, should be listed as a required authentication method before any sufficient authentication methods.

pam_shells.so
This module checks for the existence of a user's shell in /etc/shells

pam_stack.so

from the man page

In a nutshell, pam_stack lets you "call", from inside of the stack for a particular service, the stack defined for any another service. The intention is to allow multiple services to "include" a system-wide setup, so that when that setup needs to be changed, it need only be changed in one place.

pam_stress.so
A stress testing PAM module

pam_tally.so
This module maintains a count of attempted accesses, can reset count on success, can deny access if too many attempts fail.

pam_tally comes in two parts: pam_tally.so and pam_tally. The former is the PAM module and the latter, a stand-alone program. pam_tally is an (optional) application which can be used to interrogate and manipulate the counter file. It can display users' counts, set individual counts, or clear all counts. Setting artificially high counts may be useful for blocking users without changing their passwords. For example, one might find it useful to clear all counts every midnight from a cron job.

The counts file is organized as a binary-word array, indexed by uid. You can probably make sense of it with od, if you don't want to use the supplied application.

Note, there are some outstanding issues with this module: pam_tally is very dependent on getpw*() - a database of usernames would be much more flexible; the `keep a count of current logins' bit has been #ifdef'd out and you can only reset the counter on successful authentication, for now.

The authentication component of this module increments the attempted login counter.

pam_time.so
Running a well regulated system occasionally involves restricting access to certain services in a selective manner. This module offers some time control for access to services offered by a system. Its actions are determined with a configuration file. This module can be configured to deny access to (individual) users based on their name, the time of day, the day of week, the service they are applying for and their terminal from which they are making their request.

This module bases its actions on the rules listed in its configuration file: /etc/security/time.conf. Each rule has the following form,

services;ttys;users;times

In words, each rule occupies a line, terminated with a newline or the beginning of a comment; a `#'. It contains four fields separated with semicolons, `;'. The fields are as follows:

By a logic list we mean a sequence of tokens (associated with the appropriate PAM_ item), containing no more than one wildcard character; `*', and optionally prefixed with a negation operator; `!'. Such a sequence is concatenated with one of two logical operators: & (logical AND) and | (logical OR). Two examples are: !morgan&!root, indicating that this rule does not apply to the user morgan nor to root; and tty*&!ttyp*, which indicates that the rule applies only to console terminals but not pseudoterminals. For convenience and readability a rule can be extended beyond a single line with a `\newline'.

pam_unix.so
This is the standard Unix authentication module. It uses standard calls from the system's libraries to retrieve and set account information as well as authentication. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled.

The debug argument makes the accounting functions of this module syslog(3) more information on its actions. (Remaining arguments supported by the other functions of this module are silently ignored, but others are logged as errors through syslog(3)). The audit argument causes even more logging.

Based on the following shadow elements: expire; last_change; max_change; min_change; warn_change, this module performs the task of establishing the status of the user's account and password. In the case of the latter, it may offer advice to the user on changing their password or, through the PAM_AUTHTOKEN_REQD return, delay giving service to the user until they have established a new password. The entries listed above are documented in the GNU Libc info documents. Should the user's record not contain one or more of these entries, the corresponding shadow check is not performed.

pam_userdb.so
Look up users in a .db database and verify their password against what is contained in that database.

This module is used to verify a username/password pair against values stored in a Berkeley DB database. The database is indexed by the username, and the data fields corresponding to the username keys are the passwords, in unencrypted form, so caution must be exercised over the access rights to the DB database itself..

The module will read the password from the user using the conversation mechanism. If you are using this module on top of another authentication module (like pam_pwdb;) then you should tell that module to read the entered password from the PAM_AUTHTOK field, which is set by this module.

The action of the module may be modified from this default by one or more of the following flags in the /etc/pam.d/ file.

pam_warn.so
This module is principally for logging information about a proposed authentication or application to update a password.

Log the service, terminal, user, remote user and remote host to syslog(3). The items are not probed for, but instead obtained from the standard pam-items.

pam_wheel.so
This module is used to enforce the so-called wheel group. By default, it permits root access to the system if the applicant user is a member of the wheel group (better described as the group with group-id 0).

The action of the module may be modified from this default by one or more of the following flags in the /etc/pam.conf file.

To allow only members of the wheel group to become root through su, use the following line in /etc/pam.d/su:
auth required /lib/security/pam_wheel.so use_uid

pam_warn.so
This module logs information about an authentication or password change attempt to syslog.

This module has no arguments, and only auth and password components. Log the service, terminal, user, remote user and remote host to syslog(3). The items are not probed for, but instead obtained from the standard pam-items.

pam_xauth.so
This module is designed to forward xauth keys (sometimes referred to as "cookies") between users.

Without pam_xauth, when xauth is enabled and a user uses the su command to assume superuser privileges, that user is not able to run X commands as root without somehow giving root access to the xauth key used for the current X session. pam_xauth solves the problem by forwarding the key from the user running su (the source user) to the user whose identity the source user is assuming (the target user) when the session is created, and destroying the key when the session is torn down.

LDAP

While ldap is not an authentication mechanism, anymore than the file /etc/passwd is, you can store authentication information in ldap, similar to the way it is stored in /etc/passwd and /etc/shadow. So I felt it was important to include an overview of ldap as part of this discussion.

What is a directory service?

A directory is a specialized database optimized for reading, browsing and searching. Directories tend to contain descriptive, attribute-based information and support sophisticated filtering capabilities. Directories generally do not support complicated transaction or roll-back schemes found in database management systems designed for handling high-volume complex updates. Directory updates are typically simple all-or-nothing changes, if they are allowed at all. Directories are tuned to give quick response to high-volume lookup or search operations. They may have the ability to replicate information widely in order to increase availability and reliability, while reducing response time. When directory information is replicated, temporary inconsistencies between the replicas may be okay, as long as they get in sync eventually.

What is LDAP?

LDAP stands for Lightweight Directory Access Protocol. As the name suggests, it is a lightweight protocol for accessing directory services, specifically X.500-based directory services. LDAP runs over TCP/IP or other connection oriented transfer services. The nitty-gritty details of LDAP are defined in RFC2251 "The Lightweight Directory Access Protocol (v3)." This section gives an overview of LDAP from a user's perspective.

What kind of information can be stored in the directory?

The LDAP information model is based on entries. An entry is a collection of attributes that has a globally-unique Distinguished Name (DN). The DN is used to refer to the entry unambiguously. Each of the entry's attributes has a type and one or more values. The types are typically mnemonic strings, like cn for common name, or mail for email address. The syntax of values depend on the attribute type. For example, a cn attribute might contain the value Babs Jensen. A mail attribute might contain the value babs@example.com. A jpegPhoto attribute would contain a photograph in the JPEG (binary) format.

How is the information arranged?

In LDAP, directory entries are arranged in a hierarchical tree-like structure. Traditionally, this structure reflected the geographic and/or organizational boundaries. Entries representing countries appear at the top of the tree. Below them are entries representing states and national organizations. Below them might be entries representing organizational units, people, printers, documents, or just about anything else you can think of.

The tree may also be arranged based upon Internet domain names. This naming approach is becoming increasing popular as it allows for directory services to be located using the DNS.

In addition, LDAP allows you to control which attributes are required and allowed in an entry through the use of a special attribute called objectClass. The values of the objectClass attribute determine the schema rules the entry must obey.

How is the information referenced?

An entry is referenced by its distinguished name, which is constructed by taking the name of the entry itself (called the Relative Distinguished Name or RDN) and concatenating the names of its ancestor entries. The full DN format is described in RFC2253, "Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names."

How is the information accessed?

LDAP defines operations for interrogating and updating the directory. Operations are provided for adding and deleting an entry from the directory, changing an existing entry, and changing the name of an entry. Most of the time, though, LDAP is used to search for information in the directory. The LDAP search operation allows some portion of the directory to be searched for entries that match some criteria specified by a search filter. Information can be requested from each entry that matches the criteria.

How is the information protected from unauthorized access?

Some directory services provide no protection, allowing anyone to see the information. LDAP provides a mechanism for a client to authenticate, or prove its identity to a directory server, paving the way for rich access control to protect the information the server contains. LDAP also supports privacy and integrity security services.

How does LDAP work?

LDAP directory service is based on a client-server model. One or more LDAP servers contain the data making up the directory information tree (DIT). The client connects to servers and asks it a question. The server responds with an answer and/or with a pointer to where the client can get additional information (typically, another LDAP server). No matter which LDAP server a client connects to, it sees the same view of the directory; a name presented to one LDAP server references the same entry it would at another LDAP server. This is an important feature of a global directory service, like LDAP.

What about X.500?

Technically, LDAP is a directory access protocol to an X.500 directory service, the OSI directory service. Initially, LDAP clients accessed gateways to the X.500 directory service. This gateway ran LDAP between the client and gateway and X.500's Directory Access Protocol (DAP) between the gateway and the X.500 server. DAP is a heavyweight protocol that operates over a full OSI protocol stack and requires a significant amount of computing resources. LDAP is designed to operate over TCP/IP and provides most of the functionality of DAP at a much lower cost.

While LDAP is still used to access X.500 directory service via gateways, LDAP is now more commonly directly implemented in X.500 servers.

The stand-alone LDAP daemon, or slapd(8), can be viewed as a lightweight X.500 directory server. That is, it does not implement the X.500's DAP. As a lightweight directory server, slapd(8) implements only a subset of the X.500 models.

SASL

What SASL is

SASL, the Simple Authentication and Security Layer, is a method for adding authentication support to connection-based protocols. SASL is defined in RFC-2222. To use SASL, a protocol includes a command for identifying and authenticating a user to a server and for optionally negotiating a security layer between the protocol and the connection. SASL is a means for authenticating yourself to the server without providing your password in the clear. This can also be used to provide extended capabilities based on your authorization. In plainer words, a SASL mechanism can provide authentication only, or it can also provide integrity checking, and possibly encryption as well.

During authentication , the mechanism performs authentication, transmits an authorization identity or userid, from the client to server, and negotiates the use of a mechanism-specific security layer, possibly encryption.

If use of a security layer is negotiated, it is applied to all subsequent data sent over the connection. The security layer takes effect immediately following the last response of the authentication exchange for data sent by the client and the completion indication for data sent by the server. Once the security layer is in effect, all further data transfers use this encryption.

In order to implement SASL authentication, you need support on the client and on the server

The various implementations of SASL provide the following mechanisms for authentication:

SASL is only a framework: specific SASL mechanisms govern the exact protocol exchange. With the Cyrus SASL library, the mechanisms need only be written once, and they'll work with all servers that use it.

Developers can write their own mechanisms to SASL to provide authentication.

It's relatively easy to define a protocol that uses SASL- it has to support a couple of simple functions, and it doesn't need to know anything about any particular mechanism. The first requirement is that servers must be able to tell the client what mechanisms are available. Typically this is done when the server sends a greeting to the client, telling it what options it supports. The second requirement is that clients must be able to tell the server to start a particular mechanism, and then both must be able to exchange "blobs" of information to initialize the mechanism, possibly indicating success or failure. The final requirement is that on success both the client and the server call a routine to filter traffic to/from the network. If the mechanism is doing any kind of cryptography, this routine will transparently handle it for the application.

Authentication and authorization identifiers

An important concept to become familiar with is the difference between an "authorization identifier" and an "authentication identifier".

The transmitted authorization identity may be different than the identity in the client's authentication credentials. This permits agents such as proxy servers to authenticate using their own credentials, yet request the access privileges of the identity for which they are proxying. With any mechanism, transmitting an authorization identity of the empty string directs the server to derive an authorization identity from the client's authentication credentials.

userid
(user id, authorization id) The userid is the identifier an application uses to check allowable options. There might exist on the server, a user ``doe'' (account of John Doe) allowed to write to ``/home/doe'' and it's subdirectories but not to ``/etc''.
authid
(authentication id) The authentication identifier is the identifier that is being checked. "doe"'s password might be "grep45", and the system will authenticate anyone who knows "grep45" as "doe". However, it's possible to authenticate as one user but act as another user. For instance, John might be away on vacation and assign one of his assistant, Jane, to read his mail. He might then allow Jane to act as him merely by supplying her password and her id as authentication but requesting authorization as "doe". So Jane might log in with an authentication identifier of "jane" and an authorization id of "doe" and her own (Jane's) password. Anyone familiar with sudo, will see the similarity.
Applications can set their own proxy policies; by default, the SASL library will only allow the same user to act for another (that is, userid must equal authid).

Realms

The Cyrus SASL library supports the concept of "realms". A realm is an abstract set of users and certain mechanisms authenticate users in a certain realm.

In the simplest case, a single server on a single machine, the realm might be the fully-qualified domain name of the server. If the applications don't specify a realm to SASL, most mechanisms will default to this.

If a site wishes to share passwords between multiple machines, it might choose it's authentication realm as a domain name, such as "kernel-panic.org". On the other hand, in order to prevent the entire site's security from being compromised when one machine is compromised, each server could have it's own realm. Certain mechanisms force the user (client side) to manually configure what realm they're in, making it harder for users to authenticate.

The Kerberos mechanisms treat the SASL realm as the Kerberos realm. Thus, the realm for Kerberos mechanisms defaults to the default Kerberos realm on the server. They may support cross-realm authentication; check your application on how it deals with this.

Some authentication mechanisms, such as PLAIN and CRAM-MD5, do not support the concept of realms.

How SASL works

How SASL works is governed by what mechanism the client and server choose to use and the exact implementation of that mechanism. This section describes the way these mechanisms act in the Cyrus SASL implementation.

The PLAIN mechanism and sasl_checkpass() call

The PLAIN mechanism is not a secure method of authentication by itself. It is intended for connections that are being encrypted by another level. (For example, the IMAP command "STARTTLS" creates an encrypted connection over which PLAIN might be used.) The PLAIN mechanism works by transmitting a userid, an authentication id, and a password to the server, and the server then determines whether that is an allowable triple.

The principal concern for system administrators is how the authentication and password are verified. The Cyrus SASL library is flexible in this regard:

Shared secrets mechanisms

The Cyrus SASL library also supports some "shared secret" authentication methods: CRAM-MD5 and it's successor DIGEST-MD5. These methods rely on the client and the server sharing a "secret", usually a password. The server generates a challenge and the client a response proving that it knows the shared secret. This is much more secure than simply sending the secret over the wire proving that the client knows it.

There's a downside: in order to verify such responses, the server must keep password equivalents in a database; if this database is compromised, it is the same as if every user's password for that realm is compromised.

The Cyrus SASL library stores these secrets in the /etc/sasldb database. Depending on the exact database method used (gdbm, ndbm, or db) the file may have different suffixes or may even have two different files ("sasldb.dir" and "sasldb.pag"). It is also possible for a server to define it's own way of storing authentication secrets. Currently, no application is known to do this.

The principle problem for a system administrator is to make sure that sasldb is properly protected; only the servers that need to read it to verify passwords should be able to. If there are any normal shell users on the system, they must not be able to read it.

Managing password changes is outside the scope of the library. However, system administrators should probably make a way of letting user's change their passwords available to users. The "saslpasswd" utility is provided to change the secrets in sasldb. It does not affect PAM, /etc/passwd, or any other standard system library; it only affects secrets stored in sasldb.

Finally, system administrators should think if they want to enable "auto_transition". If set, the library will automatically create secrets in sasldb when a user uses PLAIN to successfully authenticate. However, this means that the individual servers, such as imapd, need read/write access to sasldb, not just read access. By default, "auto_transition" is set to false; set it to true to enable. (There's no point in enabling this option if "pwcheck_method" is "sasldb".)

Kerberos mechanisms

The Cyrus SASL library also comes with two mechanisms that make use of Kerberos: KERBEROS_V4, which should be able to use any Kerberos v4 implementation, and GSSAPI (tested against MIT Kerberos 5 and Heimdal Kerberos 5). These mechanisms make use of the kerberos infrastructure and thus have no password database.

How to set configuration options

The Cyrus SASL library comes with a built-in configuration file reader. However, it is also possible for applications to redefine where the library gets it's configuration options from.

The default configuration file

By default, the Cyrus SASL library reads it's options from /usr/lib/sasl/App.conf (where "App" is the application defined name of the application). For instance, Sendmail reads it's configuration from /usr/lib/sasl/Sendmail.conf and the sample server application included with the library looks in /usr/lib/sasl/sample.conf.

A standard Cyrus SASL configuration file looks like:

srvtab: /var/app/srvtab 
pwcheck_method: kerberos_v4

Application configuration

Applications can redefine how the SASL library looks for configuration information. Check your application's documentation for specifics.

For instance, Cyrus imapd reads its sasl options from it's own configuration file, /etc/imapd.conf, by prepending all SASL options with sasl_: the SASL option pwcheck_method is set by changing sasl_pwcheck_option in /etc/imapd.conf. Check your application's documentation for more information.

Kerberos

What is Kerberos?

Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography. A free implementation of this protocol is available from the Massachusetts Institute of Technology. Kerberos is available in many commercial products as well.

The Internet is an insecure place.

Many of the protocols used in the Internet do not provide any security. Tools to "sniff" passwords off of the network are in common use by malicious hackers. Thus, applications which send an unencrypted password over the network are extremely vulnerable. Worse yet, other client/server applications rely on the client program to be honest about the identity of the user who is using it. Other applications rely on the client to restrict its activities to those which it is allowed to do, with no other enforcement by the server.

Kerberos was created by MIT

Kerberos was created by MIT as a solution to these network security problems. The Kerberos protocol uses strong cryptography so that a client can prove its identity to a server (and vice versa) across an insecure network connection. After a client and server has used Kerberos to prove their identity, they can also encrypt all of their communications to assure privacy and data integrity as they go about their business.

Kerberos is freely available from MIT, under copyright permissions very similar those used for the BSD operating system and the X Window System. MIT provides Kerberos in source form so that anyone who wishes to use it may look over the code for themselves and assure themselves that the code is trustworthy. In addition, for those who prefer to rely on a professionally supported product, Kerberos is available as a product from many different vendors.

In summary, Kerberos is a solution to your network security problems. It provides the tools of authentication and strong cryptography over the network to help you secure your information systems across your entire enterprise.

How Kerberos Works

This section provides a simplified description of a general user's interaction with the Kerberos system. This interaction happens transparently-users don't need to know and probably don't care about what's going on-but Kerberos administrators might find a schematic description of the process useful. This description glosses over a lot of details.

Network Services and Their Client Programs

In an environment that provides network services, you use client programs to request services from server programs that are somewhere on the network. Suppose you have logged in to a workstation and you want to rlogin to a typical UNIX host. You use the local rlogin client program to contact the remote machine's rlogind daemon.

Kerberos Tickets

Under Kerberos, the `klogind' daemon allows you to login to a remote machine if you can provide `klogind' a Kerberos ticket which proves your identity. In addition to the ticket, you must also have possession of the corresponding ticket session key. The combination of a ticket and the ticket's session key is known as a credential.

Typically, a client program automatically obtains credentials identifying the person using the client program. The credentials are obtained from a Kerberos server that resides somewhere on the network. A Kerberos server maintains a database of user, server, and password information.

The Kerberos Database

Kerberos will give you credentials only if you have an entry in the Kerberos server's Kerberos database. Your database entry includes your Kerberos principal (an identifying string, which is often just your username), and your Kerberos password. Every Kerberos user must have an entry in this database.

Kerberos Realms

Each administrative domain will have its own Kerberos database, which contains information about the users and services for that particular site or administrative domain. This administrative domain is the Kerberos realm.

Each Kerberos realm will have at least one Kerberos server, where the master Kerberos database for that site or administrative domain is stored. A Kerberos realm may also have one or more slave servers, which have read-only copies of the Kerberos database that are periodically propagated from the master server.

The Ticket-Granting Ticket

The kinit command prompts for your password. If you enter it successfully, you will obtain a ticket-granting ticket and a ticket session key which gives you the right to use the ticket. This combination of the ticket and its associated key is known as your credentials. As illustrated below, client programs use your ticket-granting ticket credentials in order to obtain client-specific credentials as needed.

Your credentials are stored in a credentials cache, which is often just a file in /tmp. The credentials cache is also called the ticket file, especially in Kerberos V4 documentation. Note, however, that a credentials cache does not have to be stored in a file.

Network Services and the Master Database

The master database also contains entries for all network services that require Kerberos authentication. Suppose that your site has a machine, laughter.mit.edu, that requires Kerberos authentication from anyone who wants to `rlogin' to it. The host's Kerberos realm is ATHENA.MIT.EDU.

This service must be registered in the Kerberos database, using the proper service name, which in this case is the principal: host/laughter.mit.edu@ATHENA.MIT.EDU

The / character separates the Kerberos primary (in this case, host) from the instance (in this case, laughter.mit.edu); the @ character separates the realm name (in this case, ATHENA.MIT.EDU) from the rest of the principal. The primary, host, denotes the name or type of the service that is being offered: generic host-level access to the machine. The instance, laughter.mit.edu, names the specific machine that is offering this service. There will generally be many different machines, each offering one particular type of service, and the instance serves to give each one of these servers a different Kerberos principal.

The Keytab File

For each service, there must also be a service key known only by Kerberos and the service. On the Kerberos server, the service key is stored in the Kerberos database.

On the server host, these service keys are stored in key tables, which are files known as keytabs.(1) For example, the service keys used by services that run as root are usually stored in the keytab file /etc/krb5.keytab.

The User/Kerberos Interaction

Suppose that you walk up to a host intending to login to it, and then rlogin to the machine laughter. Here's what happens:

host% rlogin laughter

Definitions

Following are definitions of some of the Kerberos terminology.

NIS NIS+

What are NIS and NIS+?

The Network Information Service (NIS) provides a simple network lookup service consisting of databases and processes. It was formerly known as Sun Yellow Pages (YP). The name had to be changed when British Telecom claimed to have the copyright of this term, and so it became NIS. The functionality of the two remains the same; only the name has changed. Its purpose is to provide information, that has to be known throughout the network, to all machines on the network. Information likely to be distributed by NIS is:

So, for example, if your password entry is recorded in the NIS passwd database, you will be able to login on all machines on the net which have the NIS client programs running.

NIS+ (Network Information Service Plus) was introduced by Sun Microsystems with the Solaris 2.x OS. It is compatible with NIS, but has a lot of additional features. With NIS+ it is possible to have hierarchical domains. All changes are done in the NIS+ database, it is not longer necessary to make changes on source files and to rebuild the complete maps. All changes are logged, so that a replica server can sync if it was down for some time.

The choice between NIS and NIS+ is easy - use NIS+ only if you have severe security needs. NIS+ is _much_ more problematic to administer (it's pretty easy to handle on the client side, but the server side is horrible). Another problem is that the support for NIS+ under Linux contains a lot of bugs and that the development has stopped.

NIS benefits users because it improves ease of use of a network. Without NIS, having a large number of systems on the network can create problems for the user. The user would need to remember a different password for every system they use, or else maintain the same password for every system themselves, and update their password on each system separately.

NIS benefits system administrators because it improves ease of administration of a network. NIS reduces the effort of maintaining a large number of systems and provides a global user ID (UID) and group ID (GID) name space. Suppose you are using NFS to make the user's directories and files available on every system. Because NFS does not try to translate UIDs or GIDs between systems, you must ensure that each user in the network has the same user ID and group ID on every system. For example, a user on a workstation whose UID is 205 and whose GID is 35 must have the same UID and GID (205 and 35) in the /etc/passwd file on every workstation that user accesses. If this is not done, a user on one system who creates a file and logs into another system may find that the file is owned by another user.

How NIS works

Within a network there must be at least one machine acting as a NIS server. You can have multiple NIS servers, each serving different NIS "domains" - or you can have cooperating NIS servers, where one is the master NIS server, and all the other are so-called slave NIS servers (for a certain NIS "domain", that is!) - or you can have a mix of them...

Slave servers only have copies of the NIS databases and receive these copies from the master NIS server whenever changes are made to the master's databases. Depending on the number of machines in your network and the reliability of your network, you might decide to install one or more slave servers. Whenever a NIS server goes down or is too slow in responding to requests, a NIS client connected to that server will try to find one that is up or faster.

Slave servers will be notified of any change to the NIS maps, (via the yppush program), and automatically retrieve the necessary changes in order to synchronize their databases. NIS clients do not need to do this since they always talk to the NIS server to read the information stored in it's DBM databases.

Old ypbind versions do a broadcast to find a running NIS server. This is insecure, due the fact that anyone may install a NIS server and answer the broadcast queries. Newer Versions of ypbind (ypbind-3.3 or ypbind-mt) are able to get the server from a configuration file - thus no need to broadcast.

How NIS+ works

NIS+ is a new version of the network information nameservice from Sun. The biggest difference between NIS and NIS+ is that NIS+ has support for data encryption and authentication over secure RPC.

The naming model of NIS+ is based upon a tree structure. Each node in the tree corresponds to an NIS+ object, from which we have six types: directory, entry, group, link, table and private.

The NIS+ directory that forms the root of the NIS+ namespace is called the root directory. There are two special NIS+ directories: org_dir and groups_dir. The org_dir directory consists of all administration tables, such as passwd, hosts, and mail_aliases. The groups_dir directory consists of NIS+ group objects which are used for access control. The collection of org_dir, groups_dir and their parent directory is referred to as an NIS+ domain.

NIS+ servers were created with the ability to "speak" the NIS/YP client protocol. This means that a NIS+ server can support both NIS and NIS+ clients. However, the converse is not true.

What are some terminology differences between NIS and NIS+?

NIS Requirements

NIS+ Requirements

There is no NIS+ server for Linux and it doesn't look like that there ever will be one. Currently all NIS+ development has ceased.

The Linux NIS+ client code was developed for the GNU C library 2. There is also a port for Linux libc5, since most commercial Applications where linked against this library in the past, and you cannot recompile them for using glibc. There are problems with libc5 and NIS+: static programs cannot be linked with it, and programs compiled with this library will not work with other libc5 versions.

SSH

What is SSH?

The Acronym SSH stands for Secure Shell. There are a couple of ways that you can access most Linux/Unix systems. The most common way is to use a telnet program such as the one called telnet(for Unix and Windows). Accessing a shell account in this fashion though poses a danger in that everything that you do over that telnet session is visible in plain text on your local network, and the local network of the machine you are connecting to.

As one solution SSH was created to encrypt the data being sent over the network as well as provide an option that prevents passwords from being ever passed over the network. SSH can use several different forms of encryption, anywhere from 56 to 1024 bit. SSH has been ported to Operating Systems on several platforms including Linux, Microsoft Windows and Macintosh.

The following safeguards are provided by SSH:

Because the SSH protocol encrypts everything it sends and receives, it can be used to secure otherwise insecure protocols. Using a technique called port forwarding, an SSH server can become a conduit to secure insecure protocols, like POP, increasing overall system and data security.

Why Use SSH?

Threats to network traffic include packet sniffing, DNS and IP spoofing [2] and the proliferation of fake routing information. In general terms, these threats can be categorized as follows:

Both techniques cause information to be intercepted, possibly for hostile reasons. The results can be disastrous, whether that goal is achieved by listening for all packets on a LAN or a hacked DNS server pointing to a maliciously duplicated host.

If SSH is used for remote shell logins and file copying, these security threats can be greatly diminished. A server's digital signature provides verification for its identity. The entire communication between client and server systems cannot be used if intercepted, because each of the packets is encrypted. Attempts to spoof the identity of either side of a communication will not work, since each packet is encrypted using a key known only by the local and remote systems.

Heimdal

Heimdal is a free implementation of Kerberos 5.

Refeferences

The Linux-PAM System Administrators' Guide

Pluggable Authentication Modules

Linux Journal Archive: Pluggable Authentication Modules for Linux O'Reilly Article on PAM Modules

Linux PAM FAQ

Linux Documentation Project: User-Authentication HOWTO

Introduction to OpenLDAP Directory Services

RFC 2551 Lightweight Directory Access Protocol (v3)

RFC2553 Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names

Carnegie Mellon University:Cyrus SASL

The GNU SASL Manual

RFC 2222 Simple Authentication and Security Layer (SASL)

Cyrus SASL for System Administrators

Kerberos: The Network Authentication Protocol

Kerberos V5 System Administrator's Guide

The Linux NIS(YP)/NYS/NIS+ HOWTO

Red Hat Linux 7.3: The Official Red Hat Linux Reference Guide: Chapter 10; SSH Protocol