Product SiteDocumentation Site

11.7. LDAP Directory

OpenLDAP is an implementation of the LDAP protocol; in other words, it's a special-purpose database designed for storing directories. In the most common use case, using an LDAP server allows centralizing management of user accounts and the related permissions. Moreover, an LDAP database is easily replicated, which allows setting up multiple synchronized LDAP servers. When the network and the user base grows quickly, the load can then be balanced across several servers.
LDAP data is structured and hierarchical. The structure is defined by “schemas” which describe the kind of objects that the database can store, with a list of all their possible attributes. The syntax used to refer to a particular object in the database is based on this structure, which explains its complexity.

11.7.1. Installing

The slapd package contains the OpenLDAP server. The ldap-utils package includes command-line tools for interacting with LDAP servers.
Installing slapd normally asks a few debconf questions; this configuration phase can be forced by the dpkg-reconfigure slapd command.
  • Omit OpenLDAP server configuration? No, of course, we want to configure this service.
  • DNS domain name: “falcot.com”.
  • Organization name: “Falcot Corp”.
  • An administrative passwords needs to be typed in.
  • Database backend to use: “HDB”.
  • Do you want the database to be removed when slapd is purged? No. No point in risking losing the database in case of a mistake.
  • Move old database? This question is only asked when the configuration is attempted while a database already exists. Only answer “yes” if you actually want to start again from a clean database, for instance if you run dpkg-reconfigure slapd right after the initial installation.
  • Allow LDAPv2 protocol? No, there's no point in that. All the tools we're going to use understand the LDAPv3 protocol.
A minimal database is now configured, as demonstrated by the following query:
$ ldapsearch -x -b dc=falcot,dc=com
# extended LDIF
#
# LDAPv3
# base <dc=falcot,dc=com> with scope sub
# filter: (objectclass=*)
# requesting: ALL
#

# falcot.com
dn: dc=falcot,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Falcot Corp
dc: falcot

# admin, falcot.com
dn: cn=admin,dc=falcot,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2
The query returned two objects: the organization itself, and the administrative user.

11.7.2. Filling in the Directory

Since an empty database is not particularly useful, we're going to inject into it all the existing directories; this includes the users, groups, services and hosts databases.
The migrationtools package provides a set of scripts dedicated to extract data from the standard Unix directories (/etc/passwd, /etc/group, /etc/services, /etc/hosts and so on), convert this data, and inject it into the LDAP database.
Once the package is installed, the /etc/migrationtools/migrate_common.ph must be edited; the IGNORE_UID_BELOW and IGNORE_GID_BELOW options need to be enabled (uncommenting them is enough).
The actual migration operation is handled by the migrate_all_online.sh command, as follows:
# cd /usr/share/migrationtools
# LDAPADD="/usr/bin/ldapadd -c" ETC_ALIASES=/dev/null ./migrate_all_online.sh
The migrate_all_online.sh asks a few questions about the LDAP database into which the data is to be migrated. Table 11.1 summarizes the answers given in the Falcot use-case.

Table 11.1. Answers to questions asked by the migrate_all_online.sh script

Question Answer
X.500 naming context dc=falcot,dc=com
LDAP server hostname localhost
Manager DN cn=admin,dc=falcot,dc=com
Bind credentials the administrative password
Create DUAConfigProfile no

We deliberately ignore migration of the /etc/aliases file, since the standard schema as provided by Debian does not include the structures that this script uses to describe email aliases. Should we want to integrate this data into the directory, the /etc/ldap/schema/misc.schema file should be added to the standard schema.
Also note the use of the -c option to the ldapadd command; this option requests that processing doesn't stop in case of error. Using this option is required because converting the /etc/services often generates a few errors that can safely be ignored.

11.7.3. Managing Accounts with LDAP

Now the LDAP database contains some useful information, the time has come to make use of this data. This section focuses on how to configure a Linux system so that the various system directories use the LDAP database.

11.7.3.1. Configuring NSS

The NSS system (Name Service Switch, see sidebar GOING FURTHER NSS and system databases) is a modular system designed to define or fetch information for system directories. Using LDAP as a source of data for NSS requires installing the libnss-ldap package. Its installation asks a few questions; the answers are summarized in Table 11.2.

Table 11.2. Configuring the libnss-ldap package

Question Answer
LDAP server Uniform Resource Identifier ldap://ldap.falcot.com
Distinguished name of the search base dc=falcot,dc=com
LDAP version to use 3
Does the LDAP database require login? no 
LDAP account for root cn=admin,dc=falcot,dc=com
LDAP root account password the administrative password

The /etc/nsswitch.conf file then needs to be modified, so as to configure NSS to use the freshly-installed ldap module.

Example 11.31. The /etc/nsswitch.conf file

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd: ldap compat
group: ldap compat
shadow: ldap compat

hosts: files dns ldap
networks: ldap files

protocols: ldap db files
services: ldap db files
ethers: ldap db files
rpc: ldap db files

netgroup: files

The ldap module is usually inserted before others, and it will therefore be queried first. The notable exception is the hosts service since contacting the LDAP server requires consulting DNS first (to resolve ldap.falcot.com). Without this exception, a hostname query would try to ask the LDAP server; this would trigger a name resolution for the LDAP server, and so on in an infinite loop. As for the netgroup services, it is not yet handled by the LDAP module.
If the LDAP server should be considered authoritative (and the local files used by the files module disregarded), services can be configured with the following syntax:
service: ldap [NOTFOUND=return] files.
If the requested entry does not exist in the LDAP database, the query will return a “not existing” reply even if the resource does exist in one of the local files; these local files will only be used when the LDAP service is down.

11.7.3.2. Configuring PAM

This section describes a PAM configuration (see sidebar BEHIND THE SCENES /etc/environment and /etc/default/locale) that will allow applications to perform the required authentications against the LDAP database.
The LDAP module for PAM is provided by the libpam-ldap package. Installing this package asks a few questions very similar to those in libnss-ldap; some configuration parameters (such as the URI for the LDAP server) are even actually shared with the libnss-ldap package. Answers are summarized in Table 11.3.

Table 11.3. Configuration of libpam-ldap

Question Answer
Allow LDAP admin account to behave like local root? Yes. This allows using the usual passwd command for changing passwords stored in the LDAP database.
Does the LDAP database require logging in? no 
LDAP account for root cn=admin,dc=falcot,dc=com
LDAP root account password the LDAP database administrative password

Installing libpam-ldap automatically adapts the default PAM configuration defined in the /etc/pam.d/common-auth, /etc/pam.d/common-password and /etc/pam.d/common-account files. This mechanism uses the dedicated pam-auth-update tool (provided by the libpam-runtime package). This tool can also be run by the administrator should they wish to enable or disable PAM modules.

11.7.3.3. Securing LDAP Data Exchanges

By default, the LDAP protocol transits on the network as cleartext; this includes the (encrypted) passwords. Since the encrypted passwords can be extracted from the network, they can be vulnerable to dictionary-type attacks. This can be avoided by using an extra encryption layer; enabling this layer is the topic of this section.
11.7.3.3.1. Configuring the Server
The first step is to create a key pair (comprising a public key and a private key) for the LDAP server. This necessitates installing the openssl package. Running /usr/lib/ssl/misc/CA.pl -newcert asks a few mundane questions (location, organization name and so on). The answer to the “common name” question must be the fully-qualified hostname for the LDAP server; in our case, ldap.falcot.com.
This command creates a certificate in the newcert.pem file; the corresponding private key is stored in newkey.pem.
Now these keys have to be installed in their standard location:
# mv newkey.pem /etc/ssl/private/ldap-key.pem
# chmod 0600 /etc/ssl/private/ldap-key.pem
# mv newcert.pem /etc/ssl/certs/ldap-cert.pem
The slapd daemon also needs to be told to use these keys for encryption; this involves adding the following directives to the /etc/ldap/slapd.conf file:

Example 11.32. Configuring slapd for encryption

# TLS support
TLSCipherSuite HIGH
TLSCertificateFile /etc/ssl/certs/ldap-cert.pem
TLSCertificateKeyFile /etc/ssl/private/ldap-key.pem

The last step for enabling encryption involves changing the SLAPD_SERVICES variable in the /etc/default/slapd file. We'll play it safe and disable unsecured LDAP altogether.

Example 11.33. The /etc/default/slapd file

# Default location of the slapd.conf file
SLAPD_CONF=

# System account to run the slapd server under. If empty the server
# will run as root.
SLAPD_USER=

# System group to run the slapd server under. If empty the server will
# run in the primary group of its user.
SLAPD_GROUP=

# Path to the pid file of the slapd server. If not set the init.d script
# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.conf)
SLAPD_PIDFILE=

# Configure if the slurpd daemon should be started. Possible values:
# - yes:   Always start slurpd
# - no:    Never start slurpd
# - auto:  Start slurpd if a replica option is found in slapd.conf
# (default)
SLURPD_START=auto

# slapd normally serves ldap only on all TCP-ports 389. slapd can also
# service requests on TCP-port 636 (ldaps) and requests via unix
# sockets.
# Example usage:
SLAPD_SERVICES="ldaps:/// ldapi:///"

# Additional options to pass to slapd and slurpd
SLAPD_OPTIONS=""
SLURPD_OPTIONS=""

11.7.3.3.2. Configuring the Client
On the client side, the configuration for the libpam-ldap and libnss-ldap modules needs to be modified by adding the ssl on directive to the /etc/pam_ldap.conf and /etc/libnss-ldap.conf configuration files.
LDAP clients also need to be able to authenticate the server by knowing its public key. This requires installing a copy of the key (for instance as /etc/ssl/certs/ldap-cert.pem), and reference the location of this copy in the /etc/ldap/ldap.conf file.

Example 11.34. The /etc/ldap/ldap.conf file

#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

BASE   dc=falcot,dc=com
URI    ldaps://ldap.falcot.com

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

TLS_CACERT /etc/ssl/certs/ldap-cert.pem

This chapter sampled only a fraction of the available server software; however, most of the common network services were described. Now it is time for an even more technical chapter: we'll go into deeper detail for some concepts, describe massive deployments and virtualization.