Configuring OpenLDAP for Linux Authentication

By | 2018-07-24

This guide will walk you through setting up an OpenLDAP server for authenticating and managing users on Linux and UNIX. I am assuming you already have the OpenLDAP server installed and running with no backends configured. I recommend installing OpenLDAP from source, but this guide should work if you installed from a repository. I have included links to guides for setting up clients at the bottom of this page. If you want to install from source and need help, here are my guides and the official OpenLDAP documentation:

Design Directory Structure

First, you will need to choose a suffix. A suffix is the root of your directory tree. Conventionally, this is your site’s domain name broken up by domain components. For example, tylersguides.com would have a suffix of dc=tylersguides,dc=com. I recommend following the convention, but feel free to choose something else.

Most sites organize directory entries into organizational units (OU)s. OUs allow you to organize your entries to make them easier to find and manage. In the example, I will create three OUs. One OU is for users, another is for groups, and the last is for service accounts. I recommend creating a separate OU for service accounts. Putting service accounts in their own OU prevents accidental deletion. OUs can contain other OUs, so if you want to add depth to your organization, you can do so. For example, if your organization hires a lot of contractors, you might want to create an OU for employees and an OU for contractors inside the users OU.

Choose a Database Directory

Choose a location on your filesystem to store your database files. The default is /var/lib/ldap. The example uses /ldapdata. Once you decide where to put it, create it and set the proper permissions. Use the table to determine what to replace OWNER with.

mkdir /ldapdata
chown OWNER /ldapdata
chmod 750 /ldapdata
OS OWNER
CentOS 7 ldap:ldap
openSUSE ldap:ldap
Debian (Stretch) openldap:openldap
FreeBSD ldap:ldap

Password Hashes

You will need to generate two password hashes. One is for the admin user, the second is for the OS service user. Use slappasswd to do this. By default OpenLDAP uses salted SHA-1 for storing passwords. Cryptography experts no longer consider SHA-1 secure. OpenLDAP comes with a module that supports SHA-2 hashes. The examples will use salted SHA-512 for password storage. The FreeBSD binary package does not include this module, so you must install from ports or source to get this functionality. If you used the OpenSUSE repository, make sure the openldap2-contrib package is installed. In order for slappasswd to use salted SHA-512, you must provide the module name and path. If you installed from source, I am assuming you used one of the guides on this site. You need to adjust your path otherwise. Use the following example and table to generate password hashes:

slappasswd -h "{SSHA512}" -o module-load=pw-sha2.la -o module-path=PATH
OS PATH
CentOS 7 /usr/lib64/openldap/
openSUSE /usr/lib64/openldap/
Debian (Stretch) /usr/lib/ldap/
FreeBSD /usr/local/libexec/openldap/
Source (Tyler’s Guides) /opt/openldap-current/libexec/openldap
Source (default) /usr/local/libexec/openldap

Configure the Database

You need to configure a database before adding entries. The OpenLDAP developers recommend using the MDB back end. By default, MDB limits the size of the database to 10MB. You can change this by adding the olcDbMaxSize attribute; specify the max size in bytes. If it reaches the maximum, you will not be able to add new entries. For this reason, monitor the size of your database directory and be generous with the limit you set. A good rule of thumb is 3MB per 1000 entires.

Create your database by creating the following LDIF file and loading it. Replace the highlighted entries with what is relevant for your site. Replace HASH with a hash generated with slappasswd; make sure to include {SSHA512}. This password will have full access to your database, so choose a good password.

dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=tylersguides,dc=com
olcRootDN: cn=admin,dc=tylersguides,dc=com
olcRootPW: HASH
olcDbDirectory:	/ldapdata
olcDbIndex: objectClass,uid,uidNumber,gidNumber eq
olcDbMaxSize: 10485760
olcAccess: to attrs=userPassword
  by self write
  by anonymous auth
  by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
olcAccess: to attrs=shadowLastChange by self write
  by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by dn.subtree="ou=system,dc=tylersguides,dc=com" read
  by * none
olcAccess: to dn.subtree="ou=system,dc=tylersguides,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
olcAccess: to dn.subtree="dc=tylersguides,dc=com" by dn.subtree="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by users read 
  by * none

Add the database:

ldapadd -Y EXTERNAL -H ldapi:/// -f databases.ldif

Create an LDIF file to create your directory structure. Replace the highlighted parts with what is relevant for your site.

dn: dc=tylersguides,dc=com
objectClass: dcObject
objectClass: organization
objectClass: top
o: Tyler's Guides
dc: tylersguides

dn: ou=groups,dc=tylersguides,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups

dn: ou=users,dc=tylersguides,dc=com
objectClass: organizationalUnit
objectClass: top
ou: users

dn: ou=system,dc=tylersguides,dc=com
objectClass: organizationalUnit
objectClass: top
ou: system

Create a Proxy User

In order for the OS to resolve UIDs and GIDs, it needs a user to query the directory server with. Add the following to the LDIF you created in the previous step. Create the password hash with slappasswd. Make sure there is a blank line in your file between the last line of the previous step and the first line of this step. Again, replace the highlighted parts.

dn: cn=osproxy,ou=system,dc=tylersguides,dc=com
objectClass: organizationalRole
objectClass: simpleSecurityObject
cn: osproxy
userPassword: HASH
description: OS proxy for resolving UIDs/GIDs

Create a Test User and Group

Add the following to the LDIF file from the previous two steps to create a test user and group. As before, make sure you have a blank line in your file between this step and the previous step.

dn: cn=testgroup,ou=groups,dc=tylersguides,dc=com
objectClass: posixGroup
cn: testgroup
gidNumber: 5000
memberUid: testuser

dn: uid=testuser,ou=users,dc=tylersguides,dc=com
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: First Name
sn: Last Name
uid: testuser
uidNumber: 5000
gidNumber: 5000
homeDirectory: /home/testuser
loginShell: /bin/sh
gecos: Full Name

Load Test Data

Load the test data with ldapadd.

ldapadd -Y EXTERNAL -H ldapi:/// -f testdata.ldif

Now set a password for the test user and ensure you can bind to the directory server with it:

root@ldap:~# ldappasswd -Y EXTERNAL -H ldapi:/// -S "uid=testuser,ou=users,dc=tylersguides,dc=com"
root@ldap:~# ldapsearch -x -W -H ldapi:/// \
-D "uid=testuser,ou=users,dc=tylersguides,dc=com" \
-b "ou=users,dc=tylersguides,dc=com"

If all is well, you will see the attributes of your test user.

Client Configuration and Management

Now that you have a basic server configuration, it is time to configure a client and test it. Consult the relevant guide on this site or your OS documentation if you need help doing this. I have guides for CentOS 7, Debian Stretch, and OpenSUSE LEAP 15.

Once you have your client configuration working, it is time to think about managing your server. Some things to consider: