Hack #6. Centralize Logins with LDAP

Creating individual accounts on individual machines is a thing of the past: centralize authentication information and more by using a directory server.

The Lightweight Directory Access Protocol (LDAP) provides a hierarchical collection of information that can be accessed over a network. LDAP is an example of a directory service. In this context, the term directory refers to a central information resource (such as a telephone directory or network-accessible address book) but also leverages the idea of hierarchical directory structures. LDAP directories are essentially simple, hierarchical databases that are accessed using keys that identify the portions of the directory hierarchy to traverse to locate a specific unit of information.

The core idea of hierarchical elements and attributes is easy to understand and work with, and it should be familiar to users of similar information models, such as XML. The LDAP protocol is also independent of the underlying storage model used, making it easy to map LDAP data into existing databases or migrate to new, smaller database models.

Like all directory services, LDAP is a client/server technology. Clients can either query or upload information to an LDAP server. In the case of a query, the LDAP server either responds directly or forwards the query to another LDAP server, which repeats the "respond or forward" process. The OpenLDAP project (http://www.openldap.org ), where most Linux LDAP development now takes place, is the source of the software discussed in this hack.

Installing LDAP Clients and Servers

Using LDAP in your environment requires that you have a few basic packages installed on your systems, or that you build and install the OpenLDAP software from scratch. If you need to build it yourself, you can download the latest version of the full OpenLDAP package from http://www.openldap.org/software/download. If your Linux systems use a package management system, you'll need to install:

  • An OpenLDAP client on all your systems (including the server, for debugging purposes). These packages usually have names like openldapclient or openldap2-client.

  • An OpenLDAP server on your server system. Some Linux distributions, such as SUSE, provide these in openldap or operldap2 packages, while others provide explicit servers in packages with names like openldap-servers.

  • OpenLDAP libraries on all clients and servers. Some Linux distributions, such as Red Hat Enterprise Linux and Fedora, split these into separate packages that are simply named openldap, while others integrate them into the OpenLDAP client and server packages.

These packages will give you basic LDAP functionality. However, to integrate them with user lookups and authentication on your client systems, you'll also need the following:

  • The name service module, nss_ldap, for integrating user and group lookup requests with an OpenLDAP server.

  • The PAM module, pam_ldap, for integrating LDAP authentication into your client's authentication process.

If you're building these yourself, their source code is available from PADL Software Pty Ltd, the folks who wrote them, at the URL http://www.padl.com/Contents/OpenSourceSoftware.html.

Finally, you'll need some useful utilities for migrating existing password, shadow, and group information into your OpenLDAP directory. These are also available from PADL Software Pty Ltd, at the URL http://www.padl.com/download/MigrationTools.tgz.

Many Linux distributions provide graphical utilities for configuring LDAP and LDAP authentication, such as Red Hat's authconfig application and the LDAP client configuration applet in SUSE's YaST tool. This hack explains how to do everything from the command line, in case you don't have access to such utilities. If you're using either of these systems, the graphical utilities simplify the installation and configuration processes, but it's always nice to know what's really required under the covers. You will still have to migrate your user, password, and group data into your LDAP server manually, in any case.

Tip

In the rest of this hack, I'll assume that you installed all this software in standard system locations and can therefore find the OpenLDAP configuration files in /etc/openldap. If you built them yourself, you may have installed them relative to /usr/local, and thus you may need to look for the configuration files in locations such as /usr/local/etc/openldap.

Configuring an OpenLDAP Server

The configuration files for OpenLDAP clients and servers, which are traditionally located in the directory /etc/openldap, are:

ldap.conf

Sets the default values used by OpenLDAP clients on your system.

slapd.conf

Contains configuration information for the OpenLDAP slapd server running on the current system. This file should never be readable by non-privileged users, because it contains password and other security information for your OpenLDAP server.

Configuring an OpenLDAP server is a fairly simple process. First, you change the suffix entry so that it correctly identifies your domain. For example, the default entry in /etc/openldap/slapd.conf is usually:

	suffix		"dc=my-domain,dc=com"

Change this to reflect your domain. For example, to set up an OpenLDAP server for the domain vonhagen.org, change this line to the following:

	suffix		"dc=vonhagen,dc=org"

Next, change the rootdn entry to reflect the name of a privileged user who has unrestricted access to your OpenLDAP directory. For example, the default entry in /etc/openldap/slapd.conf is usually:

	rootdn		"cn=Manager,dc=my-domain,dc=com"

Continuing with the previous example, you would change this to something like the following for the vonhagen.org domain:

	rootdn		"cn=ldapadmin,dc=vonhagen,dc=org"

Though this user is the equivalent of the root user as far as OpenLDAP is concerned, the name does not have to be that of a real user on your system.

Finally, though optional in some sense, you may want to set a unique password for your OpenLDAP server by modifying the rootpw entry in your /etc/openldap/slapd.conf configuration file. This enables you to configure, test, and correct your OpenLDAP system over your local network, if necessary. For example, the default entry in /etc/openldap/slapd.conf uses the clear-text password secret, as shown here:

	rootpw		secret

You can provide a clear-text or encrypted password as the value for this entry. You can use the slappasswd command to generate an encrypted password that you can paste into the /etc/openldap/slapd.conf file, as in the following example:

	# slappasswd
	New password:
	Re-enter new password:
	{SSHA}x0uopfqDBaylPdv3zfjLqOSkrAUh5GgY

The slappasswd command prompts you for a new password, asks for confirmation, and then displays the encrypted password string preceded by the encryption mechanism used in the password. You then simply replace the value of the existing rootpw option with the generated string, as in the following example:

	rootpw		{SSHA}x0uopfqDBaylPdv3zfjLqOSkrAUh5GgY

You should enable the rootpw option only when initially configuring your OpenLDAP server, and it is necessary to do so only if you must configure your OpenLDAP server over a network. It's always a good idea to set a unique, encrypted password for your OpenLDAP server that differs from your standard root password, even though the /etc/openldap/slapd.conf file should not be readable by nonprivileged users on your system. Once you have completed your configuration, you should disable this entry by commenting it out. To do so, put a hash mark (#) at the beginning of the line containing the rootpw entry.

Tip

OpenLDAP passwords are sent in the clear over the network unless you enable Secure Socket Layer/Transaction Layer Security (SSL/TLS) encryption in your /etc/openldap/slapd.conf file. Discussing SSL/TLS encryption for OpenLDAP is outside the scope of this hack. For additional information, see a reference such as Gerald Carter's LDAP System Administration (O'Reilly).

Once you have modified your /etc/openldap/slapd.conf file and saved your changes, you can start the OpenLDAP server using the /etc/init.d/ldap script, as in the following example:

	# /etc/init.d/ldap start

As with all startup scripts on Linux systems, you should symlink this file to start up and kill files in the directories associated with your system's default runlevel to ensure that it starts automatically when you reboot your system.

Tip

The examples in the rest of this hack assume that you have entered the name ldap as a valid entry for your LDAP server in DNS.

Migrating User, Password, and Group Entries to an LDAP Server

To configure your LDAP server to provide authentication information, you must first migrate your existing authentication information to the LDAP server. You do this by preparing LDAP Data Interchange Format (LDIF) files that hold the contents of your /etc/passwd,/etc/shadow, and /etc/group files, and then importing those files into the LDAP server.

Creating LDIF files from your existing /etc/passwd, /etc/shadow, and /etc/group files is most easily done by using the migrate_passwd.pl and migrate_group.pl scripts found in the migration tools available at http://www.padl.com/download/MigrationTools.tgz. If you've installed OpenLDAP from packages, these scripts may be located on your system in the directory /usr/share/openldap/migration.

Tip

If you have multiple password, shadow, and group files on different systems that you want to merge into a single LDAP repository, you can copy them all to your LDAP server system, concatenate them, and sort them to produce single files. You can then edit these files so that they have only single entries for each user and group and install them as the master password, shadow, and group files on your server before running the migration scripts. Verify that these files work correctly after installation and before migrating them to LDAP!

To migrate user, password, and group information into your LDAP server so you can use it as a basis for client system authentication, do the following:

  1. Become the root user, and change directory to the directory where you unpacked the migration scripts or where they are already installed.

  2. Edit the file migrate_common.ph, which sets variables used by all of the migration scripts. Set the value for the DEFAULT_BASE variable to the correct value for your environment. As an example, the correct value for migrating information to the LDAP server used as an example throughout this hack would be:

    	$DEFAULT_BASE = "dc=vonhagen,dc=org";
  3. Use the migrate_passwd.pl script to generate an LDIF file for your user and password information, as in the following example:

    	./migrate_passwd.pl /etc/passwd passwd.LDIF

    The migrate_passwd.pl script also extracts the necessary password information from your /etc/shadow file.

  4. Generate an LDIF file for your group information using the migrate_group.pl script, as in the following example:

    	./migrate_group.pl /etc/group group.LDIF
  5. Import the files that you just created into your LDAP directory using commands like the following:

    	# ldapadd -x -h hostname -D "cn=ldapadmin,dc=vonhagen,dc=org" \
    		-w password -f passwd.LDIF
    	# ldapadd -x -h hostname -D "cn=ldapadmin,dc=vonhagen,dc=org" \
    		-w password -f group.LDIF

    In these commands, replace hostname with the hostname of the system on which your LDAP server is running, make sure that the credentials specified following the -D option match those of the root user for your LDAP server, and replace password with the password you set in the rootpw entry—both as defined in your OpenLDAP server configuration file (/etc/openldap/slapd.conf).

After following these steps, you are ready to update your client systems to use LDAP authentication (and test them, of course).

Updating Client Systems to Use LDAP Authentication

On each system that you want to use the new LDAP authentication server, you must do the following:

  1. Modify the configuration file /etc/pam_ldap.conf, used by the pam_ldap.so PAM module, to contain the correct information about your LDAP server. This usually simply requires correctly setting the values of the host and base statements in this file, as in the following example:

    	host ldap.vonhagen.org 
    	base dc=vonhagen,dc=org
  2. Modify the configuration file /etc/lib-nss-ldap.conf, used to integrate LDAP with the name service on your system, to contain the correct information about your LDAP server. Again, this usually simply requires correctly setting the values of the host and base statements in this file, as in the following example:

    	host ldap.vonhagen.org
    	base dc=vonhagen,dc=org
  3. Add entries for LDAP to the appropriate PAM configuration files on your system. As explained in "Customize Authentication with PAMs" [Hack #4] , some Linux systems use individual files to configure authentication for specific services, while others (such as Red Hat/Fedora) create a centralized file for system authentication, called /etc/pam.d/system-auth. If you are using individual files, you must add the appropriate entries for LDAP authentication to login-related services such as login and sshd. You should insert auth and account entries for the pam_ldap.so module before your system's generic Linux authentication checks, which are usually handled by pam_unix2.so (SUSE) or pam_pwdb.so (most other Linuxes). An example PAM file for the sshd service would look something like the following:

    	auth		required		/lib/security/pam_nologin.so
    	auth		sufficient		/lib/security/pam_ldap.so
    	auth		required		/lib/security/pam_pwdb.so shadow nodelay
    	account		sufficient		/lib/security/pam_ldap.so
    	account		required		/lib/security/pam_pwdb.so
    	password	required		/lib/security/pam_cracklib.so
    	password	required		/lib/security/pam_pwdb.so shadow nullok use_authtok
    	session		required		/lib/security/pam_mkhomedir.so skel=/etc/skel/
    					 umask=0022
    	session		required		/lib/security/pam_pwdb.so
  4. If you are using a Red Hat or Fedora system, modify /etc/pam.d/system-auth to look like the following:

    	auth		required	/lib/security/pam_env.so
    	auth		sufficient  /lib/security/pam_unix.so likeauth nullok
    	auth		sufficient  /lib/security/pam_ldap.so use_first_pass
    	auth		required	/lib/security/pam_deny.so
    	account		required	/lib/security/pam_unix.so broken_shadow
    	account		sufficient  /lib/security/pam_succeed_if.so uid < 100 quiet
    	account		[default=bad success=ok user_unknown=ignore] /lib/security
    				/pam_ldap.so
    	account		required	/lib/security/pam_permit.so
    	password	requisite   /lib/security/pam_cracklib.so retry=3
    	password	sufficient  /lib/security/pam_unix.so nullok use_authtok md5
    				 shadow
    	password	sufficient /lib/security/pam_ldap.so use_authtok
    	password	required   /lib/security/pam_deny.so
    	session		required   /lib/security/pam_limits.so
    	session		required   /lib/security/pam_unix.so
    	session		optional   /lib/security/pam_ldap.so
  5. Modify your /etc/nsswitch.conf file to specify that the system looks for password, shadow, and group information in LDAP. Correct entries would be the following:

    	passwd: files ldap
    	shadow: files ldap
    	group: files ldap

    This tells the name service switch to first check the local password, shadow, and group files on the client system for authentication information and then check LDAP. This enables you to create local accounts when necessary, giving those local accounts priority while still using LDAP for most accounts.

  6. Back up your local /etc/passwd, /etc/shadow, and /etc/group files and edit the primary copies on the client system to remove all user accounts, so that they contain only system accounts.

The next time you log in on your client system, it will contact your LDAP server for authentication information. When creating new user and group accounts, you will need to use a command-line interface to OpenLDAP (http://quark.humbug.org.au/publications/scripts/ldap/cli/) to create the necessary account information. There are also a number of graphical tools for creating and managing LDAP accounts, but I'm more comfortable with the command line.

Tip

Before logging out of this client system and configuring another, open a new login session to this host using telnet or ssh to ensure that you can correctly log in using LDAP. If you encounter any problems, do not log out of this system until you have resolved them.

Congratulations! You're now making the most of your network and will rarely, if ever, have to manage local password and group information on individual systems again. Combining this hack with other hacks (such as "Centralize Resources Using NFS" [Hack #56] and "Automount NFS Home Directories with autofs" [Hack #57] ) further liberates individual systems from user-specific data.

See Also

Get Linux Server Hacks, Volume Two now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.