11.7. LDAP Directory

OpenLDAP is an implementation of the LDAP protocol; in other words, it is 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. 安装

The slapd package contains the OpenLDAP server. The ldap-utils package includes command-line tools for interacting with LDAP servers.

Installing slapd usually asks only for the administrator’s password and the resulting database is unlikely to suit your needs. Fortunately a simple dpkg-reconfigure slapd will let you reconfigure the LDAP database with more details:

  • 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: “MDB”.

  • 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.

BACK TO BASICS LDIF format

An LDIF file (LDAP Data Interchange Format) is a portable text file describing the contents of an LDAP database (or a portion thereof); this can then be used to inject the data into any other LDAP server.

A minimal database is now configured, as demonstrated by the following query:

  1. $

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 are 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), and DEFAULT_MAIL_DOMAIN/DEFAULT_BASE need to be updated.

The actual migration operation is handled by the migrate_all_online.sh command, as follows:

  1. #

The migrate_all_online.sh asks a few questions about the LDAP database into which the data is to be migrated. 表 11.1 summarizes the answers given in the Falcot use-case.

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

QuestionAnswer
X.500 naming contextdc=falcot,dc=com
LDAP server hostnamelocalhost
Manager DNcn=admin,dc=falcot,dc=com
Bind credentialsthe administrative password
Create DUAConfigProfileno

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.

TOOL Browsing an LDAP directory

The jxplorer command (in the package of the same name) is a graphical tool allowing to browse and edit an LDAP database. It is an interesting tool that provides an administrator with a good overview of the hierarchical structure of the LDAP data.

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 下一步 NSS 与系统数据库) 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 表 11.2.

表 11.2. Configuring the libnss-ldap package

QuestionAnswer
LDAP server Uniform Resource Identifierldapi://ldap.falcot.com
Distinguished name of the search basedc=falcot,dc=com
LDAP version to use3
LDAP account for rootcn=admin,dc=falcot,dc=com
LDAP root account passwordthe administrative password
Allow LDAP admin account behave like local root?yes
Does the LDAP database require login?no

The /etc/nsswitch.conf file then needs to be modified, so as to configure NSS to use the freshly-installed ldap module. You can use the example provided in /usr/share/doc/libnss-ldap/examples/nsswitch.ldap or edit your existing configuration.

例 11.23. The /etc/nsswitch.conf file

  1. #ident $Id: nsswitch.ldap,v 2.4 2003/10/02 02:36:25 lukeh Exp $
  2. #
  3. # An example file that could be copied over to /etc/nsswitch.conf; it
  4. # uses LDAP conjunction with files.
  5. #
  6. # "hosts:" and "services:" in this file are used only if the
  7. # /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports.
  8.  
  9. # the following lines obviate the "+" entry in /etc/passwd and /etc/group.
  10. passwd: files ldap
  11. shadow: files ldap
  12. group: files ldap
  13.  
  14. # consult DNS first, we will need it to resolve the LDAP host. (If we
  15. # can't resolve it, we're in infinite recursion, because libldap calls
  16. # gethostbyname(). Careful!)
  17. hosts: dns ldap
  18.  
  19. # LDAP is nominally authoritative for the following maps.
  20. services: ldap [NOTFOUND=return] files
  21. networks: ldap [NOTFOUND=return] files
  22. protocols: ldap [NOTFOUND=return] files
  23. rpc: ldap [NOTFOUND=return] files
  24. ethers: ldap [NOTFOUND=return] files
  25.  
  26. # no support for netmasks, bootparams, publickey yet.
  27. netmasks: files
  28. bootparams: files
  29. publickey: files
  30. automount: files
  31.  
  32. # I'm pretty sure nsswitch.conf is consulted directly by sendmail,
  33. # here, so we can't do much here. Instead, use bbense's LDAP
  34. # rules ofr sendmail.
  35. aliases: files
  36. sendmailvars: files
  37.  
  38. # Note: there is no support for netgroups on Solaris (yet)
  39. netgroup: ldap [NOTFOUND=return] files
  40.  
  41.  

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.

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 幕后/etc/environment/etc/default/locale) that will allow applications to perform the required authentications against the LDAP database.

CAUTION Broken authentication

Changing the standard PAM configuration used by various programs is a sensitive operation. A mistake can lead to broken authentication, which could prevent logging in. Keeping a root shell open is therefore a good precaution. If configuration errors occur, they can be then fixed and the services restarted with minimal effort.

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 表 11.3.

表 11.3. Configuration of libpam-ldap

QuestionAnswer
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 rootcn=admin,dc=falcot,dc=com
LDAP root account passwordthe LDAP database administrative password
Local encryption algorithm to use for passwordscrypt

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. 配置服务器

The first step is to create a key pair (comprising a public key and a private key) for the LDAP server. The Falcot administrators reuse easy-rsa to generate it (see 第 10.2.2 节 “公钥基础设施:easy-rsa). Running ./easyrsa build-server-full ldap.falcot.com nopass will ask you about the “common name”. The answer to that question must be the fully-qualified hostname for the LDAP server; in our case, ldap.falcot.com.

This command creates a certificate in the pki/issued/ldap.falcot.com.crt file; the corresponding private key is stored in pki/private/ldap.falcot.com.key.

Now these keys have to be installed in their standard location, and we must make sure that the private file is readable by the LDAP server which runs under the openldap user identity:

  1. #

The slapd daemon also needs to be told to use these keys for encryption. The LDAP server configuration is managed dynamically: the configuration can be updated with normal LDAP operations on the cn=config object hierarchy, and the server updates /etc/ldap/slapd.d in real time to make the configuration persistent. ldapmodify is thus the right tool to update the configuration:

例 11.24. Configuring slapd for encryption

  1. #

TOOL ldapvi to edit an LDAP directory

With ldapvi, you can display an LDIF output of any part of the LDAP directory, make some changes in the text editor, and let the tool do the corresponding LDAP operations for you.

It is thus a convenient way to update the configuration of the LDAP server, simply by editing the cn=config hierarchy.

  1. #

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.

例 11.25. The /etc/default/slapd file

  1. # Default location of the slapd.conf file or slapd.d cn=config directory. If
  2. # empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to
  3. # /etc/ldap/slapd.conf).
  4. SLAPD_CONF=
  5.  
  6. # System account to run the slapd server under. If empty the server
  7. # will run as root.
  8. SLAPD_USER="openldap"
  9.  
  10. # System group to run the slapd server under. If empty the server will
  11. # run in the primary group of its user.
  12. SLAPD_GROUP="openldap"
  13.  
  14. # Path to the pid file of the slapd server. If not set the init.d script
  15. # will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.conf by
  16. # default)
  17. SLAPD_PIDFILE=
  18.  
  19. # slapd normally serves ldap only on all TCP-ports 389. slapd can also
  20. # service requests on TCP-port 636 (ldaps) and requests via unix
  21. # sockets.
  22. # Example usage:
  23. # SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
  24. SLAPD_SERVICES="ldaps:/// ldapi:///"
  25.  
  26. # If SLAPD_NO_START is set, the init script will not start or restart
  27. # slapd (but stop will still work). Uncomment this if you are
  28. # starting slapd via some other means or if you don't want slapd normally
  29. # started at boot.
  30. #SLAPD_NO_START=1
  31.  
  32. # If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,
  33. # the init script will not start or restart slapd (but stop will still
  34. # work). Use this for temporarily disabling startup of slapd (when doing
  35. # maintenance, for example, or through a configuration management system)
  36. # when you don't want to edit a configuration file.
  37. SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
  38.  
  39. # For Kerberos authentication (via SASL), slapd by default uses the system
  40. # keytab file (/etc/krb5.keytab). To use a different keytab file,
  41. # uncomment this line and change the path.
  42. #export KRB5_KTNAME=/etc/krb5.keytab
  43.  
  44. # Additional options to pass to slapd
  45. SLAPD_OPTIONS=""
  46.  
11.7.3.3.2. 设置客户端

On the client side, the configuration for the libpam-ldap and libnss-ldap modules needs to be modified to use an ldaps:// URI.

LDAP clients also need to be able to authenticate the server. In a X.509 public key infrastructure, public certificates are signed by the key of a certificate authority (CA). With easy-rsa, the Falcot administrators have created their own CA and they now need to configure the system to trust the signatures of Falcot’s CA. This can be done by putting the CA certificate in /usr/local/share/ca-certificates and running update-ca-certificates.

  1. #

Last but not least, the default LDAP URI and default base DN used by the various command line tools can be modified in /etc/ldap/ldap.conf. This will save quite some typing.

例 11.26. The /etc/ldap/ldap.conf file

  1. #
  2. # LDAP Defaults
  3. #
  4.  
  5. # See ldap.conf(5) for details
  6. # This file should be world readable but not world writable.
  7.  
  8. BASE dc=falcot,dc=com
  9. URI ldaps://ldap.falcot.com
  10.  
  11. #SIZELIMIT 12
  12. #TIMELIMIT 15
  13. #DEREF never
  14.  
  15. # TLS certificates (needed for GnuTLS)
  16. TLS_CACERT /etc/ssl/certs/ca-certificates.crt