Linux Authentication Using OpenLDAP, Part One
Introduction
This is the first of two articles that will discuss a number of issues with LDAP authentication on Linux. In this
installment, I will discuss an overview of LDAP, installing and configuring OpenLDAP, migrating to OpenLDAP
and setting up LDAP queries. In this series, I will focus on Red Hat Linux version 7.1 (with some comments about
earlier revisions;) however many of the same principles apply to Debian and other Linux distributions.
Authentication, PAM, and NSS
Authentication is the process wherein a user logging on to a Linux system has their credentials checked before
being allowed access. Usually, this means that a user needs to provide a login name and a password.
Many different programs provide authentication, each using a different method. For example, the basic Unix login
program provides a simple text interface for a user to enter a user ID and password. Graphical login systems such
as XDM (or GDM or KDM) provide a different interface. Programs such as SSH can authenticate users based on things
like RSA or DSA keys as well as passwords.
There are many different authentication suites or protocols available on Linux today. Like all traditional Unix
systems, Linux is capable of authenticating users against entries in the /etc/passwd and /etc/shadow files, but
it also supports such authentication schemes as Kerberos, RADIUS, and LDAP, which stands for Lightweight Directory Access
Protocol.
PAM (which stands for Pluggable
Authentication Modules) is a set of libraries provided with most modern Linux distributions, and it is installed
by default in Red Hat Linux. The PAM libraries provide a consistent interface to an authentication protocol. An
application can use the PAM libraries to allow the use of any authentication protocol within that application,
so that if the system administrator wants to change from, for example, /etc/passwd authentication to LDAP, the
application does not have to be re-written or recompiled. PAM requires a PAM module for each authentication system. There
are many such PAM modules on the above web site.
Unfortunately, PAM only provides part of the information needed to keep track of users on a Linux system. In
addition to being able to check that a user has entered the correct password, a Linux system needs other
information, such as the user's numeric user ID, their home directory, default shell, etc. This information,
which would normally be stored in the /etc/passwd file, can be determined through a system interface known as
NSS, or Name Service Switch.
Only some authentication schemes provide enough information to be useful to NSS. For example, Kerberos only
stores user authentication information, not details such as a home directory or default shell. Therefore, there
is no NSS module for Kerberos.
What is LDAP?
LDAP, or Lightweight Directory Access Protocol, is a network protocol that is used for accessing information
in an object-oriented database. LDAP includes features that make it useful to both PAM and NSS, as it can
authenticate users, as well as providing user information such as home directory names and default shells to
NSS.
An LDAP Server or Directory Server (sometimes called a DS for short) is a server that can send and receive
information in the LDAP protocol. Typically, an LDAP server will be a piece of software that listens on the
standard LDAP ports (389 and sometimes 636) for connections, and responds to LDAP queries and requests. To draw
an analogy with databases, LDAP is the equivalent of SQL, and an LDAP server is like a database server such as
Oracle or MySQL.
LDAP servers are particularly useful for storing information about people. This is because of the object-oriented
nature of LDAP. Unlike a relational database, an object in an LDAP directory can contain an arbitrary number of
attributes, and each attribute can have an arbitrary number of values. This is useful for many reasons. For
example, a database row containing a column for a phone number would allow a single entry in that phone number
column for each row in the database table. A person, however, may have more than one phone number, and so LDAP
allows multiple phone numbers to be stored in the same person object. Note the slightly different terminology here:
we say an LDAP 'directory' as opposed to a 'database', we call entries in the directory 'objects' instead of
'rows', and we call field values of an object 'attributes' instead of 'columns'.
Why Use LDAP?
There are a number of reasons why we might use LDAP:
-
LDAP allows us to centralize the information about users, passwords, home directories, etc, in a single place on
a network. If we were using /etc/passwd files, for example, we would have to make sure that all passwd files
were kept in sync across the network, which would be an absolute nightmare on a large network with users
changing passwords regularly.
-
LDAP offers encrypted transactions. Most LDAP servers offer encrypted connections using SSL (either using Start
TLS on port 389 or LDAPS on port 636), which is more secure than some mechanisms by which plain text passwords
are sent over the network.
An LDAP directory is also useful for other purposes. For example, it can quickly and easily be used as a
company's staff e-mail and contacts directory.
-
It is possible to use LDAP in a tree structured manner, unlike the /etc/passwd or NIS tables which basically
store users in a flat structure. With a large number of users it makes sense to divide them into organizational
units so that they can be found and managed more easily. In the long term, this makes managing an LDAP directory
less onerous than managing /etc/passwd files or an NIS/NIS+ database.
OpenLDAP
OpenLDAP
is an open source implementation of an LDAP directory server. OpenLDAP is installed by default with Red Hat 7.1 or
later, and is available on Red Hat versions from 6.2 onwards. Note that earlier releases of Red Hat used release 1
of the OpenLDAP product. Although this is still considered a stable release by the OpenLDAP team, for a
number of security reasons, I would advise against using it. For example, it does not support SSL or schema
checking. Your OpenLDAP version should be 2.0.7-3 or later.
Installing OpenLDAP
As usual, you can install OpenLDAP from the source code by obtaining the source files from the OpenLDAP web site and following the compilation instructions.
My preference, however, is to install the OpenLDAP packages from the RPM files as follows. Note that you will
need to install both the server and client packages if you want to set up an OpenLDAP server. First, put your
Red Hat CD-ROM into your CD-ROM drive and use the following sequence of commands:
1. mount /dev/cdrom /mnt/cdrom
2. cd /mnt/cdrom/RedHat/RPMS
3. rpm -Uhv openldap-2.0.7-14.i386.rpm openldap-servers-2.0.7-14.i386.rpm
openldap-clients-2.0.7-14.i386.rpm
4. umount /mnt/cdrom
It's possible that the packages are already installed on your system (to verify this you can do rpm -q
openldap.) It is also possible that you may hit one or more dependencies in installing the above RPMs. In
particular, the OpenLDAP packages require the OpenSSL package, and at least the krb5-libs package.
LDAP,PAM and NSS libraries
Using LDAP will almost certainly require you to install the PAM libraries for LDAP. In Red Hat 6.2 and later,
these are packaged in with the nss_ldap package (since the pam_ldap libraries are not much use without the
nss_ldap libraries and vice-versa). These are normally installed by default - to test this you can run
rpm -q nss_ldap. If the nss_ldap package is not installed, you can install it using RPM as follows:
mount /dev/cdrom /mnt/cdrom
cd /mnt/cdrom/RedHat/RPMS
rpm -Uhv nss_ldap*.rpm
umount /mnt/cdrom
If you need to obtain the source code for the pam_ldap and nss_ldap libraries, they are available from PADL.com
at the following locations:
Configuring OpenLDAP
Configuration of OpenLDAP is done through the /etc/openldap/slapd.conf file. There is a manual page describing
the contents of the slapd.conf file (see man slapd.conf) as well as an excellent administration guide on the OpenLDAP web site. As a starting point, you
might like to use the following simple configuration file:
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/rfc822-MailMember.schema
include /etc/openldap/schema/autofs.schema
include /etc/openldap/schema/kerberosobject.schema
#######################################################################
# ldbm database definitions
#######################################################################
database ldbm
suffix "o=MyCompany,c=AU"
rootdn "uid=root,ou=People,o=MyCompany,c=AU"
rootpw secret
directory /var/lib/ldap
# Indices to maintain
index objectClass,uid,uidNumber,gidNumber eq
index cn,mail,surname,givenname eq,subinitial
#
# ACLs
#
access to dn=".*,ou=People,o=MyCompany,c=AU"
attr=userPassword
by self write
by dn="uid=root,ou=People,o=MyCompany,c=AU" write
by * auth
access to dn=".*,o=MyCompany,c=AU"
by self write
by dn="uid=root,ou=People,o=MyCompany,c=AU" write
by * read
access to dn=".*,o=MyCompany,c=AU"
by * read
defaultaccess read
One thing that should be noted in the configuration file above: users should replace "o=MyCompany,c=AU" throughout
the file with a Base DN which represents their organization. Note that I prefer to use the X.500 style
specification above, but you could use the DNS specification which is "dc=mycompany,dc=com,dc=au" or similar. For
example, if your company was called "farnarkle.com" you could use "dc=farnarke,dc=com", or you could use
"o=farnarke,c=US". Remember this Base DN, it will be important later.
I have elected to include some elementary Access Control in the file. The standard slapd.conf file included with
Red Hat Linux does not include ACLs, but they are mandatory for real use. You may want to expand on the above
ACLs (see the slapd.conf manual or the administrator's guide.)
I have included a default root password - 'secret'. This is a bad idea once you have data in your LDAP
directory. We will deal with this later.
I have not included TLS certificates, keys, or other information. I would consider this to be a security issue
on a network, because without these the server will operate entirely in plain text mode. This will be covered
later.
Once you have a working slapd.conf file, you should be able to start your server. This is easy enough to do, you
can just run the following command:
/etc/rc.d/init.d/ldap start
Provided that the slapd.conf file is correct, you should be able to use pstree to see a running slapd process.
If the slapd.conf file is incorrect, look for error messages (running slapd -d here might help), fix up any
problems you see, and try again.
Migrating to OpenLDAP
Once you have your LDAP server started, you will have an empty directory. The first thing you need to do is to
populate it with data from your existing authentication database.
Using the supplied LDAP tools
OpenLDAP provides a suite of tools to migrate data from your existing NIS or /etc/passwd database into LDAP. If
you currently run another authentication scheme such as Kerberos or S/Key, and you are migrating to LDAP, then
I'm afraid you are on your own.
In Red Hat Linux 7.1, the migration tools are in /usr/share/openldap/migration/. In Red Hat 6.2 and earlier they
were in /usr/lib/openldap/migration/. In either case, open a shell window, change to that directory, and get to
work. First, edit the migrate_common.ph file. Around line 72 you will see a couple of lines like this:
$DEFAULT_MAIL_DOMAIN = "babel.com.au";
$DEFAULT_BASE = "o=Babel,c=AU";
You will need to edit these two lines, providing your default mail domain and the Base DN that you defined
earlier in the slapd.conf file. Next, it's a simple matter of running the migration tools. This can be done
using a simple command, assuming that you are migrating from /etc/passwd files to LDAP:
migrate_all_online.sh
(make sure that your LDAP server is running before using the above command).
This will ask you for the root DN and password (enter the password secret that we defined in the slapd.conf
file), and will start to populate your LDAP directory.
Setting up LDAP queries
Having data in your LDAP directory is all very well and good, but at some stage you are going to want to query
that data. There are a standard set of command line-based LDAP query and management tools provided with
OpenLDAP. These include ldapadd, ldapmodify, and ldapsearch. Each of these tools has a man page, and you would
do well to read these man pages in detail.
The standard configuration file for these tools is /etc/openldap/ldap.conf. The file format of this file is
fairly simple; on a single system it need only contain the following two lines:
BASE o=MyCompany,c=AU
URI ldap://127.0.0.1
Remember to substitute your Base DN that you defined in the slapd.conf file instead of the o=MyCompany, c=AU
entry shown above.
On a network, you may have to substitute the IP address of your LDAP server instead of 127.0.0.1 shown above.
For those of you who understand LDAP concepts a little better: OpenLDAP doesn't (yet) support SLP or DNS RR
based location, so you have to be fairly precise about the location of the server -- either an IP address, a
host name from /etc/hosts, or something that can be found in DNS.
Once you have done that, you should be able to perform a simple search. You could start by looking for your root
user by using the following simple command:
ldapsearch -x 'uid=root'
You should see an entry fairly similar to this one:
version: 2
#
# filter: uid=root
# requesting: ALL
#
# root,People,MyCompany,AU
dn: uid=root,ou=People,o=MyCompany,c=AU
uid: root
cn: root
sn: root
mail: root@mycompany.com.au
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: kerberosSecurityObject
objectClass: shadowAccount
shadowMax: 99999
shadowWarning: 7
krbName: root@MYCOMPANY.COM.AU
loginShell: /bin/bash
uidNumber: 0
gidNumber: 0
homeDirectory: /root
gecos: root
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Now that you have come this far, stop and smile. You have managed to get LDAP working, which is sometimes not an
easy task!
This brings us to the end of the first installment of this two-part series. In the next article, we will
continue the discussion of OpenLDAP and Linux, covering subjects such as: Setting up PAM and NSS for LDAP, LDAP
Tools, making OpenLDAP more secure and generating SSL keys for OpenLDAP.