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,
supports the use of SSL/TLS to secure the entire communication link
between client and server, including the authentication process.
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:
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.
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
Start the slapd daemon. A typical
slapd command line looks like this:
# /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/"
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.
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:
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. 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.
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
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
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+).
|