6.6 LDAP: Using a Directory Service for User Authentication


For several years now, every time anyone put together a list of hot system administration topics, LDAP was sure to be near the top. Many sites are beginning to use LDAP for storing employee information, including user account information, and as a means for performing enterprise-wide user authentication. In this way, LDAP-based account data and authentication can replace separate, per-system logins and network-based authentication schemes like NIS.

In this closing section of the chapter, we'll take a brief look at LDAP and specifically, the OpenLDAP environment and consider how it may be used for user authentication.

6.6.1 About LDAP

LDAP, as its fully expanded name Lightweight Directory Access Protocol indicates, is a protocol that supports a directory service. The best analogy for a directory service is the phone company's directory assistance. Directory assistance is a mechanism for customers to find information that they need quickly. Traditionally, human operators provided the (hopefully friendly) interface between the user (customer) and the database (the list of phone numbers). Directory assistance is not a means for customers to change their phone number, indicate whether their phone number should be listed or unlisted, or to obtain new telephone service.

A computer-based directory service provides similar functionality. It is a database and means of accessing information within it. Specifically, the directory service database has several specific characteristics that are different from, say, databases used for transaction processing:

  • It is optimized for reading (writing may be expensive).

  • It provides advanced searching features.

  • Its fundamental data structures collectively known as the schema can be extended according to local needs.

  • It adheres to published standards to ensure interoperability among vendor implementations (specifically, a boatload of RFCs).

  • It takes advantage of distributed storage and data-replication techniques.

LDAP's roots are in the X.500 directory service and its DAP protocol. LDAP was designed to be a simpler and more efficient protocol for accessing an X.500 directory. It is "lightweight" in several ways: LDAP runs over the TCP/IP network stack (instead of DAP's full implementation of all seven OSI layers), it provides only the most important small subset of X.500 operations, and data is formatted as simple strings rather than complex data structures. Like DAP itself, LDAP is an access protocol. The actual database services are provided by some other facility, often referred to as the back end. LDAP serves a means for efficiently accessing the information stored within it.

In order to emphasize these differences with respect to standard relational databases, different terminology is used for the data stored in a directory. Records are referred to as entries, and fields with a record are called attributes.

LDAP was first implemented at the University of Michigan in the early 1990s. There are many commercial LDAP servers available. In addition, OpenLDAP is an open source implementation of LDAP based on the work at Michigan (http://www.openldap.org). The OpenLDAPpackage includes daemons, configuration files, startup scripts, libraries, and utilities.

These are the most important OpenLDAP components:

Daemons

slapd is the OpenLDAP daemon, and slurpd is the data replication daemon.

A database environment

OpenLDAP supports the Berkeley DB and the GNU GDBMdatabase engines.

Directory entry-related utilities

These utilities are ldapadd and ldapmodify (add/modify directory entries), ldapdelete (delete directory entries), ldapsearch (search directory for entries matching specified criteria), and ldappasswd (change entry password).

Related utilities

Related utilities include, for example, slappasswd (generate encoded passwords).

Configuration files

Configuration files are stored in /etc/openldap.

Unix versions differ in their LDAP support. Some, like Linux and FreeBSD, use OpenLDAP exclusively. Others, likeSolaris, provide only client support by default (although Solaris offers an LDAP server as an add-on facility at extra cost). Be sure to check what your version uses if you plan to use the provided facilities. Switching to OpenLDAP is also an option for all of the systems we are considering.

6.6.2 LDAP Directories

LDAP directories are logically tree structures, and they are typically rooted at a construct corresponding to the site's domain name, expressed in a format like this one:

dc=ahania,dc=com

Each component of the domain name becomes the value for a dc (domain component) attribute, and all of them are collected into a comma-separated list. This is known as the directory's base, corresponding in this case to ahania.com. Domain names with more than two components would have additional dc attributes in the list (e.g., dc=research,dc=ahania,dc=com).

Such a list of attribute=value pairs is the method for referring to any location (entry) with the directory. Spaces are not significant between items.

Let's now turn to a sample record from adirectory service database:

dn: cn=Jerry Carter, ou=MyList, dc=ahania, dc=com objectClass: person cn: Jerry Carter sn: Carter description: Samba and LDAP expert telephoneNumber: 22

This data format is known asLDIF (LDAP Data Interchange Format). It is organized as a series of attribute and value pairs (colon-separated). For example, the attribute telephoneNumber has the value 22.

The first line is special. It specifies the entry's distinguished name (dn), which functions as its unique key within the database (I like to think of it as a Borg "designation"). As expected, it is constructed as a comma-separated list of attribute-value pairs. In this case, the entry is for common name "Jerry Carter," organizational unit "MyList" in the example directory for ahania.com.

The objectClass attribute specifies the type of record: in this case, a person. Every entry needs at least one objectClass attribute. Valid record types are defined in the directory's schema, and there are a variety of standard record types that have been defined (more on this later). The other attributes in the entry specify the person's surname, description and phone number.

The first component of the dn is known as the entry's relative distinguished name (rdn). In our example, that would be cn=Jerry Carter. It corresponds to the location within the ou=MyList,dc=ahania,dc=com subtree where this entry resides. An rdn must be unique within its subtree just as the dn is unique within the entire directory.

Here is a simple representation of the directory tree in which successive (deeper) levels are indicated by indentation:

dc=ahania,dc=com     ou=MyList,dc=ahania,dc=com          cn=Jerry Carter,ou=MyList,dc=ahania,dc=com          cn=Rachel Chavez,ou=MyList,dc=ahania,dc=com          more people ...     ou=HisList,dc=ahania,dc=com           different people ...

The directory is divided into two organization units, each of which has a number of entries under it (corresponding to people).

6.6.2.1 About schemas

The schema is the name given to the collection of object and attribute definitions which define the structure of the entries (records) in an LDAP database. LDAP objects are standardized in order to provide interoperability with a variety of directory-services servers. Schema definitions are stored in files located in the /etc/openldap/schema subdirectory. The OpenLDAP package provides all of the most common standard schema, and you can add additional definitions, if necessary. You specify the files that are in use via entries in slapd.conf , as in these examples:

include         /etc/openldap/schema/core.schema include         /etc/openldap/schema/misc.schema

Object definitions in the schema files are fairly easy to understand:[20]

[20] For those of you familiar with SNMP, LDAP uses ASN.1 syntax for its schemas, and thus its object definitions somewhat resemble SNMP MIB definitions.

objectclass ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL    MUST ( sn $ cn )    MAY  ( userPassword $ telephoneNumber $ seeAlso $ description ) )

This is the definition of the person object class. The first line specifies the class name. It also indicates that it is a structural object (the other sort is an auxiliary object, which adds supplemental attributes to its parent object) and that its parent class is top (a pseudo-object indicating the top of the hierarchy). The remaining lines specify required and optional attributes for the object.

Attributes are defined in separate stanzas having an even more obscure format. For example, here is the definition of the sn (surname) attribute:

attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' ) SUP name ) attributetype ( 2.5.4.41 NAME 'name'    EQUALITY caseIgnoreMatch    SUBSTR   caseIgnoreSubstringsMatch    SYNTAX   1.3.6.1.4.1.1466.115.121.1.15{32768} )

The sn attribute draws its definition from its parent, the name attribute. Its definition specifies its syntax and how equality and substring comparisons are to be performed (themselves defined via keywords and values defined elsewhere in the schema).

In general, you can figure out what's going on with most objects by examining the relevant schema files. The website http://ldap.hklc.com provides a very convenient interface for exploring standard LDAP schema objects.

6.6.3 Installing and Configuring OpenLDAP: An Overview

InstallingOpenLDAP is not difficult, but it can be time-consuming. The first step is to obtain all of the needed software. This includes not only OpenLDAP itself, but also its prerequisites:

  • A database manager: GNU gdbm (http://www.fsf.org) or BerkeleyDB (http://www.sleepycat.com)

  • The Transport Layer Security (TLS/SSL) libraries (http://www.openssl.org)

  • The Cyrus SASL libraries (http://asg.web.cmu.edu/sasl/)

Once the prerequisites are met, we can build and install OpenLDAP. The OpenLDAP documentation for doing so is pretty good.

Once the software is installed, the next step is to create a configuration file for the slapd daemon, /etc/openldap/slapd.conf:

# /etc/openldap/slapd.conf include     /etc/openldap/schema/core.schema pidfile     /var/run/slapd.pid argsfile    /var/run/slapd.args database    ldbm suffix      "dc=ahania, dc=com"   rootdn      "cn=Manager, dc=ahania, dc=com" # encode with slappasswd -h '{MD5}' -s <password> -v -u rootpw      {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==  directory   /var/lib/ldap

Additional items may appear in your file. Change any paths that are not correct for your system, and set the correct dc components in the suffix (directory base) and rootdn (database owner) entries (Manager is the conventional common name to use for this purpose). Set a password for the root dn in the rootpw entry. This may be in plain text, or you can use the slappasswd utility to encode it.

Finally, make sure that the specified database directory exists, is owned by root, and has mode 700. The configuration file itself should also be readable only by root.

Once the configuration file is prepared, you can start slapd manually. On some systems, you can use the provided boot script, as in this example:

# /etc/init.d/ldap start

If you want the LDAP daemons to be started at boot time, you'll need to ensure that this file is run by the boot scripts.

Next, we create the first directory entries, via a text file inLDIFformat (the default LDAP text-based import and export format). For example:

# Domain entry dn: dc=ahania,dc=com objectclass: dcObject objectclass: organization o: Ahania, LLC dc: ahania.com # Manager entry dn: cn=Manager,dc=ahania,dc=com objectclass: organizationalRole cn: Manager

Use a command like this one to add the entries from the file:

# ldapadd -x -D "cn=Manager,dc=ahania,dc=com" -W -f /tmp/entry0 Enter LDAP Password:     Not echoed adding new entry "dc=ahania,dc=com" adding new entry "cn=Manager,dc=ahania,dc=com"

The -f option to ldapadd specifies the location of the prepared LDIF file. -D specifies the dn with which to connect to the server (this process is known as "binding"), and -x and -W say to use simple authentication (more about this later) and to prompt for the password, respectively.

You can verify that everything is working by running the following command to query the directory:

# ldapsearch -x -b 'dc=ahania,dc=com' -s base '(objectclass=*)' version: 2 ... # ahania,dc=com dn: dc=ahania,dc=com objectClass: dcObject objectClass: organization o: Ahania, LLC dc: ahania.com ...

This command displays the directory's base level (topmost) entry (we'll discuss the command's general syntax in a bit).

At this point, the server is ready to go to work. For more information on installing OpenLDAP, consult Section 2, "Quick Start," of the OpenLDAP 2.0 Administrator's Guide.

6.6.3.1 More about LDAP searching

The full syntax of the ldapsearchcommand is:

ldapsearch options search-criteria [attribute-list]

where options specify aspects of command functioning, search-criteria specify which entries to retrieve, and attribute-list specifies which attributes to display (the default is all of them). Search criteria are specified according to the (arcane) LDAP rules, whose simplest format is:

(attribute-name=pattern)

The pattern can include a literal value or a string containing wildcards. Thus, the criteria (objectclass=*) returns entries having any value for the objectclass attribute (i.e., all entries).

The following command illustrates some useful options and a more complex search criterion:

# ldapsearch -x -b 'dc=ahania,dc=com' -S cn  \    '(&(objectclass=person)(cn=Mike*))'  \    telephoneNumber  description  dn: cn=Mike Frisch, ou=MyList, dc=ahania, dc=com telephoneNumber: 18 description: Computational chemist dn: cn=Mike Loukides, ou=MyList, dc=ahania, dc=com telephoneNumber: 14 description: Editor and writer

The output is (considerably) shortened.

This query returned two entries. The options said to use the simple authentication scheme (-x), to start the search at the entry dc=ahania,dc=com (-b), and to sort the entries by the cn attribute (-S).

The search criteria specified that the objectclass should be person and the cn should start with "Mike" (illustrating the syntax for an AND condition). The remaining arguments selected the two attributes that should be displayed in addition to the dn.

The following command could be used to perform a similar query on a remote host:

# ldapsearch -H ldap://bella.ahania.com -x -b 'dc=ahania,dc=com' \      '(cn=Mike*)'  telephoneNumber description

The -H option species the URI for the LDAP server: bella.

The search context for LDAP clients can be preset using the ldap.conf configuration file (also in /etc/openldap). Here is an example:

# /etc/openldap/ldap.conf URI  ldap://bella.ahania.com BASE dc=ahania,dc=com

With this configuration file, the previous command could be simplified to:

# ldapsearch -x  '(cn=Mike*)'  telephoneNumber description

There are a variety of LDAP clients available to make directory-entry viewing and manipulation easier than using LDIF files and command-line utilities. Some common ones are kldap (written by Oliver Jaun, http://www.mouthpoint.ch/oliver/kldap/), gq (http://biot.com/gq/), and web2ldap (http://web2ldap.de). The gq utility is pictured in Figure 6-12 and Figure 6-13.

6.6.4 Using OpenLDAP for User Authentication

Enterprise-level user authentication is another appropriate and desirable application for an OpenLDAP-based directory service. Setting up such functionality is not difficult, but the process does require several steps.

6.6.4.1 Select an appropriate schema

You'll need to incorporate user account and related configuration information conventionally stored in files (or in the NIS facility) into the directory service. Fortunately, there are standard objects for this purpose. In the case of user accounts, the ones to use are posixAccount and shadowAccount (both defined in the nis.schema file). In addition, if you wish to place users into an organizational unit (which is the standard practice, as we'll see), then the account object is also used (defined in cosine.schema).

Accordingly, we'll add these lines to slapd.conf:

include  /etc/openldap/schema/cosine.schema include  /etc/openldap/schema/nis.schema   index    cn,uid       eq index    uidNumber    eq index    gidNumber    eq

The final three lines create indexes on the specified fields in order to speed up searches.

While you are performing this process, you may also want to enable slapd logging via this configuration file entry:

# log connection setup, searches and various stats (8+32+256) loglevel 296

The parameter specifies the desired items to be logged; it is a mask that ANDs bits for the various available items (see the OpenLDAP Administrator's Guide for a list). Specify a log level of 0 to disable logging. Log messages are sent to the syslog local4.debug facility.

Don't forget to restart slapd after editing its configuration file.

6.6.4.2 Convert existing user account data

The next step is to transfer the user account data to the directory. The easiest way to do so is to use the open source migration tools provided by PADL software (http://www.padl.org). These are a series of Perl scripts that extract the required data from its current location and create corresponding directory entries. Using them goes like this:

  • Install the scripts to a convenient location.

  • Edit the migrate_common.ph file. You will have to modify at least these entries: DEFAULT_BASE, DEFAULT_MAIL_DOMAIN, DEFAULT_MAIL_HOST, and the various sendmail-related entries (if you plan to use OpenLDAP for this purpose as well).

    You should also set EXTENDED_SCHEMA to 1 if you want the scripts to create user account entries such as person, organizationalPerson, and inetOrgPerson objects in addition to the account-related objects.

There are two ways to proceed with the migration. First, you can run a script that automatically transfers all of the information to the directory: migrate_all_online.pl is used if slapd is running, and migrate_all_offline.pl is used otherwise.

I am not brave enough to just go for it; I run the various component scripts by hand so I can examine their work before importing the resulting LDIF files. For example, this command converts the normal and shadow password files to LDIF format:

# migrate_passwd.pl  /etc/passwd  passwd.ldif

The desired output file is specified as the second parameter.

Here is an example of the conversion process in action. The script takes the following entries from /etc/passwd and /etc/shadow:

/etc/passwd
chavez:x:502:100:Rachel Chavez:/home/chavez:/bin/tcsh
/etc/shadow
chavez:zcPv/oXSSS9hJg:11457:0:99999:7:0::

It uses those entries to create the following directory entry:

dn: uid=chavez,ou=People,dc=ahania,dc=com uid: chavez cn: Rachel Chavez objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount uidNumber: 502 gidNumber: 100 gecos: Rachel Chavez  homeDirectory: /home/chavez loginShell: /bin/tcsh userPassword: {crypt}zcPv/oXSSS9hJg  shadowLastChange: 11457 shadowMax: 99999 shadowWarning: 7

If you choose this route, you will need also to run the migrate_base.pl script to create the top-level directory entries corresponding to the ous (e.g., People above) in which the scripts place the accounts (and other entities). Another advantage of this method is that you can change the ou name if you don't like it, subdivide it, or transform it in other ways, before importing.

6.6.4.3 Specify the name service search order

Now we are ready to use the directory service for user account operations. In order to do so, we will need two additional packages: nss_ldap and pam_ldap (both available from http://www.padl.com). The first of these provides an interface to the /etc/nsswitch file. The relevant lines need to be edited to add LDAP as an information source:

passwd: files ldap shadow: files ldap ...

These lines tell the operating system to look in the conventional configuration file first for user account information and then to consult the OpenLDAP server.

This module also requires some entries in the ldap.conf client configuration file. For example:

nss_base_passwd      ou=People,dc=ahania,dc=com nss_base_shadow      ou=People,dc=ahania,dc=com nss_base_group       ou=Group,dc=ahania,dc=com 

These entries specify the directory tree location of the ous holding the user account and group information.

NOTE

figs/armadillo_tip.gif

This configuration file is usually in /etc/openldap, but it is also possible to place it directly in /etc, and the latter location takes precedence. If you install the nss_ldap package manually, it will probably place an example copy in /etc. This can cause some trouble and be hard to debug when you don't know that it is there! The pam_ldap package does the same thing.

Once things are configured, you can use the following command to view user accounts:

# getent passwd

In the testing phase, you will want to migrate a few test accounts and then run this command. The migrated accounts will appear twice until you remove them from the configuration files.

6.6.4.3.1 Configure PAM to use OpenLDAP

The PAM facility (discussed previously) provides the means for interfacing the OpenLDAP directory data to the user authentication process. Accordingly, you will need the pam_ldap package to interface to OpenLDAP.

Once the package is installed, you will need to modify the files in /etc/pam.d or /etc/pam.conf to use the LDAP module (examples are provided with the package). For example, here is the modified version of the PAM configuration file for rlogin (shown in the format used by per-service PAM configuration files):

auth      required    /lib/security/pam_securetty.so auth      required    /lib/security/pam_nologin.so auth      sufficient  /lib/security/pam_rhosts_auth.so auth      sufficient  /lib/security/pam_ldap.so auth      required    /lib/security/pam_unix.so auth      required    /lib/security/pam_mail.so account   sufficient  /lib/security/pam_ldap.so account   required    /lib/security/pam_unix.so password  sufficient  /lib/security/pam_ldap.so password  required    /lib/security/pam_unix.so  strict=false session   required    /lib/security/pam_unix.so  debug 

Generally, the pam_ldap.so module is just inserted into the stack above pam_unix.so (or equivalent module).

There are also several optional PAM-related entries which may be included in ldap.conf. For example, the following ldap.conf entries restrict user access by host, based on the contents of the user's directory entry:

# Specify allowed hosts for each user  pam_check_host_attr  yes        

The following directory entry illustrates the method for granting user chavez access to a list ofhosts:

dn: uid=chavez,ou=People,dc=ahania,dc=com objectClass: account                              Parent of hos.t objectClass: posixAccount                         Unix user account. ... # List of allowed hosts          host: milton.ahania.com host: shelley.ahania.com host: yeats.ahania.com ...

Similarly, the following configuration file entries specify a list of allowed users for each host computer:

# Limit host access to the specified users pam_groupdn cn=dalton.ahania.com,dc=ahania,dc=com pam_member_attribute uniquemember

Here is the corresponding entry for a host:

# List of allowed users on the local host dn: cn=dalton.ahania.com,dc=ahania,dc=com objectClass: device                              Parent of ipHost. objectClass: ipHost                              Parent of groupOfUniqueNames. objectClass: groupOfUniqueNames cn: dalton cn: dalton.ahania.com uniqueMember: uid=chavez,ou=People,dc=ahania,dc=com uniqueMember: uid=carter,ou=People,dc=ahania,dc=com ...
6.6.4.4 Configure directory access control

The final steps in setting things up involves directoryaccess control. The database files themselves are protected against all non-root access, so permissions are enforced by the server. Access control information is specified in the server's configuration file, slapd.conf, via access control entries like these:

# simple access control: read-only except passwords access to dn=".*,dc=ahania,dc=com" attr=userPassword      by self write      by dn=root,ou=People,dc=ahania,dc=com write     by * auth access to dn=".*,dc=ahania,dc=com"      by self write      by * read

The access to entry specifies a pattern that the dn must match in order for the entry to apply. In the case of multiple entries, the first matching entry is used, and all remaining entries are ignored, so the ordering of multiple entries is very important. The first access to entry applies to the userPassword attribute of any entry: any dn in dc=ahania,dc=com. The owner can modify the entry, where the owner is defined as someone binding to the server using that dn and its associated password. Everyone else can access it only for authentication/binding purposes; they cannot view it, however. This effect is illustrated in Figure 6-13, which shows user a2's search results for the specified query.

Figure 6-13. The OpenLDAP server prevents unauthorized access
figs/esa3.0613.gif

The access control second entry serves as a default for the remainder of the database. Again, the owner can modify an entry, and everyone else can read it, an access level which allows both searching and display. These permissions are often appropriate for a company directory, but they are too lax for user account data. We'll need to examine access control entries in more detail to design something more appropriate.

6.6.4.5 OpenLDAP access control

An access control entry has the following general form:

access to  what-data     by  what-users allowed-access    [by  ...  ]

where what-data is an expression for the entries and possibly attributes to which this directive applies, what-users specifies who this directive applies to, and allowed-access is the access level that they are granted. There can be multiple by clauses. All variables can be literal values or include regular expressions.

The defined access levels are the following:

none

No access.

auth

Use for authentication only.

compare

Values are accessible to comparison operations.

search

Values are accessible to search filters.

read

Data can be viewed.

write

Data can be viewed and modified.

The target of the by clause has many possibilities, including a dn (which may contain wildcards) and the keywords self (the entry's owner), domain (which takes an expression for a domain as its argument), and anonymous (access by users who haven't been authenticated). A single asterisk can be used to signify access by anyone.

Let's look at some examples. The following configuration file directive allows everyone to have read access to the entire specified directory and also allows each entry's owner to modify it:

access to dn=".*,dc=ahania,dc=com"    by self write    by * read

The following example directives allow each entry's owner to read the entire entry but modify only a few attributes:

access to dn=".*,dc=ahania,dc=com" attrs="cn,sn,description,gecos"    by self write access to dn=".*,dc=ahania,dc=com"    by self read

The following example allows the uid of root (in any top-level organizational unit) to modify any password attribute in the directory:

access to dn=".*,dc=ahania,dc=com" attrs="password"    by dn="uid=root,ou=[A-Za-z]+,dc=ahania,dc=com" write

Note that we are assuming that ou names contain only letters.

Finally, this example controls access to the entries under the specified ou, limiting read access to members of the local domain:

access to dn=".*,ou=People,dc=ahania,dc=com"    by domain=.*\.ahania\.com read    by anonymous auth

Nonauthenticated users can use the data in this subtree only for LDAP authentication purposes.

You can use constructs like these to implement whatever access control design makes sense for your security objectives and needs. Consult the OpenLDAP Administrator's Guide for full details about access control directives.

6.6.5 Securing OpenLDAP Authentication

In all of our examples to this point, we have considered only the simplest method of presenting authentication credentials to the LDAP server: supplying a password associated with a specific distinguished name's password attribute. This is known as simple authentication, and it is the easiest way to bind to the LDAP server. However, since the passwords are sent to the server in the clear, there are significant security problems with this approach.

OpenLDAP supports the common authentication schemes: simple authentication using passwords, Kerberos-based authentication, and using the authentication services provided by the Simple Authentication and Security Layer (SASL). The first two of these are selected by the -x and -k options to the various LDAP client commands, respectively, and the absence of either of them implies SASL should be used. The Kerberos authentication method is deprecated, however, since superior Kerberos functionality is provided by SASL.

SASL was designed to add additional authentication mechanisms to connection-oriented network protocols like LDAP. Unix systems generally use the Cyrus SASL library, which provides the following authentication methods:

ANONYMOUS and PLAIN

Standard anonymous and simple, plain text password-based binds

DIGEST-MD5

MD5-encoded passwords

KERBEROS_V4 and GSSAPI

Kerberos-based authentication for Kerberos 4 and Kerberos 5, respectively

EXTERNAL

Site-specific authentication modules

Installing and configuring SASL is somewhat complex, and we don't have space to consider it here. Consult http://asg.web.cmu.edu/sasl/ for more information.

Fortunately, OpenLDAP also provides the means for securing the simple authentication scheme. It uses an interface to the Secure Sockets Layer ( SSL) and Transport Layer Security (TLS) networking functions. SSL provides encrypted authentication and data transfer via port 636 (assigned to the ldaps service), while TLS provides this via the standard LDAP port of 389. The advantage of the latter is that both encrypted and unencrypted clients can use the same standard port. However, it is usually best to enable both of them since client support is varied and unpredictable.

In order to use SSL and TLS, you will need to create a certificate for the LDAP server, using a process like this one:

# cd /usr/ssl/cert # openssl req -newkey rsa:1024 -x509 -days 365 \     keyout slapd_key.pem -out slapd_cert.pem Using configuration from /usr/ssl/openssl.cnf Generating a 1024 bit RSA private key writing new private key to 'newreq.pem' Enter PEM pass phrase:     Not echoed. Verifying password - Enter PEM pass phrase: ----------------------------------------------------------- You are about to be asked to enter information that  will be incorporated into your certificate request. Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:Connecticut ...

First, we change to the SSL certificates directory, and then we run the command that creates the certificate and key files. This process requires you to enter a pass phrase for the private key and to provide many items of information, which are used in creating the certificate. When this process completes, the certificate is located in the file slapd_cert.pem, and the key is stored in slapd_key.pem.

The next steps consist of removing the pass phrase from the key file (otherwise, you'll need to enter it every time you start slapd), and then setting appropriate ownership and protections for the files:

# openssl rsa -in slapd_key.pem -out slapd_key.pem    # chown  slapd-user . sldap-group  sl*.pem   # chmod 600 sl*.pem 

Once the certificate files are created, we add entries to slapd.conf pointing to the certificate files:

# SSL/TLS TLSCertificateFile /usr/ssl/certs/slapd_cert.pem TLSCertificateKeyFile /usr/ssl/certs/slapd_key.pem   # Specify ciphers to use -- this is a reasonable default TLSCipherSuite HIGH:MEDIUM:+SSLv2

Finally, we need to modify the boot script that controls slapd so that the startup command lists both normal and secure LDAP as supported protocols. Here is the relevant line:

slapd -h "ldap:/// ldaps:///"

After you restart the server, you can verify that things are working in several ways. An easy way is to run a search command and watch the associated network traffic as the command runs. For example, you can use the ngrep utility to watch the two LDAP ports and look for unencrypted passwords. In this example, we look for the string "bbb", which is the password used for binding to the server:

# ngrep 'bbb' port 636 or port 389 

Then, in another window, we run an ldapsearch command, which binds to a test entry in the directory (uid=a2), specifying the password first with -x and then with -w, using the ldap and ldaps services, respectively. Here is the second command:

# ldapsearch -H ldaps://10.0.49.212:636 -w bbb -x \      -D 'uid=a2,ou=People,dc=ahania,dc=com' 'uid=a*'

The search command should return some entries both times, but the ngrep command will not find any matching packets for the second search since the password is encrypted.

Alternatively, you can use a client that supports one or both of these facilities. Figure 6-14 illustrates the gq utility's server properties dialog. You can check the appropriate box to use TLS and then run a similar test to the preceding, again searching for the cleartext password (and not finding it when TLS is enabled).

Figure 6-14. Enabling TLS support in the gq client
figs/esa3.0614.gif

If you have problems binding to the server, make sure that the password you are using is the correct one for that entry and that the access level for your test entry is sufficient for the operation to succeed. Finally, be sure that you have restarted the slapd process and that it has not generated any error messages.

NOTE

figs/armadillo_tip.gif

This introduction to OpenLDAP should be sufficient to get you started experimenting with this facility. As with any change of this size and complexity, it is important to test changes in a controlled and limited environment before attempting to apply them to production systems and/or on a large scale.

6.6.6 Wither NIS?

The Network Information Service (NIS) is another distributed database service that allows a single set of system configuration files to be maintained for an entire local network of computers. NIS was created by Sun Microsystems. With NIS, a single password file can be maintained for an entire network of computers almost automatically (you still have to add or modify entries on one copy by hand). This section will provide a brief description of NIS. Consult your system documentation for more details (use man -k nis and man -k yp to get started). In addition, Managing NFS and NIS, by Hal Stern, Mike Eisler, and Ricardo Labiaga (O'Reilly & Associates), contains an excellent discussion of NIS.

NIS was designed for a very open environment in which significant trust among all systems is desired (and assumed). As such, many considerations related to protecting systems from the bad guys outside or inside were overlooked or ignored in its design. Unfortunately, it isn't an exaggeration to say that NIS is a security nightmare.

If your network has direct connections to other computers outside of your control, or if there are any internal systems that need to be protected from others within the local network, then I'd advise you not to use NIS or even NIS+ (which fixes only a few of NIS's most egregious security flaws). Use NIS only when you want an open, mutually trusting security environment across an entire local network that has all its entrances from the outside world as well as untrusted parts of the same site protected by very rigorous firewalls.



Essential System Administration
Essential System Administration, Third Edition
ISBN: 0596003439
EAN: 2147483647
Year: 2002
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net