Chapter 27 Lightweight Directory Access Protocol (LDAP) – Linux Administration: A Beginner's Guide, Eighth Edition, 8th Edition

CHAPTER

27

Lightweight Directory Access Protocol (LDAP)

The Lightweight Directory Access Protocol (LDAP) has been referred to as many things, including “the best thing since sliced bread.” However, it is actually a set of open protocols used to access, query, and modify centrally stored information over a network. LDAP is based on the X.500 standard (X.500 is an International Organization for Standardization [ISO] standard that defines an overall model for distributed directory services) but is a more lightweight version of the original standard. RFC 4511 explains the relationship like so: “LDAP provides access to distributed directory services that act in accordance with X.500 data and service models.”

LDAP was developed by the University of Michigan in 1992 as a lightweight alternative to the Directory Access Protocol (DAP). LDAP itself does not define the directory service. It instead defines the transport and format of messages used by a client to access and maintain data in a directory (such as the X.500 directory). LDAP is extensible, relatively easy to implement, and based on an open standard. This chapter provides an introduction to the world of directory services, as implemented by OpenLDAP. Essential concepts governing the architecture and use of LDAP will be covered.

LDAP Basics

LDAP is a protocol for accessing a specially tailored database that is used for a variety of things, such as directory service. This directory is like a database of sorts and can be used to store all kinds of information. But unlike traditional databases, an LDAP database is especially suited for read, search, and browse operations instead of write operations. It is with reads that LDAP shines!

Some popular LDAP implementations are OpenLDAP suite, Microsoft Active Directory, 389 Directory Server, IBM Security Directory Server, and NetIQ eDirectory.

NOTE  If we wanted to be pedantic, we would point out that some of these implementations are not pure/strict LDAP implementations because they don’t strictly adhere to the LDAP standard, are missing parts of the LDAP schema, or simply have too many customizations.

LDAP Directory

Just as in the popular Domain Name System (DNS), the directory entries in LDAP are arranged in a hierarchical tree structure. As in most hierarchical structures, the further you go down the tree, the more precise the content stored therein. The hierarchical tree structure of LDAP is known formally as the directory information tree (DIT). The top of the directory hierarchy has a root element. The complete path to any node in the tree structure, which uniquely identifies it, is known as the distinguished name (DN) of the node or object.

Again, just as in DNS, the structure of an LDAP directory can reflect geographic and/or organizational boundaries. Geographic boundaries can be along country lines, state lines, city lines, or the like. Organizational boundaries can, for example, be along functional lines, departmental lines, or organizational units (OUs).

For example, suppose a company named Example, Inc., decides to structure its directory tree using a domain-based naming structure. This company has different subdivisions (OUs), such as the Engineering department, the Sales department, and the R&D department. The LDAP directory tree of the company is illustrated in Figure 27-1.

Figure 27-1   LDAP tree for example.org

Here’s the DN of a sample object in the directory tree shown in the figure:

Client/Server Model

As with most network services, LDAP adheres to the usual client/server paradigm. A typical interaction between the client and the server goes like this:

1.   An LDAP client application connects to an LDAP server. This process is also referred to as “binding to a server.”

2.   Based on the access restrictions configured on the server, the LDAP server either accepts or refuses the bind/connection request.

3.   Assuming the server accepts, the client has the choice of querying the directory server, browsing the information stored on the server, or attempting to modify/update the information on the LDAP server.

4.   Again, based on access restrictions, the server can allow or deny any of the operations attempted by the client. In the event that the server cannot answer a request, it may forward or refer the client to another upstream LDAP server that may have a more authoritative response to the request.

Uses of LDAP

LDAP is a distributed directory service and can be used as storage for various types of information. Just about any kind of information can be stored in an LDAP directory—information as varied in nature as plain textual information, images, binary data, public key certificates, and so on. Over time, various LDAP schemas have been created to allow the storage of different data sources in an LDAP directory. Here are some example uses for LDAP:

•   LDAP can serve as a complete identity management solution for an organization. It can provide authentication and authorization services for users.

•   The information stored in DNS records can be stored in LDAP.

•   LDAP can be used to provide “yellow pages” services for an organization (for instance, employees’ contact information—phone numbers, addresses, departments, and so on).

•   Mail routing information can be stored in LDAP.

•   A Samba schema exists that allows a Samba server to store extensive object attributes in LDAP. This allows Samba to function as a drop-in replacement for Microsoft Windows domain controllers in environments where redundancy and replication are needed.

LDAP Terminology

If you are going to master LDAP-speak, you might as well know the essential LDAP technical jargon. This section defines some terms and explains some concepts that you will often encounter when dealing with LDAP.

•   Entry (or object)   One unit in an LDAP directory. Each entry is qualified by its distinguished name (DN). Here’s an example:

•   Attributes   These are pieces of information associated with an entry, such as an organization’s address or employees’ phone numbers.

•   objectClass   This is a special type of attribute. All objects in LDAP must have an objectClass attribute. The objectClass definition specifies which attributes are required for each LDAP object, and it specifies the object classes of an entry. The values of this attribute may be modified by clients, but the objectClass attribute itself cannot be removed. The objectClass definitions are themselves stored in schema files.

•   Schema   A collection of rules that determines the structure and contents of the directory. The schema contains the attribute type definitions, objectClass definitions, and other information. The schema lists the attributes of each object type and whether these attributes are required or optional. Schemas are usually stored in plain-text files.

Following are a few examples of schemas:

•   core.schema   Defines the basic LDAPv3 attributes and objects. It is a required core schema in the OpenLDAP implementation.

•   inetorgperson.schema   Defines the inetOrgPerson object class and its associated attributes. This object can be used to store contact information.

•   LDIF   This stands for LDAP Data Interchange Format. It is a plain-text file for LDAP entries. Files used for importing or exporting data to and from an LDAP server should be in this format. The data used for replication among LDAP servers is also in this format.

OpenLDAP

OpenLDAP is the open source implementation of LDAP that runs on Linux/UNIX systems. OpenLDAP is a suite of programs, made up of slapd, slurpd, various utilities, and libraries, that implements the LDAP protocol along with various client- and server-side utilities.

Server-Side Daemons

The server side consists of two main daemons:

•   slapd   This is a stand-alone LDAP daemon that listens for LDAP connections from clients and responds to the LDAP operations it receives over those connections.

•   slurpd   This is a stand-alone LDAP replication daemon that is used to propagate changes from one slapd database to another. This daemon is used for synchronizing changes from one LDAP server to another. It is useful when more than one LDAP server is in use.

OpenLDAP Utilities

The OpenLDAP utilities are a set of command-line programs used for querying, viewing, updating, and modifying the data stored in the OpenLDAP directory. Some of the programs are listed and described in Table 27-1.

Table 27-1   OpenLDAP Utilities

Installing OpenLDAP

To get the OpenLDAP server and client components up and running, these packages are required on Fedora, RHEL, and CentOS systems:

•   openldap-2*.rpm   Provides the configuration files and libraries for OpenLDAP.

•   openldap-clients*.rpm   Provides the client programs needed for accessing and modifying OpenLDAP directories. This is only needed on the client side!

•   openldap-servers*.rpm   Provides the servers (slapd, slurpd) and other utilities necessary to configure and run LDAP.

We will use the dnf package manager to download and install the openldap-servers package on our sample Fedora server. The steps are listed here:

1.   While logged in as root, first confirm which of the packages you already have installed by querying the RPM database:

NOTE  The operating system installation process of most Linux distributions will automatically include the base OpenLDAP software as a part of the minimum software installed. This is done so that the system can be configured as an LDAP client from the get-go without any additional hassle.

2.   Predictably, our sample system already has the basic openldap libraries in place, so we will go ahead and install the OpenLDAP client and server packages using dnf:

Once the installation completes successfully, you can go on to the configuration section.

Configuring OpenLDAP

Depending on what you want to do with your directory, configuring your directory server can be a real pain or it can be a simple process. Setting up your directory is usually easy if you are working on a brand-new deployment, where you don’t have to worry about any legacy issues, existing users or data, and similar issues. For environments with existing infrastructure, extra precautionary measures have to be taken.

CAUTION  If you are deploying LDAP in an environment where you need to be concerned about backward-compatibility issues, legacy architectures, existing users, or existing data, you are advised to approach your OpenLDAP rollout with great caution. This can take months of planning (and will involve pain and suffering, according to this book’s technical editor, David Lane) in some situations. The planning should include extensive testing and actual staging of the current environment on test systems.

Another important factor to consider when configuring your LDAP directory service is the structure of the directory. For example, before proceeding, you should have answers to the following questions: What are the organizational divisions in your establishment? Along what boundaries will the structure be built? How sensitive is the information you want to store in the directory? Will more than one LDAP server be required?

Configuring slapd

The slapd.conf file is the configuration file for the slapd daemon. On Fedora and other Red Hat–like distros, the full path to the file is /etc/openldap/slapd.conf. In this section, we will dissect the default configuration file that comes with our Fedora server and discuss some of its interesting sections.

NOTE  On Debian-like distros, the configuration file for slapd is located at /etc/ldap/slapd.conf.

Following is a truncated version of a slapd.conf file. Note that we’ve kept the comments in the file to a minimum and have eliminated the configuration directives that we don’t need to address here. Only the stripped-down version of the file that is relevant to our current discussion is displayed. Line numbers have been added to aid readability.

Here are some items to note from the preceding listing:

•   Lines 1–3 are comment entries. Any text after the pound sign (#) is a comment.

•   Lines 4–7 are include statements. These include statements are used to instruct slapd to read additional configuration information from the files specified. In this case, the additional files being pulled in are the specified OpenLDAP schema files stored under the /etc/openldap/schema/ directory. At a minimum, the core.schema file must be present.

•   In line 9, the pidfile directive points to the path of the file that will hold slapd’s process ID.

•   In line 10, the argsfile directive is used for specifying the path to a file that can be used to store command-line options used for starting slapd.

•   In line 11, the database option marks the beginning of a new database instance definition. The value of this option depends on the back-end that will be used to hold the database. In our sample slapd.conf file, bdb (Berkeley DB) is used as the database type. Examples of other supported database back-end types are null, sql, passwd, and meta. Some database back-ends are described further in Table 27-2.

Table 27-2   OpenLDAP Database Back-Ends

•   In line 12, the suffix directive specifies the DN suffix of queries that will be passed to this particular database back-end. It defines the domain for which the LDAP server provides information or for which the LDAP server is authoritative. This entry should be changed to reflect your organization’s naming structure.

•   In line 13, the rootdn directive specifies the DN of the superuser for the LDAP directory. This user is to the LDAP directory what the root superuser is to a Linux system. The user specified here is not subject to any access controls or administrative restrictions for operations on the database in question. The DN specified here need not exist in the directory.

•   In line 17, the rootpw directive specifies the password for the DN specified by the rootdn directive. Naturally, a very strong/good password should be used here. The password can be specified in plain text (very, very bad idea), or the hash of the password can be specified. The slappasswd program can be used to generate password hashes.

•   Finally, in line 22, the directory directive specifies the path to the BDB files containing the database and associated indices.

Having gone through a few important directives in the slapd.conf file, we will now make a few changes to the file to customize it for our environment. But before starting, we’ll use the venerable openssl utility to generate and make use of a self-signed certificate to help secure all communications between the LDAP server and any LDAP clients (sssd, nslcd, ldap client utilities, and so on).

NOTE  We’ve bundled working copies of the configuration and/or script files used in this chapter at the following URL to save you some typing: http://linuxserverexperts.com/8e/chapter-27.tar.xz

To follow along using this bundle, just download the file, extract its contents, and copy the file(s) to the proper directories on your local system.

1.   As a privileged user, use the openssl utility to generate a self-contained self-signed certificate. The resulting file will be stored in /etc/openldap/server.pem.

2.   If it exists, make a backup of the current slapd.conf file by renaming it (so that you can always revert back to it in case of mistakes):

3.   Move the existing slapd configuration directory (/etc/openldap/slapd.d/) out of the way and create a new one:

4.   Use any text editor to create a new /etc/openldap/slapd.conf file with the following:

5.   Save your changes to the file and exit the editor.

6.   Use the slaptest command to convert the slapd.conf file that you created earlier into the new openldap configuration format:

7.   The resulting slapd daemon’s configuration should be owned by the system user named ldap. Use the chown and chmod commands to ensure that the configuration files have the correct ownership and permissions:

TIP  Watch out for the permissions of the OpenLDAP configuration files! The slapd daemon will refuse to start on a Fedora or RHEL system if the LDAP user cannot read the configuration file(s). Also, the contents of the database directory (/var/lib/ldap) must be owned by the user ldap to avoid odd errors.

Starting and Stopping slapd

After setting up slapd’s configuration file, our next step will be to start the daemon. Starting it on systemd-enabled systems is easy. We’ll use the systemctl command to first check the status of the daemon:

If the output of the previous command shows that the daemon is not currently running, start it with this command:

And if you find that the LDAP service is already running, you can instead issue the systemctl command with the restart option, like so:

TIP  On some Linux distros, you may get a warning message about DB_CONFIG not existing under the /var/lib/ldap directory whenever you start the LDAP service. You can fix this warning by using the sample DB_CONFIG file that ships with the distribution. The sample file is stored under /etc/openldap/ or /usr/share/openldap-servers/, and here’s the command to copy and rename the file:

On systemd-enabled systems, if you want the slapd service to start up automatically with the next system reboot, type this:

Besides the basic service/daemon admin tasks (configuration, enabling, starting, stopping, and so on), another important task involved with getting your LDAP server (slapd) ready to serve clients on the network is to make sure the service port for the service is reachable through any relevant host-based or network-based firewalls.

Red Hat–based distros such as Fedora often ship with host-based firewall rules that protect the system and its services/daemons. You can use a predefined firewalld service definition on Fedora to permanently open up the port for the LDAP service by executing the following commands:

Configuring OpenLDAP Clients

The notion of clients takes some getting used to in the LDAP world. Almost any system resource or process can be an LDAP client. And, fortunately or unfortunately, each group of clients may have its own specific configuration files. The configuration files for OpenLDAP clients are generally named ldap.conf, but they may be stored in different directories, depending on the particular client in question.

Depending on the distro, some common locations for the OpenLDAP client configuration files are under these directories: /etc/openldap/, /etc/ldap, and /etc/. The client applications that use the OpenLDAP libraries (provided by the openldap*.rpm package)—applications such as ldapadd, ldapsearch—consult the /etc/openldap/ldap.conf file, if it exists. The nss_ldap libraries instead use the /etc/ldap.conf file as their configuration file.

In this section, we will set up the configuration file for the OpenLDAP client tools. This configuration file is straightforward; we will be changing only a few of its directives.

Open the /etc/openldap/ldap.conf file in any text editor, and make sure that the following configuration directives are set to the appropriate values shown next. You should create the entries if they don’t exist already in the file.

TIP  One particular variable/directive that you might need to change in the /etc/openldap/ldap.conf file, if you are using the client tools from a host other than the LDAP server itself, is the URI directive. This should be set to the IP address of the remote LDAP server. But because we are using the LDAP clients directly on the LDAP server itself, a URI directive of ldaps://localhost will suffice in our example.

Creating Directory Entries

The LDAP Data Interchange Format (LDIF) is used to represent entries in an LDAP directory in textual form. As stated earlier, data in LDAP is presented and exchanged in this format. The data in an LDIF file can be used to manipulate, add, remove, and change the information stored in the LDAP directory. Here’s the format for an LDIF entry:

The LDIF file is slightly strict in its format. You should keep these points in mind:

•   Multiple entries within the same LDIF file are separated by blank lines.

•   Entries that begin with the pound sign (#) are regarded as comments and are ignored.

•   An entry that spans more than one line can be continued on the next line by starting the next line with a single space or tab character.

•   The space following the colon (:) is important for each entry.

In this section, we will use a sample LDIF file to populate our new directory with basic information to set up our directory information tree, as well as with information describing two users, named bogus and testuser.

1.   The sample LDIF file is presented next. Use any text editor to input the text in the listing into the file. Be careful with the white spaces and tabs in the file, and make sure you maintain a newline after each DN entry, as shown in our sample file.

2.   Save the file as sample.ldif and then exit your text editor.

3.   Use the ldapadd utility to import the sample.ldif file into the OpenLDAP directory:

These are the parameters used in this ldapadd command:

•   -x   Indicates that simple authentication should be used instead of Simple Authentication and Security Layer (SASL).

•   -D   Specifies the distinguished name with which to bind to the LDAP directory (that is, the binddn parameter specified in the slapd.conf file).

•   -w   Allows the user to be prompted for the simple authentication password instead of specifying the password in plain text on the command line.

•   -f   Specifies the file from which to read the LDIF file.

4.   Enter the password you created using the slappasswd utility earlier—that is, the password that was specified in the /etc/openldap/slapd.conf file for the rootpw directive (line 12: slappasswd -s test). We used “test” as the password in our example.

We are done populating the directory!

Searching, Querying, and Modifying the Directory

We’ll use a couple of OpenLDAP client utilities to retrieve information from our directory.

1.   We’ll use the ldapsearch utility to search for and retrieve every entry in the database directory:

2.   Let’s repeat the search again, but without specifying the -b option and also making the output less verbose:

Here, we didn’t need to specify explicitly the basedn to search because that information is already defined in our /etc/openldap/ldap.conf file.

3.   We’ll narrow down our query by searching only for the entry for the object whose common name (cn) is equal to bogus. Issue this command:

4.   We’ll attempt to perform a privileged operation on a directory entry using the ldapdelete utility. Let’s delete the entry for the object with the DN of cn=bogus,dc=example,dc=org. Issue this command:

Enter the password for the cn=Manager,dc=example,dc=org DN to complete the operation.

5.   Use ldapsearch again to make sure the entry has indeed been removed:

This command should return nothing.

Using OpenLDAP for User Authentication

Now we’ll set up the OpenLDAP server (and client) that we configured earlier in the chapter to manage Linux user accounts. We will be using some of the migration scripts that come with the software to pull/migrate the users that already exist in the system’s /etc/passwd file into LDAP.

Configuring the Server

Setting up a Linux system to use LDAP as the storage back-end for user account information is easy once you have taken care of all the other basic OpenLDAP configuration tasks.

On mainstream Linux distros, a bunch of useful scripts exists in a package called migrationtools* that can help with the migration of information (such as users, groups, aliases, hosts, netgroups, and services) in existing name services into an OpenLDAP directory. These scripts are often stored under /usr/share/migrationtools/.

On our Fedora server, we’ll customize the migrate_common.ph file to suit our particular setup, but first we need to install the package that provides the script:

1.   Start by installing the package that provides the migration scripts we will be using:

Among other things, this command will install the file under /usr/share/migrationtools/migrate_common.ph.

2.   Open the file for editing and look for lines/entries similar to these:

We will change these variables to read like so:

3.   We’ll use another one of the migration scripts (migrate_base.pl) to create the base structure for our directory:

4.   Now execute the script:

This command will create a file named base.ldif under your home directory.

5.   Make sure slapd is running (via systemctl start slapd) and then import the entries in the base.ldif file into the OpenLDAP directory:

6.   Now we need to export the current users in the system’s /etc/passwd file into an LDIF-type file. We will use the /usr/share/migrationtools/migrate_passwd.pl script:

7.   We can begin importing all the user entries in the ldap-users.ldif file into our OpenLDAP database. For this, we will use the ldapadd command:

Enter the rootdn’s password (test) when prompted.

Configuring the Client

Configuring a client system to use an LDAP directory for user authentication is as easy as pie on a Fedora, RHEL, or CentOS system. Most distros have command-line utilities as well as distro-specific GUI tools that make it easy. We’ll use the authselect utility on our Fedora system here.

1.   Make sure the authselect package is installed by running the following:

2.   Display the current and active system identity and authentication source:

The output shows that the System Security Services Daemon (sssd) profile is currently being used. Next, we’ll configure a new service domain called newldap to use with sssd.

3.   As a privileged user, create (or overwrite) the /etc/sssd/sssd.conf (chmode 400) configuration file with the following content. We’ll use Bash’s Heredoc to do this.

4.   Set the proper permissions on sssd.conf and then ensure that the system is using the sssd profile:

5.   Apply the changes to sssd:

6.   Restart the sssd service unit:

7.   You use the syntax “<username@newldap>” to quickly test that the system can use the supplied LDAP server to provide authentication/authorization services to the client. For example, use the id command to query the LDAP server for info about the user yyang stored in LDAP:

That’s it. You are done.

We just described a simple way to enable a Fedora client system to use an OpenLDAP server for its user authentication. We did not bother with a lot of details, because this is just a proof of concept. Following are some of the details you might have to deal with in a real production environment:

•   Home directories   Ensure that users’ home directories are available to them when they’re logging in from any system. One way to do this is by sharing user home directories via Network File System (NFS) and exporting the share to all client systems.

•   Security   Our sample setup did not use any super-secure measures; for example, we used and blindly trusted our self-signed TLS/SSL certificates! This should be of paramount importance in a production environment so that user passwords do not go flying across the network in plain text.

•   Miscellaneous   Other issues weren’t addressed here, but we’ll leave those as a mental exercise for you to stumble upon and ponder.

TIP  Take a look at the FreeIPA project (www.freeipa.org) for a canned identity management solution that combines and extends various concepts and solutions discussed in this and other chapters.

Summary

This chapter covered some LDAP basics. It concentrated mostly on the open source implementation of LDAP known as OpenLDAP. You learned about the components of OpenLDAP—the server-side daemons and the client-side utilities used for querying and modifying the information stored in an LDAP directory. We created a simple directory and populated it with some sample entries.

Finally, we configured our LDAP server to store user and password information for users in its directory. This makes it possible for remote LDAP clients to consult the LDAP server for their own user authentication needs.

We’ve barely scratched the surface of the topic, but LDAP is too large a topic to be covered fully in a single chapter. Hopefully, we’ve whetted your appetite and got you started in the right direction with some essential concepts and ideas.