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).
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:
The OpenLDAP configuration is done in the file /usr/local/etc/openldap/slapd.conf
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
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"
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
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.
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/"'
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.
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
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.
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
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.
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
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
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
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.
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).
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
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/"
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.