LDAP quick start guide

These are notes I collected while getting LDAP working for posix user/group name service in the GECo computing lab.

OpenLDAP, ie. the Lightweight Directory Access Protocol, is essentially a network acccessable database that can provide directory service for pretty much anything. One of the main uses for LDAP is to provide name service for user and group information in a networked computer environment. The usefulness of this is that it allows many computers to share the same user and group information.

The basic idea is as follows. On login, user name info is mapped to uid by a querry to the Name Service Switch (NSS), which then queries LDAP. Once the uid is returned, the Pluggable Authentication Modules (PAM) service is used to match user and auth. This is also done through LDAP.

For the system described in this howto, LDAP will handle authentication and authorization for normal posix users and groups. Information for system users will still be maintained locally. We will also have LDAP handle Netgroups for computers in the lap (useful for NFS (with caveats, mentioned later)).

These notes are specifically for Debian GNU/Linux 4.0 ("etch") systems, but they should be similar for other linux distributions as well.

  1. Setting up the LDAP server
  2. Setting up the LDAP client
  3. Creating and populating the LDAP database
  4. Server administration

Setting up the LDAP server: slapd

The first thing to do is install and configure the slapd server on whatever machine is going to function as the LDAP server. You should also install the ldap-utils package:

server:~$ apt-get install slapd ldap-utils

Apt may prompt you for information about configuring slapd. You will also be asked to enter an administrator password for the initial database. Make sure you note it down. You may also be asked for the base name uri. If you are not asked, then it has probably determined the basename from the domain name of the server. For this example, we will use:

dc=your,dc=domain,dc=org

If you are not asked to enter a basename, make sure that the basename you will use is specified correctly in /etc/ldap/slapd.conf:

server:~$ grep -1 "dc=your,dc=domain,dc=org" /etc/ldap/slapd.conf
# The base of your directory in database #1
suffix          "dc=your,dc=domain,dc=org"

--
# for syncrepl.
# rootdn          "cn=admin,dc=your,dc=domain,dc=org"

--
access to attrs=userPassword,shadowLastChange
        by dn="cn=admin,dc=your,dc=domain,dc=org" write
        by anonymous auth
--
access to *
        by dn="cn=admin,dc=your,dc=domain,dc=org" write
        by * read
--
#access to dn=".*,ou=Roaming,o=morsnet"
#        by dn="cn=admin,dc=your,dc=domain,dc=org" write
#        by dnattr=owner write
server:~$

It's probably wise to specify explicitly the slapd service url in /etc/default/slapd, although this is not strictly necessary for the setup we are using:

# /etc/default/slapd

SLAPD_SERVICES="ldap:///"

Now you can restart slapd:

server:~$ /etc/init.d/slapd restart

It's helpful to configure /etc/ldap/ldap.conf so that LDAP tools on the server can easily access it's own slapd server:

# /etc/ldap/ldap.conf

BASE	dc=your,dc=domain,dc=org
URI	ldap://localhost

The server should now be running a normal, unencrypted slapd server.

Configuring the server to use SSL encryption

It is highly recommended that LDAP be configured to use SSL/TLS encryption. This is especially important for the setup described here, since LDAP will be handling user authentication, and will therefore be required to store (hashed) user passwords.

Before any service can be configured to use SSL, there must first be an SSL private key, and corresponding certificate signed by a trusted certificate authority (CA). For information on issuing SSL certificates, including signing them with your own certificate authority, please refer to the SSL how-to. For now we assume that the needed certificates and keys are already exist.

Once the key and certificates are in place, add the following lines to the slapd.conf, pointing to the LDAP service key and certificate, as well as the CA certificate (I usually put this stanza right before "Backend Directives"):

# /etc/ldap/slapd.conf
...
#######################################################################
# Enable ssl encryption
TLSCACertificateFile /etc/ssl/certs/your.domain.org-cacert.pem
TLSCertificateFile /etc/ldap/server.your.domain.org-ssl-cert.pem
TLSCertificateKeyFile /etc/ldap/server.your.domain.org-ssl-key.pem
TLSCipherSuite HIGH:+MEDIUM:!LOW

#######################################################################
# Specific Backend Directives for bdb:
...

Make sure that the server key is readable by the LDAP user *only*. This is very important for security reasons. For Debian etch, the default slapd user is "openldap".

server:~$ chown root:openldap /etc/ldap/server.your.domain.org-ssl-key.pem
server:~$ chmod 640 /etc/ldap/server.your.domain.org-ssl-key.pem

We also need to modify the /etc/ldap/slapd.conf to tell slapd to use tls encryption. This used to be done simply by telling slapd to serve on the secure LDAP port, 636, with the secure LDAP uri "ldaps:///". However, this method appears to be deprecated in favor of the newer "StartTLS" method. I should warn, though, that not all LDAP clients support StartTLS (such as Apache versions 2.0).

To configure slapd to use the StartTLS method, the access stanzas in /etc/ldap/slapd.conf must be modified to include Security Strength Factor declarations in the "who" field (see man slapd.access for more information):

# /etc/ldap/slapd.conf
...

# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
# Require TLS for all connections.
access to attrs=userPassword,shadowLastChange
        by tls_ssf=128 ssf=128 dn="cn=admin,dc=your,dc=domain,dc=org" write
        by tls_ssf=128 ssf=128 anonymous auth
        by tls_ssf=128 ssf=128 self write
        by * none

# The admin dn has full write access, everyone else
# can read everything.
# Require TLS for all write connections.
access to *
        by tls_ssf=128 ssf=128 dn="cn=server.your.domain.org,ou=services,dc=server,dc=your,dc=domain,dc=org" write
        by tls_ssf=128 ssf=128 dn.children="ou=admin,dc=your,dc=domain,dc=org" write
        by * read
...

You should now be able to restart slapd and have it run with TLS/SSL encryption.


Setting up the LDAP client

On the client, install the LDAP client utilities:

server:~$ apt-get install ldap-utils

This includes the configuration file /etc/ldap/ldap.conf where you can specify a default LDAP server:

# /etc/ldap/ldap.conf

BASE    dc=your,dc=domain,dc=org
URI     ldap://server.your.domain.org

TLS_CACERT /etc/ssl/certs/your.domain.org-cacert.pem
TLS_REQCERT demand

Configure the client NSS to use LDAP

First install the libnss-ldap library:

server:~$ apt-get install libnss-ldap

This installs the config file /etc/libnss-ldap.conf that must be modified to use LDAP and tls. Here is a basic setup that should work for the system we're setting up:

# /etc/libnss-ldap.conf

host server.your.domain.org
base dc=your,dc=domain,dc=org
uri ldap://server.your.domain.org/
ldap_version 3
ssl start_tls
tls_checkpeer yes
tls_cacertfile /etc/ssl/certs/your.domain.org-cacert.pem

We also have to modify /etc/nsswitch.conf to tell NSS to use LDAP:

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

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

hosts:          files dns
networks:       files

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

netgroup:       ldap

Since name service is done over the network, you should probably install the Name Service Caching Daemon (ncsd):

server:~$ apt-get install nscd

Configure the client PAM to use LDAP

We now need to configure the PAM to use LDAP as well. Start by installing the libpam-ldap package:

server:~$ apt-get install libpam-ldap

Like libnss-ldap, libpam-ldap also comes with a config file. In fact, you may notice that they are basicaly identical. The libpam-ldap config file is basically identical to the libnss-ldap config file, accept that we add a line to configure how passwords are stored

# /etc/pam_ldap.conf

host server.your.domain.org
base dc=your,dc=domain,dc=org
uri ldap://server.your.domain.org/
ldap_version 3
...
# Hash password locally; required for University of
# Michigan LDAP server, and works with Netscape
# Directory Server if you're using the UNIX-Crypt
# hash mechanism and not using the NT Synchronization
# service. 
pam_password crypt
...
ssl start_tls
tls_checkpeer yes
tls_cacertfile /etc/ssl/certs/your.domain.org-cacert.pem

For ease of adminitration, I actually use a single config file for both /etc/libnss-ldap.conf and /etc/pam_ldap.conf, soft-linked appropriately.

We also need to configure the various PAM modules that will be using LDAP. Here is a configuration that has worked for me:

# /etc/pam.d/common-auth

auth [success=1 default=ignore]	pam_unix.so nullok_secure
auth required 			pam_ldap.so use_first_pass
auth required 			pam_permit.so
# /etc/pam.d/common-account

account [success=1 default=ignore]	pam_unix.so
account required 			pam_ldap.so
account required 			pam_permit.so
# /etc/pam.d/common-session

session [success=1 default=ignore] pam_unix.so
session	required 		   pam_ldap.so
session required 		   pam_permit.so
# /etc/pam.d/common-passwd

password [success=1 default=ignore] pam_unix.so obscure min=6 md5
password required		    pam_ldap.so try_first_pass
password required 		    pam_permit.so

Other client config notes

The client should now be configured to use the LDAP server for NSS and PAM. Here are a couple of closing notes that might be important:

External Links:


Creating and populating the LDAP database

Once the server has been properly configured, the database must be populated with whatever information it's going to serve. In our case, this will include entries for users, groups, and workstations.

There are many tools that can be used for manipulating LDAP databases (Debian packages 'ldapscripts' and 'cpu' (command-line) and 'luma' (gui), just to name a few). In this document, however, we will just be manipulating the database directly with the tools provided in the 'ldap-utils' package.

Specific entries in the database are input using the '.ldif' data format, as will be illustrated below.

Creating top level objects

When slapd is installed, it creates an initial database with entries that define the top level domain of the server, and an administrator for the database. But before we can add individual entries, we must first create the initial top level objects that the individual entries will be members of. We will need three top-level objects, for the three types of database entries. Below is an example ldif for creating these objects:

# initialize.ldif

dn: ou=People,dc=your,dc=domain,dc=org
objectClass: top
objectClass: organizationalUnit
ou: People
description: your.domain.org users

dn: ou=Groups,dc=your,dc=domain,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Groups
description: your.domain.org groups

dn: ou=Netgroup,dc=your,dc=domain,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Netgroup
description: your.domain.org netgroups

dn: cn=Workstations,ou=Netgroup,dc=your,dc=domain,dc=org
objectClass: top
objectClass: nisNetgroup
cn: Workstations
description: your.domain.org computer workstations

Now that we have an ldif, we can insert it into the database with either the 'ldapadd' tool:

server:~$ ldapadd -x -W -D 'cn=admin,dc=your,dc=domain,dc=org' < initialize.ldif

or by stopping the slapd server and using the 'slapadd' tool. Either way works fine, but using slapadd is probably preferable when adding lots of data at once.

Creating a user account

LDAP uses schemas to help define various object classes. It is important to know which schemas you need to use for various object entries.

Below is the ldif for a new user account. Note it uses three object classes: posixAccount (from nis.schema), and inetOrgPerson (from inetorgperson.schema). It also create the user group for the new user.

# new_user.ldif

dn: uid=foobar,ou=People,dc=your,dc=domain,dc=org
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
uid: foobar
cn: Foo Bar
sn: Bar
givenName: Foo
uidNumber: 2000
gidNumber: 2000
shadowMax: 99999
shadowWarning: 7
shadowLastChange: 12959
loginShell: /bin/bash
homeDirectory: /home/foobar
mail: foobar@your.domain.org

dn: cn=jrollins,ou=Groups,dc=your,dc=domain,dc=org
objectClass: posixGroup
cn: foobar
gidNumber: 2000

Notice that the uid/gid is 2000. I like to start LDAP user id ranges well outside those used by local accouts, which start at 1000. It's also nice to make group id's to be the same as user id's.

We add this ldif to the database the same way we did for the initial object definitions:

server:~$ ldapadd -x -W -D 'cn=admin,dc=your,dc=domain,dc=org' < new_user.ldif

Here are some ldifs for a none-user group, and a workstation:

# new_group.ldif

dn: cn=group1,ou=Groups,dc=your,dc=domain,dc=org
objectClass: posixGroup
cn: group1
gidNumber: 1500
# new_host.ldif

dn: cn=host1,ou=Netgroup,
changetype: modify
replace nisNetgroupTriple
cn: group1

dn: cn=Workstations,ou=Netgroup,dc=your,dc=domain,dc=org
objectClass: nisNetgroup
cn: Workstations
description: your.domain.org computer workstations
nisNetgroupTriple: (host1,,your.domain.org)

For the Workstation Netgroup, each new workstation will get it's own 'nisNetgroupTriple' line.


LDAP Server administration

I want to here outline a couple of things that might make administering your LDAP server a little easier.

Useful tools

By far the most useful LDAP tool that I have come across (other than those provided by the 'ldap-utils' package, is ldapvi. ldapvi is a command-line based tool that allows you to directly edit the LDAP database with the test editor of your choosing.

migrationtools is a set of scripts that will migrate unix flat files to LDAP ldif files that can be imported into the server database.

A nice gui LDAP directory browser and adminitration tool is luma.

A console-based tool to administer simple shadow users and groups is cpu.

External links:


Other things to think about doing


Other useful guides


Last modified: Mon Jan 29 08:58:24 EST 2007