Note This independently authored paper is obsolete. Reviewers of this papers have indicated that they believe the paper suffers from a number of significant technical errors and offers poor advice in a number of areas. As the author is unreachable and this paper is quite old, the paper has has been classified as obsolete. It is strongly recommended that users of OpenLDAP Software consult the OpenLDAP Administrator's Guide for a detailed and up-to-date discussion of TLS/SSL use in OpenLDAP Software. Note added by Kurt Zeilenga (7 March 2006, updated 27 March 2013) |
It should be noted that the steps taken in this document ensure an LDAP version 3 level of compliance.
1.1 Acknowledgment
None of the details here would be possible without the information taken from the "OpenLDAP Administrator's Guide" or the help received from Kurt Zeilenga, one of the main OpenLDAP contributors. OpenLDAP is a large set of software tools and I could not have set up the SSL portion without advice and tips from Kurt. Thank you very much, Kurt!
The OpenLDAP download site offers two download sources: release and stable. For this document, the release version was used on advice from Kurt. Frequently, release versions make it to stable status quickly as was the case for me. Advanced users may also want to check out the test release if available. Also, older releases may have an update available for users who haven't upgraded to the current development level.
If OpenLDAP is installed already and you are downloading the tarball, you should locate current OpenLDAP objects and avoid using them altogether. Why? It would be undesirable if an older LDAP standalone daemon (slapd) is started instead of the newly created one, since the daemon would not refer to the recently created server and configuration files!
Before installing the tarball, use "find" or "locate" and take note of the locations and dates of the following (which may not exist on your machine):
Actually, older version OpenLDAP client commands may be used to access the directory. The real issue on the client side is configuring the correct ldap.conf associated with the client. This issue is left for the user to decide.
2.1 Additional Software
Besides OpenLDAP, other development software may be required as dictated by the selected OpenLDAP configuration options.The best practice for installing missing software is:
- Run the configure script (see section 3.2.1 "configure") with your options.
- Look for error messages involving missing header files or libraries.
- Consult the Linux distro CDs and install the necessary rpm. Almost all missing rpms are the development releases of the form
package-devel-release.arch.rpm
. To ensure compatibility, it is a good idea to verify client and development software have similar release values. They should be equal if they come from the same distribution. For example:
- openssl-0.9.6g-18.i586.rpm
- openssl-devel-0.9.6g-18.i586.rpm
2.1.1 Database Backend
One of the OpenLDAP options you should set during the OpenLDAP build is your desired database backend. Slapd comes with a variety of different database backends you can choose from. The two most commonly used are BDB, a high-performance transactional database backend and LDBM, a lightweight DBM based backend.The default backend is BDB which means Sleepycat Software Berkley DB 4.1 will be utilized (
--enable-bdb
configure option). If that is not the desired database, then disable it (--disable-bdb
configure option) and select another type.It may be easier to use one of the many LDBM backends (GDBM, Berkley DB, MDBM, or BCompact). Although many of the database clients are installed already, you will still need to install the development rpms, as discussed in section 2.1. I chose the LDBM route (
--enable-ldbm
) and installed both the GDBM and Berkely DB rpms. Both were installed because I wanted to see which database OpenLDAP selects when more than one is available. However, only one database needs to be present.Indeterminate of the database backend employed, the OpenLDAP software handles all of the database transactions transparently once OpenLDAP is installed and running. Therefore, the database does not need to be configured or initiated.
2.1.2 Software for this Example
You do not need to use the software levels in this example but you should use at a minimum OpenLDAP 2.1. More important is the use of a current version of Linux and its distributed rpms than searching for the software levels listed. The levels are listed only for reference. Current Linux levels may be determined from the distributor's website.Your list could be shorter or longer depending upon the options selected during configuration and the software already installed on your Linux machine. In addition, SuSE and RedHat have differing dependencies, i.e., a RedHat box would not have a SASL dependence on the installation of Heimdal.
Operating system: SuSE 8.1
OpenLDAP: 2.1.17Additional rpms
OpenSSL openssl-devel-0.9.6g-18
GDBM gdbm-devel-1.8.0-671
Berkley DB db-devel-4.0.14-182
Cyrus SASL cyrus-sasl-devel-1.5.27-256
DES* des-4.04b-501
Heimdal* heimdal-devel-0.4e-186
PAM pam-devel-0.76-36* required by Cyrus SASL
3.0 Configure, Build, and Install OpenLDAP
At a minimum, the document
"OpenLDAP Quick Start Guide" should be reviewed before attempting to install
OpenLDAP. If problems persist, the comprehensive
"OpenLDAP Administrator's
Guide" can be helpful. Hopefully, this document will provide enough detail to
perform the task at hand.
It is assumed the OpenLDAP source has been unpacked and the user has changed to the top level OpenLDAP directory at this stage of the document:
% tar zxf openldap-VERSION.tgz
|
At the top level of the OpenLDAP distribution are two files worth skimming:
README lists required software levels for OpenLDAP 2.1
and documentation sites.
INSTALL lists installation steps and suggests files to
configure.
Note: a simple default install of OpenLDAP is not an option if SSL is to be enabled. A little extra work will be required.
3.1 Configure Options
As mentioned already, there are over one hundred options that can be configured. To view a complete list, type:
% ./configure --help
Here is a short list of some common options [default value]:
--no-create do not create output files --prefix=PREFIX install architecture independent files in PREFIX [/usr/local] --enable-debug enable debugging [yes] --with-tls with TLS-SSL support [auto] --with-cyrus-sasl with Cyrus SASL support [auto] --with-kerberos with Kerberos support [auto] --enable-slapd enable building slapd [yes] --enable-cleartext enable cleartext passwords [yes] --enable-crypt enable crypt passwords [no] --enable-kpasswd enable Kerberos password verification [no] --enable-spasswd enable (Cyrus) SASL password verification [no] --enable-wrappers enable TCP wrapper support [no] --enable-bdb enable Berkley DB (4.1) backend [yes] --enable-ldbm enable ldbm backend [no] --with-ldbm-api with LDBM API auto|berkley|bcompact|mdbm|gdbm [auto] '--disable-FEATURE' is equivalent to '--enable-FEATURE=no'. '--without-FEATURE' is equivalent to '--with-FEATURE=no'.
3.1.1 Example Configure Options
This example uses these features:
--prefix=/usr
A preference to avoid installing everything into /usr/local. Also, LDAP client commands are installed to usr/bin/ (overwrite and void old LDAP client commands).
--with-tls and --enable-slapdThe whole purpose of this exercise.
--with-cyrus-saslAt first this option was not selected, but the OpenLDAP Admin Guide states that the system "will not be fully LDAPv3 compliant unless it detects a usable Cyrus SASL installation."
--enable-cryptCryptic passwords are always good.
--enable-ldbm and --disable-bdbTurn off BDB and turn on LDBM style database backend.
Default options turned on: --enable-debug and --enable-cleartextOptions avoided: --enable-kerberos (not part of this exercise)
3.2 Build and Install
After selecting the configure options, follow these steps to build and install the OpenLDAP system. Do not proceed until each step is completed error-free.
3.2.1 configure
The form of this command is:[ [ env ] settings ] ./configure options
([ ] represents optional segments of the command)
(Some shells do not require the use of 'env')
(Usually 'options' are optional but not for this example)Settings may be any of these (from Admin Guide):
Table 1: Configuration Flags
VARIABLE DESCRIPTION CC Specify alternative C Compiler CFLAGS Specify additional compiler flags CPPFLAGS Specify C preprocessor flags LDFLAGS Specify linker flags LIBS Specify additional entries Example command using environment settings:
% env CPPFLAGS="-I/usr/local/incude" LDFLAGS="-L/usr/local/lib" \
./configure --with-tlsHere is the actual command used to configure the test system:
% ./configure --prefix=/usr --with-tls --enable-slapd --with-cyrus-sasl \
--enable-crypt --enable-ldbm --disable-bdbCopyright 1998-2024 The OpenLDAP Foundation, All Rights Reserved.
Restrictions apply, see COPYRIGHT and LICENSE files.
Configuring OpenLDAP 2.1.17-Release ...
checking host system type... i686-pc-linux-gnu
( ... A few hundred lines of output ... )
Please run "make depend" to build dependencies
%Successful configuration will end with "Please run 'make depend' to build dependencies". If this message is not displayed, examine the output for missing headers or libraries. See section 2.1 "Additional Software" if software is missing.
3.2.2 make depend
Enter the following command to build dependencies and look for errors:% make depend
3.2.3 make
Enter the following command to build the system and look for errors:% make
Missing libraries will be discovered during 'make'. Also, this part should take a long time to execute (more than five minutes).
3.2.4 make test
This command is optional but testing the standalone system is recommended. This command also has a long execution time.
% make test
If all goes well, the system has been built as configured! Otherwise return to the configure, make depend, and make steps to find the problem.
3.2.5 make install
Enter the following command to install the binaries and man pages. Most installs require 'root' privileges.
% su root -c 'make install'
Tip: the installed man pages can be the best source of OpenLDAP answers in some instances.
There are two ways to create and install a server certificate. Both methods involve creating the server certificate, sending it to OpenLDAP clients, and making appropriate changes to the OpenLDAP configuration files. Also, both methods involve OpenSSL commands that query the user for information used to create the certificate.
When asked for a 'Common Name', you must enter the fully-qualified distinguished name of the server, e.g. myserver.com, and not 'your name' as is suggested by the OpenSSL prompt. This common mistake is the cause of over 90% of server certificate errors!
4.1 Self Signed Certificate
The first way to create a server certificate is to use OpenSSL and create a self signed server certificate. From a command line:
% openssl req -newkey rsa:1024 -x509 -nodes -out server.pem -keyout server.pem -days 365
OpenLDAP only works with unencrypted keys and the '-nodes' argument prevents encryption of the private key.
The next step would involve configuring OpenLDAP with the location of server.pem. Self-signed certificate usage is discouraged and their configuration is not discussed in detail in this document because of these two downsides:
1. The private key is included in the certificate which will be transported to all OpenLDAP client machines.
2. Interpreting error messages from OpenSSL commands (see section 6.1 "SSL Connection Check".) The following output from an "openssl s_client ..." command is not an actual error (output edited for clarity):
Self Signed Certificate Output
% openssl s_client -connect localhost:636 -showcerts
CONNECTED(00000003)
depth=0 /O=Example Org/OU=Example Unit/CN=myserver.com/Email=me@example.com
verify error:num=18:self signed certificate
verify return:1
( deleted output )
---
Key-Arg : None
Start Time: 1050024298
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)For these reasons it is strongly recommended to use CA signed certificates!
However, to configure a self-signed certificate, only three entries in
slapd.conf
need to be set (see section 5.1.1):
TLSCACertificateFile server.pem
TLSCertificateFile server.pem
TLSCertificateKeyFile server.pem
4.2 CA Issued Certificate
If you have access to a trusted Certificate Authority (CA), then step through the CA process to get a CA certificate, server certificate and server private key. See section 5.0 for info on how to configure your server with these items.However, if a trusted CA is not available, OpenSSL makes the same process quick and easy.
The steps:
1. Create any directory for creating and signing your certificates.
For example, /var/myca.
% mkdir /var/myca
2. Change to /var/myca and run the OpenSSL CA script (in /usr/share/ssl/misc/ on my box):
% cd /var/myca/
% /usr/share/ssl/misc/CA.sh -newca
CA certificate filename (or enter to create) <enter>
Making CA certificate ...
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..........................++++++
.........................++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase: <ca pass>
Verifying password - Enter PEM pass phrase: <ca pass again>
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Unit
Common Name (eg, YOUR name) []:example.com
Email Address []:.
%This creates demoCA/cacert.pem and demoCA/private/cakey.pem (CA cert and private key).
3. Make your server certificate signing request (CSR):
% openssl req -newkey rsa:1024 -nodes -keyout newreq.pem -out newreq.pem
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..............++++++
..........................++++++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Org Unit
Common Name (eg, YOUR name) []:myserver.com
Email Address []:ldap@myserver.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <pass>
An optional company name []:.
%The result is newreq.pem.
4. Have the CA sign the CSR:
% /usr/share/ssl/misc/CA.sh -sign
Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase: <ca pass>
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'Texas'
localityName :PRINTABLE:'Austin'
organizationName :PRINTABLE:'Example Org'
organizationalUnitName:PRINTABLE:'Example Org Unit'
commonName :PRINTABLE:'myserver.com'
emailAddress :IA5STRING:'ldap@myserver.com'
Certificate is to be certified until Apr 10 18:58:58 2004 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Unit, CN=example.com
Validity
Not Before: Apr 11 18:58:58 2003 GMT
Not After : Apr 10 18:58:58 2004 GMT
Subject: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Org Unit, CN=myserver.com/Email=ldap@myserver.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
< ... >
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
D0:C0:9D:46:30:65:2A:9C:63:63:6A:E6:FE:E4:AC:F7:21:F8:33:61
X509v3 Authority Key Identifier:
keyid:31:2E:0D:FB:A0:74:5A:0B:4B:C5:C4:E0:69:7F:32:6D:AF:46:82:F1
DirName:/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
serial:00
Signature Algorithm: md5WithRSAEncryption
< ... >
-----BEGIN CERTIFICATE-----
< ... >
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
%This creates newcert.pem (server certificate signed by CA) with private key, newreq.pem.
5. Now the certificates can be moved to the desired certificate repository and renamed.
I prefer /usr/var/openldap-data as my certificate directory.
% cp demoCA/cacert.pem /usr/var/openldap-data/cacert.pem
% mv newcert.pem /usr/var/openldap-data/servercrt.pem
% mv newreq.pem /usr/var/openldap-data/serverkey.pem
% chmod 400 /usr/var/openldap-data/serverkey.pemThe last command makes the private key read-only by the user who runs slapd. A 'chown' command will be necessary if the owner of the server key is not the same as the user who runs slapd. The certificates should be publicly readable.
6. Make the CA certificate available to your LDAP clients.
If the client is on the same machine, copy cacert.pem to a location accessible by the client. If clients are on other machines, then cacert.pem will have to be copied to those machines and also made accessible.
This process requires a few more steps than creating a self signed certificate, but the benefits gained outweigh any extra time spent creating the CA.
4.3 Client Certificate
Client certificates are created similarly to server certificates. Using the steps outlined in section 4.2 "CA Issued Certificate", the only changes are as follow:Step 1 and 2: Do nothing ... the CA does not need to be created again. The plan is to use the same CA certificate to sign the client certificate.
Step 3: Same command but actually enter the client's name instead of the server name when prompted for the Common Name. Of course, all of the other responses should be descriptive of the client as well as defining the client's subject DN.
Step 4: Same command with the same resulting files for the cert and private key. Good thing the last certificate was renamed in step 5!
Step 5: Now the certificates can be moved to the user's desired certificate repository and renamed.
(For example, /home/user/certs.)
% mv newcert.pem /home/user/certs/ldap.client.pem
% mv newreq.pem /home/user/certs/keys/ldap.client.key.pem
% chmod 400 /home/user/certs/keys/ldap.client.key.pemThe last command makes the private key read-only by the user who runs the LDAP client. A 'chown' command will be necessary if the owner of the server key is not the same as the user who runs the client. The certificate should be publicly readable.
Step 6: Shouldn't have to do anything here after the previous 'mv' commands were executed.
With the certificates created, only one more step remains before the server can be started: LDAP configuration.
5.0 OpenLDAP Configuration
To configure your OpenLDAP system, there are three areas to consider: server
(slapd.conf), client(ldap.conf), and directory (schema). Please note that this section
will discuss the requirements for server side SSL and client authentication although
a system may be configured without client authentication. A table summarizing all
of the pertinent SSL configuration variations will be presented in
5.4 Configuration Summary.
5.1 Server
Most of the configuration occurs in the slapd daemon configuration file, slapd.conf. Verify that the file corresponding to your new slapd daemon is the one that is being edited before proceeding. Also, the Admin Guide chapter, "Administration Guide, section 5: The slapd Configuration File", goes into more detail than this section and should be reviewed.
5.1.1 Example slapd.conf
The slapd.conf file contains many comments that are very helpful. One of the first states that the file should not be world readable. If it doesn't already have 600 protection mode, make it so.Here is the example slapd.conf with important comments and entries in bold. It is displayed in its entirety due to the importance of the file.
#######################################################################
# $OpenLDAP$
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/etc/openldap/schema/core.schema
include /usr/etc/openldap/schema/cosine.schema
include /usr/etc/openldap/schema/inetorgperson.schema
include /usr/etc/openldap/schema/misc.schema
include /usr/etc/openldap/schema/openldap.schema
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /usr/var/slapd.pid
argsfile /usr/var/slapd.args
# Load dynamic backend modules:
# modulepath /usr/libexec/openldap
# moduleload back_bdb.la
# moduleload back_ldap.la
# moduleload back_ldbm.la
# moduleload back_passwd.la
# moduleload back_shell.la
# Sample security restrictions
#
# Disallow clear text exchange of passwords
# disallow bind_simple_unprotected
#
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
access to *
by self write
by users read
by anonymous auth
#
# if no access controls are present, the default policy is:
# Allow read by all
#
# rootdn can always write!
# CA signed certificate and server cert entries:
TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCACertificateFile /usr/var/openldap-data/cacert.pem
TLSCertificateFile /usr/var/openldap-data/servercrt.pem
TLSCertificateKeyFile /usr/var/openldap-data/serverkey.pem
# Use the following if client authentication is required
TLSVerifyClient demand
# ... or not desired at all
#TLSVerifyClient never
#######################################################################
# ldbm database definitions
#######################################################################
database ldbm
#suffix "dc=my-domain,dc=com"
#rootdn "cn=Manager,dc=my-domain,dc=com"
suffix "dc=myserver,dc=com"
rootdn "cn=Manager,dc=myserver,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
#rootpw secret
rootpw {SSHA}/nM76XvHqgByMF/mplwZ4EuP6EjSPCFc
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /usr/var/openldap-data
# Indices to maintain
index objectClass eq
#######################################################################The important directives in slapd.conf are described in Table 2.
Table 2: LDAP Server Directives
DIRECTIVE VALUE DESCRIPTION include
filename additional configuration files or schema TLSCipherSuite
cipher suite spec describes what ciphers will be accepted TLSCACertificateFile
filename file that contains the certificates of all trusted CA certs TLSCACertificatePath
directory directory containing CA certificates. Usually this or TLSCACertificateFile is used. TLSCertificateFile
filename server certificate filename TLSCertificateKeyFile
filename server private key filename TLSVerifyClient
level Client Authentication: level of checks to perform on incoming client certs ( never | allow | try | demand,hard ) database
type database definition ( bdb | ldap | ldbm | shell | null | sql and others ) suffix
dn suffix DN suffix of queries passed to database backend rootdn
dn DN that is not subject to access control for the database rootpw
password password or hash of password for rootdn directory
directory database directory which must exist prior to starting slapd There are other variables that may be used. Table 2 summarizes a basic set of server configuration directives.
5.2 Client
Depending on the OpenLDAP system installed, "man ldap.conf
" may or may not return all of the information available. If 'TLS OPTIONS' is not displayed, go to the newly installed OpenLDAP system and run the command again. OpenLDAP clients on other machines may not have updated man pages.The
ldap.conf
file sets system-wide defaults for LDAP clients.If user-specific values are required, then the same
ldap.conf
directives should be applied toldaprc
or.ldaprc
files in the user home or current working directories. User-specific entries override global LDAP settings.If implementing client authentication, it is required to add the client certificate and key pair to an ldaprc or .ldaprc file.
5.2.1 LDAP Client Configuration Directives
In the following table, user-only refers to ldaprc or .ldaprc file directives and are not global LDAP directives.
Table 3: LDAP Client Directives
DIRECTIVE VALUE DESCRIPTION BASE
dn default base (DN form) to use when performing ldap operations BINDDN
dn default bind DN to use when performing ldap operations user-only HOST
name[:port] name of LDAP servers to connect to (separate by spaces) PORT
number default port used when connecting to LDAP servers. 636 = SSL! SIZELIMIT
number search return limit (0 = unlimited search) TIMELIMIT
number search time limit (0 = unlimited time) TLS
level whether clients should use TLS by default (never | hard)
use of this directive is discouraged; incompatible with LDAPv3 StartTLS requestTLS_CACERT
filename specifies the file that contains all of the CA certificates the client recognizes TLS_CACERTDIR
directory used if TLS_CACERT fails TLS_REQCERT
level specifies what checks to perform on a server certificate ( never | allow | try | demand,hard ) TLS_CERT
filename Client Authentication: specifies the client certificate user-only TLS_KEY
filename Client Authentication: specifies the private key for TLS_CERT entry user-only
5.2.2 Example ldap.conf
Exampleldap.conf
:
#
# Global LDAP settings
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
HOST myserver.com
PORT 636
TLS_CACERT /etc/ssl/certs/cacert.pem
TLS_REQCERT demandThis configuration will connect to
ldaps://myserver.com:636
without the need to specify the host and port in client commands.
5.2.3 Example ldaprc
Theldaprc
file is used to override global LDAP values and to set the certificate and private key used to establish client authentication.Example
ldaprc
(in user's home or current directory):
#
# User specific LDAP settings
#
# Override global directive (if set)
TLS_REQCERT demand
# client authentication
TLS_CERT /home/ldap-user/certs/client.cert.pem
TLS_KEY /home/ldap-user/certs/keys/client.key.pem
This minimal configuration is all that is required for client authentication.
5.3 Schema
Inslapd.conf
, schema are listed near the top of the file. Initialslapd.conf
files may contain one schema with several commented schemas. The example slapd.conf file added a few other schemas found in the schema directory.Example slapd.conf schema entries:
include /usr/etc/openldap/schema/core.schema
include /usr/etc/openldap/schema/cosine.schema
include /usr/etc/openldap/schema/inetorgperson.schema
include /usr/etc/openldap/schema/misc.schema
include /usr/etc/openldap/schema/openldap.schemaNo additional configuration is necessary to get the server up and running.
5.4 Configuration Summary
There are varying degrees of SSL configuration one may institute. Table 3 summarizes the various directives and values that can be used to set up basic server side SSL ("basic") up to strict server side and client side SSL ("best").Table 4: SSL/TLS Directives
File Directive Basic OK Good Better Best slapd.conf
TLSCACertificateFile
orTLSCACertificatePath
x x x x x TLSCertificateFile
x x x x x TLSCertificateKeyFile
x x x x x TLSCipherSuite
- x x x x TLSVerifyClient
never never allow try demand ldap.conf TLS_CACERT
- x x x x TLS_CACERTDIR (optional)
- x x x x TLS_REQCERT
never never allow try demand ldaprc
or.ldaprc
TLS_CERT
- - - x x TLS_KEY
- - - x x
KEY
- : no entry
x : use directive and enter filename or directory
Note: TLSVerifyClient default is 'never' and TLS_REQCERT default is 'demand'
6.0 Testing the Server
The server is now ready to be started!
% /usr/libexec/slapd -d127 -h "ldap:/// ldaps:///"
|
This starts the server running on the two default ports of 389 (ldap://) and 636 (ldaps://). On my box, the slapd daemon resides in the /usr/libexec/ directory. The "-d127" is a debug level and a value of '-1' will produce max debug output.
There is another way to start the server. A script called "ldap" exists (usually in
/etc/rc.d/init.d) that can be edited to start your LDAP server. Initially, it probably
won't reflect any of the newly created slapd values such as the path to the
slapd
executable nor will it have the flexibility to start LDAP on specific
ports. I find it much easier to use the above command in a separate window and then
be able to view debug output.
If alternate ports are desired, you can also start the server like this:
% /usr/libexec/slapd -d9 -h "ldaps:/// ldaps://:12345"
|
This command only starts the server on SSL ports 636 and 12345. It also uses a debug level of '9' which will display SSL connect information (and less of the other gorp associated with '-d -1').
How do you know if the server is really doing anything? OpenSSL has a utility that verifies the SSL connection and you can also add some entries and then search for them via an OpenLDAP client.
6.1 SSL Connection Check
To check the SSL connection, try this command:
% openssl s_client -connect localhost:636 -showcerts -state -CAfile <ca cert>
If the LDAP server is not executing on your client machine, "localhost" must be substituted with the server name, e.g. "myserver.com".
Also, to verify the server certificate, you must provide the client CA certificate to the CAfile argument. Why does the CA certificate have to be specified if it already is in ldap.conf? Because the command is an OpenSSL client command and not an LDAP client command.
The command can also be used to verify a TLS connection on non-ldaps ports, e.g. port 389.
Good output looks like this (edited):
OpenSSL Output Using Server Side SSL
% openssl s_client -connect myserver.com:636 -showcerts -state \
-CAfile /var/cacert/cacert.pem
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=1 /C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
verify return:1
depth=0 /C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Org Unit/CN=myserver.com/Email=ldap@myserver.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
( ... Certificate chain output deleted ... )
---
No client certificate CA names sent
---
SSL handshake has read 1804 bytes and written 314 bytes
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 1024 bit
SSL-Session:
Protocol : TLSv1
Cipher : DES-CBC3-SHA
Session-ID: E7E1D275B86A9695BEB1B15E4C0E681F55505016A6AC9F4E55B88FD...
Session-ID-ctx:
Master-Key: 2DC9724A4978BEF82B7FCCE6FA3E72C55C3D6A915AD7B7FC8E0F...
Key-Arg : None
Start Time: 1050452423
Timeout : 300 (sec)
Verify return code: 0 (ok)
---The command will hang after the final return code output. This is normal. "Control-c" will end the command.
The line
"No client certificate CA names sent"
is indicative of a server side SSL set up. If client authentication had been configured, the OpenSSL command and output would resemble this:OpenSSL Output Using Client Authentication
Note the extra SSL handshake output in bold.
% openssl s_client -connect myserver.com:636 -state \
-CAfile /var/cacert/cacert.pem \
-cert /home/ldap-user/certs/client.cert.pem \
-key /home/ldap-user/certs/keys/client.key.pem
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=1 /C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
verify return:1
depth=0 /C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Org Unit/CN=myserver.com/Email=ldap@myserver.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
( ... Certificate chain output deleted ... )
subject=/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Org Unit/CN=myserver.com/Email=ldap@myserver.com
issuer=/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
---
Acceptable client certificate CA names
/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
---
SSL handshake has read 1916 bytes and written 2102 bytes
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 1024 bit
SSL-Session:
Protocol : TLSv1
Cipher : DES-CBC3-SHA
Session-ID: 96B9C18DAC585050EDC30C1BB7792A6C33C44F2DDB98EBAEBEC68B270...
Session-ID-ctx:
Master-Key: 540C7F9FAD1CBE503C9A3BA5D47A76A005BDEEEB1908F270669D32...
Key-Arg : None
Start Time: 1052237883
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
6.2 OpenLDAP client commands
OpenLDAP has several client commands. Most common: ldapsearch, ldapadd, ldapmodify, and ldapdelete. This document will show example commands but will not explain the details of their operation. Please consult the man pages for more details.The sections that follow show examples that add entries to the LDAP directory and then search the directory for various entries.
6.2.1 Adding Entries
Using any editor, copy and paste the following LDIF file to "init.ldif". Any leading and trailing white space should be eliminated. Change the DN values to mirror yourslapd.conf
suffix values. For example if your suffix is"dc=ldap,dc=com"
, then the DN entries below would be"dn: dc=ldap,dc=com"
.init.ldif
#init.ldif
dn: dc=myserver,dc=com
objectclass: dcObject
objectclass: organization
o: Example Org
dc: myserver
dn: cn=my-name,dc=myserver,dc=com
objectclass: organizationalRole
cn: my-name
dn: ou=my system,dc=myserver,dc=com
objectclass: organizationalUnit
ou: my system
description: Test organizational unit to hold admin user
dn: cn=mr admin,ou=my system,dc=myserver,dc=com
objectclass: person
userPassword: testpass
description: mr admin test user
cn: mr admin
sn: adminNow add the LDIF entries to the LDAP database (using your rootdn):
% ldapadd -x -D "cn=Manager,dc=myserver,dc=com" -W -f init.ldif
You will be prompted for the rootpw because of the "-W" argument. If successful, you will see four "adding new entry <entry>" lines.
To ensure an SSL connection, you can specify a host with: "-H ldaps://myserver.com". This argument is needed if the host is not set on a stand alone client.
6.2.2 Searching the Directory
Use the following commands to search the directory. To understand the different command flags, consult the man pages for ldapsearch. In all of the commands that follow, the argument ' -D "cn=Manager,dc=myserver,dc=com" ' is necessary because of this access block in slapd.conf:
access to *
by self write
by users read
by anonymous authIf this block had been commented out as in a default
slapd.conf
, then none of the "-D" arguments would be needed in the ldapsearch commands here and in the following sections.Return all entries
Client on same machine:
% ldapsearch -x -b 'dc=myserver,dc=com' -D "cn=Manager,dc=myserver,dc=com" '(objectclass=*)' -W
Stand alone LDAP client:
% ldapsearch -x -b 'dc=myserver,dc=com' -D "cn=Manager,dc=myserver,dc=com" '(objectclass=*)' -H ldaps://myserver.com -W
The output should look like:
version: 2
#
# filter: (objectclass=*)
# requesting: ALL
#
# myserver, com
dn: dc=myserver,dc=com
objectClass: dcObject
objectClass: organization
o: Example Org
dc: myserver
# my-name, myserver, com
dn: cn=my-name,dc=myserver,dc=com
objectClass: organizationalRole
cn: my-name
# my system, myserver, com
dn: ou=my system,dc=myserver,dc=com
objectClass: organizationalUnit
ou: my system
description: Test organizational unit to hold admin user
# mr admin, my system, myserver, com
dn: cn=mr admin,ou=my system,dc=myserver,dc=com
objectClass: person
userPassword:: dGVzdHBhc3M=
description: mr admin test user
cn: mr admin
sn: admin
# search result
search: 2
result: 0 Success
# numResponses: 5
# numEntries: 4
%Return some entries (part one)
Command with output:
% ldapsearch -x -b 'cn=my-name,dc=myserver,dc=com' -D"cn=Manager,dc=myserver,dc=com" -H ldaps://myserver.com '(objectclass=*)' -w secret
version: 2
#
# filter: (objectclass=*)
# requesting: ALL
#
# my-name, myserver, com
dn: cn=my-name,dc=myserver,dc=com
objectClass: organizationalRole
cn: my-name
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1Return some entries (part two)
Command with output:
% ldapsearch -x -b 'ou=my system,dc=myserver,dc=com' -D"cn=Manager,dc=myserver,dc=com" -H ldaps://myserver.com '(objectclass=*)' -w secret
version: 2
#
# filter: (objectclass=*)
# requesting: ALL
#
# my system, myserver, com
dn: ou=my system,dc=myserver,dc=com
objectClass: organizationalUnit
ou: my system
description: Test organizational unit to hold admin user
# mr admin, my system, myserver, com
dn: cn=mr admin,ou=my system,dc=myserver,dc=com
objectClass: person
userPassword:: dGVzdHBhc3M=
description: mr admin test user
cn: mr admin
sn: admin
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
7.0 Using TLS
Up to this point, most of the document has dealt with SSL and not TLS. SSL
connections are always encrypted while TLS connections give the client the option
to upgrade to an encrypted connection.
TLS requires the same configuration settings as SSL. Upon examination, all of the important SSL directives start with "TLS" in section 5.4 "Configuration Summary" which should have tipped you off to the dual relationship.
However, simply accessing ldap://:389 does not ensure a TLS encrypted
connection. Accessing ldaps:// is not a TLS connection either. In order to use TLS
over an ldap:// connection, add a ldap_start_tls_s()
call to your
client code:
int rc, port=389;
|
Another difference between SSL and TLS in the above code is that SSL doesn't
use ldap_init()
. Instead it uses ldap_initialize(**LDAP,
string)
where the string is a URI, e.g. "ldaps://myserver.com:636".
Attempting to use ldap_init()
over SSL will cause a broken pipe error.
Also, attempting to call ldap_start_tls_s()
when an SSL connection
is already utilized will also be in error.
Another TLS method that can be used is to add a "-Z" or "-ZZ" flag to client commands:
% ldapsearch -x -b 'dc=myserver,dc=com'
-D "cn=Manager,dc=myserver,dc=com" '(objectclass=*)'
-H ldaps://myserver.com -W -ZZ
|
The "-ZZ" flag forces TLS handshake to be successful. The single "-Z" flag tries to enable TLS and will proceed without using encrypted connections if the TLS handshake fails.
It would be nice to set a TLS configuration directive in either
slapd.conf
or ldap.conf
but my attempts to do so
have not resulted in a successful TLS handshake in the server output.
OpenLDAP documentation does suggest using a "Start TLS"
call in a configuration file which has not been successful for me.
8.0 Summary
As can be seen, enabling SSL/TLS on an OpenLDAP server and client can be
achieved quickly. If client authentication is desired, then only a few more steps
and changes are required. OpenLDAP manages the SSL connection once it knows
where the server and CA certificates (client side) reside.
Although enabling an SSL connection to a server is straight forward if the steps outlined in this document are followed, problems can arise when trying to execute the LDAP client. OpenLDAP is sophisticated software with several nuances that take experience to understand and use correctly. Execution errors can arise when the following occurs:
... just to name a few. However most problems with OpenLDAP are the result of human error and they will appear less frequently as OpenLDAP is more often utilized.