Previous Section Next Section

14.4 LDAP

The Lightweight Directory Access Protocol (LDAP) is a low-overhead version of the X.500-base directory access service. It provides for the storage of directory information (including, for authentication systems, usernames and passwords) with access and updates over a secure network channel. There are two major versions of LDAP. LDAPv2, described in the 1995 RFC 1777, provides no security for passwords unless it is implemented in conjunction with Kerberos. LDAPv3, described in RFC 2251, adds support for SASL (the Simple Authentication and Security Layer, RFC 2222). SASL provides several additional approaches to secure password authentication (including Kerberos!). Furthermore, the open source implementation of LDAPv3, OpenLDAP 2.0.x,[18] supports the use of SSL/TLS to secure the entire communication link between client and server, including the authentication process.

[18] As of this writing, the current release of OpenLDAP is 2.1.3, but the current stable release (proven to be reliable) is 2.0.25. As most Linux systems distribute the stable releases, we focus on OpenLDAP 2.0.x here.

On its own, LDAP provides general directory services. For example, many organizations deploy LDAP to organize their employee phone, email, and address directory, or directories of computers on the network. We discuss LDAP in this chapter because it can form the basis of an authentication and network information system, and because it is increasingly being used for that purpose, particularly on Linux systems.

14.4.1 LDAP: The Protocol

The LDAP server's data is organized as a tree of entries, each belonging to one or more object classes, and each containing attributes with values. For example, an entry belonging to the posixAccount object class might have the following attributes:

cn

The common name of the entry, a required attribute that distinguishes this entry from others with the same parent in the directory tree. For posixAccount objects, the common name is often the user's full name.

uid

The user's login ID.

uidNumber

The Unix UID number associated with this user.

gidNumber

The Unix GID number associated with this user's primary group.

homeDirectory

The user's home directory path.

userPassword

The user's password (sometimes). In most configurations, a shadowAccount object contains the encrypted password data instead.

loginShell

The user's login shell.

gecos

The user's comment field, often the user's full name.

description

An optional description of the entry.

LDAP is a client/server protocol. The LDAP client sends requests to the LDAP server, and receives responses back. Clients can send requests to modify the server's data store, or to search it and return one or more attributes of a particular entry, or a whole subtree of entries.

14.4.2 LDAP Integrity and Reliability

OpenLDAP 2.0.x provides several important features to ensure the integrity of the data and the reliability of the system:

Data integrity and confidentiality

The OpenLDAP server can accept connections secured by TLS and can provide end-to-end encryption of the client/server interaction. In addition, TLS makes unauthorized modification of the data stream infeasible.

Server authentication

To support TLS, the LDAP server is assigned a cryptographic public key certificate signed by a trusted certifying authority. LDAP clients with the certificates of the server and the certifying authority can assure themselves that they are communicating with the server they intended to communicate with.

Replication

OpenLDAP includes a daemon (slurpd) that can replicate entire LDAP datastores onto secondary servers to provide redundancy should the master server fail.

14.4.3 Authentication with LDAP

RFC 2307 describes an approach to using LDAP as a network information system. Although this RFC does not specify an Internet standard, its mechanisms are widely used, and a schema to implement them (nis.schema) is included with OpenLDAP 2.0.x. The schema defines object classes that represent users (posixAccount and shadowAccount), groups (posixGroup), services (ipService), protocols (ipProtocol), remote procedure calls (oncRPC), hosts (ipHost), networks (ipNetwork), NIS netgroups (nisNetgroup, nisMap, nisObject), and more.

Each service that authenticates users could be rewritten to perform an LDAP lookup; this would be analogous to the "Kerberizing" process that Kerberos requires. However, this approach is inefficient. Every time a new authentication system is developed, a new version of each network client and server has to be written. Instead, two alternatives have been developed, released as open source software by PADL Software Pty, Ltd., and included with most Linux distributions.

14.4.3.1 nss_ldap

One approach is to modify the C library functions that get user information (such as getpwent( )) to use an LDAP database instead of (or along with) local files, NIS, and so on. Systems that use the Name Service Switch model described in the sidebar earlier in this chapter can use the libnss_ldap library to transparently enable LDAP searches for users, passwords, groups, and other information.

14.4.3.2 pam_ldap

Another approach is to develop a higher-level authentication library and adapt each network client and server to use the high-level library. When a new authentication system is developed, it need only be added to the library to provide it to all of the clients and servers. This is the approach taken by Sun's Pluggable Authentication Module (PAM), which is widely deployed on Linux systems. LDAP authentication is implemented as a PAM module, pam_ldap. Unlike libnss_ldap, pam_ldap provides only user authentication against the LDAP database; it does not distribute other database information.

Because the most common use of PAM is to authenticate users against local password files, PAM is discussed in some detail in Chapter 4. If your LDAP server is using the standard nis.schema, adding LDAP authentication to a PAM-controlled service is as easy as adding a line to its PAM configuration file that specifies pam_ldap.so as sufficient for authentication, account verification, and password updating. Accordingly, we concentrate on nss_ldap here.

14.4.4 Configuring Authentication with nss_ldap

Here's an example of the configuration of nss_ldap for authentication. Consider a fictional organization that uses the myorg.org domain and has a cluster of Linux client workstations that use LDAP to perform user authentication against an nis.schema tree stored on the ldap.myorg.org Linux server.

14.4.4.1 Setting up the LDAP server

Follow these steps to set up the LDAP server:

  1. The server needs to have OpenLDAP 2.0.x installed and compiled to support TLS, which implies that the OpenSSL libraries are available. It's also useful to have the libnss_ldap libraries on the server. Compiling OpenLDAP is beyond the scope of this book, but most major Linux distributions include OpenLDAP packages that are easily installed. For example, if the server is running Red Hat Linux 7.3, the openldap, openldap-clients, openldap-servers, openssl, and nss_ldap rpms should be installed. A server running Debian Linux 3.0 would install the libldap2, libnss-ldap, ldap-utils, slapd, openssl, and libssl0.9.6 debs.

  2. The OpenLDAP server daemon is called slapd, and is configured through the file slapd.conf, which may reside in /etc, /etc/ldap, /etc/openldap, or a similar location. slapd.conf has several options that control how and where the server stores its data, who may read and write data from the server, which schemas are in use, the top of the tree of entries that this server is responsible for, and, for TLS, where to find the server's certificate and associated private key. Because this file may contain (encrypted) passwords, it should be readable only by the user that slapd runs as.

    Here's a minimal slapd.conf for authentication:

    # Include important schema; nis.schema depends on core.schema and cosine.schema.
    include         /etc/openldap/schema/core.schema
    include         /etc/openldap/schema/cosine.schema
    include         /etc/openldap/schema/nis.schema
    # Where to find the TLS certificate and private key
    # This example uses a self-signed certificate generated using:
    #   openssl req -newkey rsa:1024 -keyout slapd.key -nodes -x509 -days 365 -out
    #   slapd.crt
    # The common name in the certificate would be ldap.myorg.org.
    # In production applications, you'd probably generate a key and a certificate-
    # signing request instead and send the request to a certifying authority who
    # would send back the certificate.
    # These files should be readable by the UID that the LDAP server runs as, but no
    # one else.
    # 
    TLSCertificateFile /usr/share/ssl/certs/slapd.crt
    TLSCertificateKeyFile /usr/share/ssl/certs/slapd.key
    # Use the standard ldbm database backend.
    database        ldbm
    # Define the base of the data tree.
    suffix          "dc=myorg,dc=org"
    # The "root" distinguished name--the name of a superuser who can modify any data
    rootdn         "cn=manager,dc=myorg,dc=org"
    # The password for the superuser, as an encrypted hash. Generated with the 
    # slappasswd program
    rootpw        {SSHA}aSO0BEyYov82bgOxMjdkWk8uYMmiwMtM
    # Before running slapd, this directory must: (a) exist and (b) be accessible only
    # by slapd and ldap tools.
    directory       /var/lib/ldap
    # Indices to maintain
    index   objectClass,uid,uidNumber,gidNumber,memberUid   eq
    index   cn,mail,surname,givenname                       eq,subinitial
  3. Start the slapd daemon. A typical slapd command line looks like this:[19]

    [19] Of course, slapd is normally started at boot time by whatever process is used on your system to run daemons at startup.

    # /usr/sbin/slapd -u ldap -h "ldap:/// ldaps:///"

    This command line runs the daemon as user ldap and directs it to bind itself to the ldap port (389) and ldaps (LDAP-over-SSL) port (636) on all of the server's interfaces. The argument to the -h switch is a space-separated list of URLs. If the daemon should provide only SSL-secured LDAP on the interface with the IP address associated with ldap.myorg.org, the command line might look like this:

    # /usr/sbin/slapd -u ldap -h "ldaps://ldap.myorg.org/"
  4. Generate data for the server. OpenLDAP is distributed with several tools that can be used to add data to a running LDAP server. Initially, rootdn and rootpw are used when connecting to the LDAP server to add data; once your user account data has been added to the server, the LDAP root account can be disabled, and you can write access control rules in slapd.conf to allow read or write access to different portions of the data tree by different user accounts.

    Entries to be added are written in the LDAP Data Interchange Format (LDIF), a textual representation of LDAP data, and the LDAP tools read in LDIF files and transmit the data to the server. Writing LDIF is beyond the scope of this book but is covered in detail in the OpenLDAP Administrator's Guide at http://www.openldap.org/doc.

    If your server already has the initial user and group account information stored in the /etc/passwd, /etc/shadow, and /etc/group files, check out the MigrationTools packages from PADL. They provide shell scripts that can convert these files to the appropriate LDAP entries.

  5. Add appropriate rules to your LDAP server's host-based firewall and your network's firewall to permit LDAP queries only from hosts that you want them from.

At this point, the server contains the account data that we want the clients to use for authentication. It remains to configure the clients to access the server.

14.4.4.2 Setting up the LDAP clients

Follow these steps to set up the LDAP clients:

  1. The clients need to have OpenLDAP 2.0.x and libnss_ldap libraries installed and compiled to support TLS, which implies that the OpenSSL libraries are available.[20] In addition, you may want the nscd daemon installed. For example, if the server is running Red Hat Linux 7.3, the openldap, nscd, openssl, and nss_ldap RPMs should be installed. A server running Debian Linux 3.0 would install the libldap2, nscd, libnss_ldap, and libssl0.9.6 debs.

    [20] Debian's LDAP libraries are not compiled with TLS support. If you're in this situation, you can still ensure TLS-secured connections by using the stunnel program to set up an encrypted channel that is redirected to a port on the local host. For some excellent examples of this trickery, see the LDAP-Implementation-HOWTO by Roel van Meer and Giuseppe Lo Biondo at http://www.tldp.org/HOWTO/LDAP-Implementation-HOWTO/index.html.

  2. The ldap.conf file, typically found in /etc, /etc/ldap, /etc/openldap, or similar locations, provides the default information used by LDAP clients—typically the data tree to search and the URL of the LDAP server(s). It's a very simple file and should be world-readable, but writable only by root. Here's what the myorg.org ldap.conf might look like:

    BASE    dc=myorg, dc=org
    URI     ldaps://ldap.myorg.org
  3. The file /etc/nsswitch.conf (discussed earlier in this chapter) controls which services are used to look up information about users, groups, etc. By adding LDAP to the file, we can cause the C library network information functions to search the LDAP database:

    # User accounts, passwords, and groups--local files, then LDAP
    passwd:       files ldap
    shadow:       files ldap
    group:        files ldap
    # Hosts--try local files, then DNS
    hosts:        files dns
    # For these maps, try ldap first, and if it returns nothing, we're done.
    # Use files only if the LDAP server is unreachable.
    services:     ldap [NOTFOUND=return] files
    networks:     ldap [NOTFOUND=return] files
    protocols:    ldap [NOTFOUND=return] files
    rpc:          ldap [NOTFOUND=return] files
    ethers:       ldap [NOTFOUND=return] files
  4. Finally, nscd can be started in order to cache LDAP lookup results. This is particularly useful if the LDAP server responds slowly or is on a distant network segment. nscd is started at boot time like other daemons, and its caching rules (what to cache and for how long) are controlled by the /etc/nscd.conf configuration file.

At this point, software that uses the C library functions (such as getpwent( )) should automatically recognize users and groups that are defined in the LDAP database as well as those in the local files.

LDAP provides a powerful and flexible alternative to NIS or NIS+. Its primary advantages include its ability to store and serve non-authentication data as well as authentication data, and the availability of TLS-secured communication. Its primary disadvantage is that updating the LDAP database is more complex than updating an NIS master. In addition, current implementations of LDAP do not provide for client host authentication (but neither does NIS or NIS+).

    Previous Section Next Section