Published : 2014-02-26

OpenLDAP

OpenLDAP is the reference open-source directory. It includes all the features you can expect from a directory, and is based on a schema system. Each schema defines a set of attributes and associated constraints that will define the associated object.

An LDAP directory is based on a tree of objects, each identified by a DN (distinguished name), distributed in organizational units (OU) under a root (origin).

OpenLDAP Installation

Under FreeBSD, we will install OpenLDAP 2.4

cd /usr/ports/net/openldap24-server
make install clean

Select the following options according to your needs:

  • Fetch
  • BDB
  • Passwd
  • Sock
  • ODBC
  • TCP_Wrappers
  • Collect
  • DynGroup
  • DynList
  • PPolicy
  • ProxyCache
  • SeqMode
  • Unique
  • Valsort
  • SmbPwd
  • Dynamic-Backends

Configuration

The OpenLDAP configuration is done in the file /usr/local/etc/openldap/slapd.conf

Base schemas

We will add some base schemas useful to the directory, allowing us to define what a person is, an organizational unit, and the posix schema needed for UNIX systems to rely on it (order matters):

include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
include         /usr/local/etc/openldap/schema/misc.schema
include         /usr/local/etc/openldap/schema/nis.schema
include         /usr/local/etc/openldap/schema/openldap.schema

LDAP root

We now need to configure the root of the directory. Edit the following line (this may not match your domain name):

suffix          "dc=unix-experience,dc=fr"

LDAP super user

The LDAP root user is the object that has all the powers on the directory; it does not necessarily exist visibly in the tree and can even be in a path that does not exist:

rootdn          "cn=admin,dc=unix-experience,dc=fr"

To assign it an encrypted password, run the following command:

slappasswd -s motdepasse
{SSHA}DRA+C7TAbDR+tWdD9x6cQBPnDKafBCLvY

Then add the result of the command to the slapd.conf file, as follows:

rootpw {SSHA}DRA+C7TAbDR+tWdD9x6cQBPnDKafBCLvY

Starting the OpenLDAP service

The directory is now configured in a basic way, we will now be able to populate it and create its root.

service slapd start

Create a root.ldif file and enter the following data:

dn: dc=unix-experience,dc=fr
dc: unix-experience
objectClass: dcObject
objectClass: organization
o: unix-experience

dn: ou=people,dc=unix-experience,dc=fr
objectClass: top
objectClass: organizationalUnit
ou: people

The first entry is the LDAP origin, the second one is a first organizational unit containing the users in standard configurations.

We now inject it into the directory:

ldapadd -f root.ldif -D cn=admin,dc=unix-experience,dc=fr -W

To verify that your data is present, dump the whole directory:

slapcat

We could have run a search on the whole directory:

ldapsearch -b dc=unix-experience,dc=fr

Note that no authentication is requested; that’s because we are on the LDAP server itself.

SSL Support

A directory is one of the most sensitive elements of an information system. The data it contains can be extremely sensitive, so it should be encrypted so that it cannot be intercepted or altered. We will add the SSL encryption layer to the LDAP protocol.

First we create a certificate:

openssl req -x509 -new -out ldap_cert.pem -keyout ldap_key.pem -days 3650 -nodes

Then we define the path to the certificates for the OpenLDAP service:

TLSCertificateFile /usr/local/etc/openldap/ldap_cert.pem
TLSCertificateKeyFile /usr/local/etc/openldap/ldap_key.pem

And finally we enable SSL support by adding the flags to the service in the /etc/rc.conf file:

slapd_flags='-h "ldaps://0.0.0.0/ ldap://0.0.0.0/"'

SMB/MS-CHAP schema integration

To integrate the SMB schema into our directory and thus be able to use MS-CHAPv2 authentication or even act as an Active Directory domain controller, we need some additional tools:

cd /usr/ports/net/samba36
make KRB5_HOME=/usr/local
make install clean
cd /usr/ports/net/smbldap-tools
make install clean

We copy the schema:

cp /usr/local/share/examples/samba36/LDAP/samba.schema /usr/local/etc/openldap/schema/

and integrate it in the slapd.conf:

include         /usr/local/etc/openldap/schema/samba.schema

More information on managing this schema will be added later.

Supann schema integration (higher education)

Copy the content of this file into the file /usr/local/etc/openldap/schema/supann.schema and remove the comments with accented characters that could prevent OpenLDAP from starting.

Then add the schema to OpenLDAP:

include         /usr/local/etc/openldap/schema/supann.schema

OpenLDAP replication

Since OpenLDAP version 2.4, it includes an LDAP replication mechanism. It was previously possible to configure master/slave servers, but this feature is more interesting in a high-availability context and allows load balancing.

When a piece of data is altered on one of the nodes, as soon as the replication queue is available, it will send an LDAP order to define the update on the other nodes.

If you didn’t enable it at compile time, enable the syncprov module and recompile OpenLDAP.

Replication user configuration

It is not recommended to use the superuser for replication, so we will configure a replication account:

dn: cn=replicator,ou=system,dc=unixperience,dc=it
objectClass: top
objectClass: organizationalPerson
userPassword: {SSHA}cqz/RnlJiooZ12aseBczGK87VrpR25mZ
sn: replicator
ldapadd -Z -c -f replica.ldif -D cn=admin,dc=unixperience,dc=it -W

Open the slapd.conf file to give write rights to the replication user:

access to *
        by self write
        by dn="cn=replicator,ou=system,dc=unixperience,dc=it" write
        by anonymous auth

Replication configuration

Each LDAP node has a serverID identifying it within the LDAP cluster and a RID (replication ID) which must be identical on every node.

serverID        1
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100
syncrepl        rid=1
        provider=ldap://ldap2.unixperience.it:389/
        bindmethod=simple
        binddn="cn=replicator,ou=system,dc=unixperience,dc=it"
        credentials=r3pl1c@t0r
        searchbase="dc=unixperience,dc=it"
        schemachecking=on
        type=refreshAndPersist
        retry="5 +"
mirrormode on

The searchbase directive is handy because it allows to perform only a partial replication of the directory by selecting a branch.

The retry directive defines a delay before retrying, here 5 seconds. The + symbol defines a retry loop. It is possible to define more specific periods by writing retry=“5 10 30 60 180 +”, which will try again after 5, 10, 30… seconds.

The checkpoint directives are extremely important, and positioning them as here should satisfy your usual needs.

Security improvements

Prevent password visibility

For security, you can prevent users from seeing their password in the directory. Add the following rules, before the global access rule:

access to attrs=userPassword
        by self =wx
        by * =x

Performance improvements

Cache configuration

In the case of a very large directory (more than 3000 users), with a huge number of attributes, it may be necessary to properly manage the LDAP cache. To allow OpenLDAP to use more memory for its cache, first copy the following file:

cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG

and edit the following line (here we assign 768MB of RAM to the cache):

 set_cachesize 0 768435456 1

Indexing configuration

When searching, the concept of index is fundamental. Some attributes of a directory can be requested to reference a user and find them regularly. In this case, it is appropriate to reorganize the OpenLDAP database by indexing efficiently. Add for instance the following line:

index   cn,uid          eq

Indexing is done cold. Stop the service and run the following command (before restarting it):

slapindex

Day-to-day operations

General commands

Adding entries to the directory

The command to add entries to the LDAP directory is:

ldapadd -f /path/file.ldif

You can also use ldapmodify:

ldapmodify -a -f /path/file.ldif

If you are not on the machine hosting the directory or if you have disabled unauthenticated modifications, type the following command (it is not necessary to use the LDAP superuser, a user with write rights is enough):

ldapadd -x -D "cn=admin,dc=unix-experience,dc=fr" -W -f /path/file.ldif

Warning! ldapadd does not merge an entry; if it exists, the command will fail and move on to the next entry.

Deleting an entry from the directory

The command is very simple:

ldapdelete <dn>
ldapdelete < /path/file
ldapdelete -f /path/file

In the case of files, this is a list of DNs (one DN per line).

Add a group

If it doesn’t exist, you can add a dedicated OU for groups, to keep a clear view of the directory:

dn: ou=groups,dc=unix-experience,dc=fr
objectclass:organizationalunit
ou: groups
description: generic groups branch

Here is now a simple ldif file containing a group:

dn: cn=unixadm,ou=groups,dc=unix-experience,dc=fr
objectclass: groupofnames
cn: unixadm
description: UNIX admins
member: cn=titi.toto,ou=people,dc=unix-experience,dc=fr
member: cn=misc.user,ou=people,dc=unix-experience,dc=fr

OpenLDAP troubleshooting

If you notice that OpenLDAP does not start, or takes an extremely long time to start, after the startup command has been issued, kill the command and start OpenLDAP in debug mode. To do this, take your slapd command line and add the -d 50 option. Example:

/usr/local/libexec/slapd -d 50 -h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/ ldap://0.0.0.0/ ldaps://0.0.0.0/"

Case of “unable to join the environment”

This means that your LDAP database is inconsistent and OpenLDAP doesn’t understand the context of the database (bdb backend). You need to perform a recovery of the database via the associated OpenLDAP/bdb commands. To do this, simply type the following command (change the version to your bdb version or later, and the path to your distribution, here FreeBSD):

db-recover4.6 -h /var/db/openldap-data

Wait, normally nothing is displayed and after a while you get your prompt back. You should now be able to start OpenLDAP, the debug mode will show you whether it worked.

Clean up OpenLDAP logs