OpenLDAP Server

LDAP is an acronym for Lightweight Directory Access Protocol, it is a simplified version of the X.500 protocol. The directory setup in this section will be used for authentication. Nevertheless, LDAP can be used in numerous ways: authentication, shared directory (for mail clients), address book, etc.

To describe LDAP quickly, all information is stored in a tree structure. With OpenLDAP you have freedom to determine the directory arborescence (the Directory Information Tree: the DIT) yourself. We will begin with a basic tree containing two nodes below the root:

  • "People" node where your users will be stored

  • "Groups" node where your groups will be stored

Before beginning, you should determine what the root of your LDAP directory will be. By default, your tree will be determined by your Fully Qualified Domain Name (FQDN). If your domain is example.com (which we will use in this example), your root node will be dc=example,dc=com.

Installation

First, install the OpenLDAP server daemon slapd and ldap-utils, a package containing LDAP management utilities:

sudo apt-get install slapd ldap-utils

By default slapd is configured with minimal options needed to run the slapd daemon.

The configuration example in the following sections will match the domain name of the server. For example, if the machine's Fully Qualified Domain Name (FQDN) is ldap.example.com, the default suffix will be dc=example,dc=com.

Populating LDAP

OpenLDAP uses a separate directory which contains the cn=config Directory Information Tree (DIT). The cn=config DIT is used to dynamically configure the slapd daemon, allowing the modification of schema definitions, indexes, ACLs, etc without stopping the service.

The backend cn=config directory has only a minimal configuration and will need additional configuration options in order to populate the frontend directory. The frontend will be populated with a "classical" scheme that will be compatible with address book applications and with Unix Posix accounts. Posix accounts will allow authentication to various applications, such as web applications, email Mail Transfer Agent (MTA) applications, etc.

[Note]

For external applications to authenticate using LDAP they will each need to be specifically configured to do so. Refer to the individual application documentation for details.

[Note]

Remember to change dc=example,dc=com in the following examples to match your LDAP configuration.

First, some additional schema files need to be loaded. In a terminal enter:

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif

Next, copy the following example LDIF file, naming it backend.example.com.ldif, somewhere on your system:

# Load dynamic backend modules
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: back_hdb

# Database settings
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcSuffix: dc=example,dc=com
olcDbDirectory: /var/lib/ldap
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: secret
olcDbConfig: set_cachesize 0 2097152 0
olcDbConfig: set_lk_max_objects 1500
olcDbConfig: set_lk_max_locks 1500
olcDbConfig: set_lk_max_lockers 1500
olcDbIndex: objectClass eq
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcAccess: to attrs=userPassword by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
olcAccess: to attrs=shadowLastChange by self write by * read
olcAccess: to dn.base="" by * read
olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read

[Note]

Change olcRootPW: secret to a password of your choosing.

Now add the LDIF to the directory:

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend.example.com.ldif

The frontend directory is now ready to be populated. Create a frontend.example.com.ldif with the following contents:

# Create top-level object in domain
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: Example Organization
dc: Example
description: LDAP Example 

# Admin user.
dn: cn=admin,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: secret

dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

dn: uid=john,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: john
sn: Doe
givenName: John
cn: John Doe
displayName: John Doe
uidNumber: 1000
gidNumber: 10000
userPassword: password
gecos: John Doe
loginShell: /bin/bash
homeDirectory: /home/john
shadowExpire: -1
shadowFlag: 0
shadowWarning: 7
shadowMin: 8
shadowMax: 999999
shadowLastChange: 10877
mail: [email protected]
postalCode: 31000
l: Toulouse
o: Example
mobile: +33 (0)6 xx xx xx xx
homePhone: +33 (0)5 xx xx xx xx
title: System Administrator
postalAddress: 
initials: JD

dn: cn=example,ou=groups,dc=example,dc=com
objectClass: posixGroup
cn: example
gidNumber: 10000

In this example the directory structure, a user, and a group have been setup. In other examples you might see the objectClass: top added in every entry, but that is the default behaviour so you do not have to add it explicitly.

Add the entries to the LDAP directory:

sudo ldapadd -x -D cn=admin,dc=example,dc=com -W -f frontend.example.com.ldif

We can check that the content has been correctly added with the ldapsearch utility. Execute a search of the LDAP directory:

ldapsearch -xLLL -b "dc=example,dc=com" uid=john sn givenName cn

dn: uid=john,ou=people,dc=example,dc=com
cn: John Doe
sn: Doe
givenName: John

Just a quick explanation:

  • -x: will not use SASL authentication method, which is the default.

  • -LLL: disable printing LDIF schema information.

Further Configuration

The cn=config tree can be manipulated using the utilities in the ldap-utils package. For example:

  • Use ldapsearch to view the tree, entering the admin password set during installation or reconfiguration:

    sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
    
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: cn=config
    
    dn: cn=module{0},cn=config
    
    dn: cn=schema,cn=config
    
    dn: cn={0}core,cn=schema,cn=config
    
    dn: cn={1}cosine,cn=schema,cn=config
    
    dn: cn={2}nis,cn=schema,cn=config
    
    dn: cn={3}inetorgperson,cn=schema,cn=config
    
    dn: olcDatabase={-1}frontend,cn=config
    
    dn: olcDatabase={0}config,cn=config
    
    dn: olcDatabase={1}hdb,cn=config
    
    

    The output above is the current configuration options for the cn=config backend database. Your output may be vary.

  • As an example of modifying the cn=config tree, add another attribute to the index list using ldapmodify:

    sudo ldapmodify -Y EXTERNAL -H ldapi:///
    
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: olcDatabase={1}hdb,cn=config
    add: olcDbIndex
    olcDbIndex: uidNumber eq
    
    modifying entry "olcDatabase={1}hdb,cn=config"
    
    

    Once the modification has completed, press Ctrl+D to exit the utility.

  • ldapmodify can also read the changes from a file. Copy and paste the following into a file named uid_index.ldif:

    dn: olcDatabase={1}hdb,cn=config
    add: olcDbIndex
    olcDbIndex: uid eq,pres,sub
    

    Then execute ldapmodify:

    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f uid_index.ldif
    
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    modifying entry "olcDatabase={1}hdb,cn=config"
    
    

    The file method is very useful for large changes.

  • Adding additional schemas to slapd requires the schema to be converted to LDIF format. The /etc/ldap/schema directory contains some schema files already converted to LDIF format as demonstrated in the previous section. Fortunately, the slapd program can be used to automate the conversion. The following example will add the dyngoup.schema:

    1. First, create a conversion schema_convert.conf file containing the following lines:

      include /etc/ldap/schema/core.schema
      include /etc/ldap/schema/collective.schema
      include /etc/ldap/schema/corba.schema
      include /etc/ldap/schema/cosine.schema
      include /etc/ldap/schema/duaconf.schema
      include /etc/ldap/schema/dyngroup.schema
      include /etc/ldap/schema/inetorgperson.schema
      include /etc/ldap/schema/java.schema
      include /etc/ldap/schema/misc.schema
      include /etc/ldap/schema/nis.schema
      include /etc/ldap/schema/openldap.schema
      include /etc/ldap/schema/ppolicy.schema
      
    2. Next, create a temporary directory to hold the output:

      mkdir /tmp/ldif_output
      
    3. Now using slapcat convert the schema files to LDIF:

      slapcat -f schema_convert.conf -F /tmp/ldif_output -n0 -s "cn={5}dyngroup,cn=schema,cn=config" > /tmp/cn=dyngroup.ldif
      

      Adjust the configuration file name and temporary directory names if yours are different. Also, it may be worthwhile to keep the ldif_output directory around in case you want to add additional schemas in the future.

    4. Edit the /tmp/cn\=dyngroup.ldif file, changing the following attributes:

      dn: cn=dyngroup,cn=schema,cn=config
      ...
      cn: dyngroup
      

      And remove the following lines from the bottom of the file:

      structuralObjectClass: olcSchemaConfig
      entryUUID: 10dae0ea-0760-102d-80d3-f9366b7f7757
      creatorsName: cn=config
      createTimestamp: 20080826021140Z
      entryCSN: 20080826021140.791425Z#000000#000#000000
      modifiersName: cn=config
      modifyTimestamp: 20080826021140Z
      
      [Note]

      The attribute values will vary, just be sure the attributes are removed.

    5. Finally, using the ldapadd utility, add the new schema to the directory:

      sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /tmp/cn\=dyngroup.ldif
      

    There should now be a dn: cn={4}dyngroup,cn=schema,cn=config entry in the cn=config tree.

LDAP Replication

LDAP often quickly becomes a highly critical service to the network. Multiple systems will come to depend on LDAP for authentication, authorization, configuration, etc. It is a good idea to setup a redundant system through replication.

Replication is achieved using the Syncrepl engine. Syncrepl allows the changes to be synced using a consumer, provider model. A provider sends directory changes to consumers.

Provider Configuration

The following is an example of a Single-Master configuration. In this configuration one OpenLDAP server is configured as a provider and another as a consumer.

  1. First, configure the provider server. Copy the following to a file named provider_sync.ldif:

    # Add indexes to the frontend db.
    dn: olcDatabase={1}hdb,cn=config
    changetype: modify
    add: olcDbIndex
    olcDbIndex: entryCSN eq
    -
    add: olcDbIndex
    olcDbIndex: entryUUID eq
    
    #Load the syncprov and accesslog modules.
    dn: cn=module{0},cn=config
    changetype: modify
    add: olcModuleLoad
    olcModuleLoad: syncprov
    -
    add: olcModuleLoad
    olcModuleLoad: accesslog
    
    # Accesslog database definitions
    dn: olcDatabase={2}hdb,cn=config
    objectClass: olcDatabaseConfig
    objectClass: olcHdbConfig
    olcDatabase: {2}hdb
    olcDbDirectory: /var/lib/ldap/accesslog
    olcSuffix: cn=accesslog
    olcRootDN: cn=admin,dc=example,dc=com
    olcDbIndex: default eq
    olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart
    
    # Accesslog db syncprov.
    dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
    changetype: add
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: syncprov
    olcSpNoPresent: TRUE
    olcSpReloadHint: TRUE
    
    # syncrepl Provider for primary db
    dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config
    changetype: add
    objectClass: olcOverlayConfig
    objectClass: olcSyncProvConfig
    olcOverlay: syncprov
    olcSpNoPresent: TRUE
    
    # accesslog overlay definitions for primary db
    dn: olcOverlay=accesslog,olcDatabase={1}hdb,cn=config
    objectClass: olcOverlayConfig
    objectClass: olcAccessLogConfig
    olcOverlay: accesslog
    olcAccessLogDB: cn=accesslog
    olcAccessLogOps: writes
    olcAccessLogSuccess: TRUE
    # scan the accesslog DB every day, and purge entries older than 7 days
    olcAccessLogPurge: 07+00:00 01+00:00
    
  2. The AppArmor profile for slapd will need to be adjusted for the accesslog database location. Edit /etc/apparmor.d/usr.sbin.slapd adding:

      /var/lib/ldap/accesslog/ r,
      /var/lib/ldap/accesslog/** rwk,
    

    Then create the directory, reload the apparmor profile, and copy the DB_CONFIG file:

    sudo -u openldap mkdir /var/lib/ldap/accesslog
    sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog/
    sudo /etc/init.d/apparmor reload
    
    [Note]

    Using the -u openldap option with the sudo commands above removes the need to adjust permissions for the new directory later.

  3. Edit the file and change the olcRootDN to match your directory:

    olcRootDN: cn=admin,dc=example,dc=com
    
  4. Next, add the LDIF file using the ldapadd utility:

    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif
    
  5. Restart slapd:

    sudo /etc/init.d/slapd restart
    

The Provider server is now configured, and it is time to configure a Consumer server.

Consumer Configuration

  1. On the Consumer server configure it the same as the Provider except for the Syncrepl configuration steps.

    Add the additional schema files:

    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
    

    Also, create, or copy from the provider server, the backend.example.com.ldif

    # Load dynamic backend modules
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModulepath: /usr/lib/ldap
    olcModuleload: back_hdb
    
    # Database settings
    dn: olcDatabase=hdb,cn=config
    objectClass: olcDatabaseConfig
    objectClass: olcHdbConfig
    olcDatabase: {1}hdb
    olcSuffix: dc=example,dc=com
    olcDbDirectory: /var/lib/ldap
    olcRootDN: cn=admin,dc=example,dc=com
    olcRootPW: secret
    olcDbConfig: set_cachesize 0 2097152 0
    olcDbConfig: set_lk_max_objects 1500
    olcDbConfig: set_lk_max_locks 1500
    olcDbConfig: set_lk_max_lockers 1500
    olcDbIndex: objectClass eq
    olcLastMod: TRUE
    olcDbCheckpoint: 512 30
    olcAccess: to attrs=userPassword by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
    olcAccess: to attrs=shadowLastChange by self write by * read
    olcAccess: to dn.base="" by * read
    olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read
    

    And add the LDIF by entering:

    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend.example.com.ldif
    
  2. Do the same with the frontend.example.com.ldif file listed above, and add it:

    sudo ldapadd -x -D cn=admin,dc=example,dc=com -W -f frontend.example.com.ldif
    

    The two severs should now have the same configuration except for the Syncrepl options.

  3. Now create a file named consumer_sync.ldif containing:

    #Load the syncprov module.
    dn: cn=module{0},cn=config
    changetype: modify
    add: olcModuleLoad
    olcModuleLoad: syncprov
    
    # syncrepl specific indices
    dn: olcDatabase={1}hdb,cn=config
    changetype: modify
    add: olcDbIndex
    olcDbIndex: entryUUID eq
    -
    add: olcSyncRepl
    olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" 
     credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" 
     logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on 
     type=refreshAndPersist retry="60 +" syncdata=accesslog
    -
    add: olcUpdateRef
    olcUpdateRef: ldap://ldap01.example.com
    

    You will probably want to change the following attributes:

    • ldap01.example.com to your server's hostname.

    • binddn

    • credentials

    • searchbase

    • olcUpdateRef:

  4. Add the LDIF file to the configuration tree:

    sudo ldapadd -c -Y EXTERNAL -H ldapi:/// -f consumer_sync.ldif
    

The frontend database should now sync between servers. You can add additional servers using the steps above as the need arises.

[Note]

The slapd daemon will send log information to /var/log/syslog by default. So if all does not go well check there for errors and other troubleshooting information. Also, be sure that each server knows it's Fully Qualified Domain Name (FQDN). This is configured in /etc/hosts with a line similar to:

127.0.0.1	ldap01.example.com ldap01

.

Setting up ACL

Authentication requires access to the password field, that should be not accessible by default. Also, in order for users to change their own password, using passwd or other utilities, shadowLastChange needs to be accessible once a user has authenticated.

To view the Access Control List (ACL), use the ldapsearch utility:

ldapsearch -xLLL -b cn=config -D cn=admin,cn=config -W olcDatabase=hdb olcAccess
Enter LDAP Password: 
dn: olcDatabase={1}hdb,cn=config
olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=admin,dc=exampl
 e,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=admin,dc=example,dc=com" write by * read

TLS and SSL

When authenticating to an OpenLDAP server it is best to do so using an encrypted session. This can be accomplished using Transport Layer Security (TLS) and/or Secure Sockets Layer (SSL).

The first step in the process is to obtain or create a certificate. Because slapd is compiled using the gnutls library, the certtool utility will be used to create certificates.

  1. First, install gnutls-bin by entering the following in a terminal:

    sudo apt-get install gnutls-bin
    
  2. Next, create a private key for the Certificate Authority (CA):

    sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
    
  3. Create a /etc/ssl/ca.info details file to self-sign the CA certificate containing:

    cn = Example Company
    ca
    cert_signing_key
    
  4. Now create the self-signed CA certificate:

    sudo certtool --generate-self-signed --load-privkey /etc/ssl/private/cakey.pem \ 
     --template  /etc/ssl/ca.info --outfile /etc/ssl/certs/cacert.pem
    
  5. Make a private key for the server:

    sudo sh -c "certtool --generate-privkey > /etc/ssl/private/ldap01_slapd_key.pem"
    
    [Note]

    Replace ldap01 in the filename with your server's hostname. Naming the certificate and key for the host and service that will be using them will help keep filenames and paths straight.

  6. To sign the server's certificate with the CA, create the /etc/ssl/ldap01.info info file containing:

    organization = Example Company
    cn = ldap01.example.com
    tls_www_server
    encryption_key
    signing_key
    
  7. Create the server's certificate:

    sudo certtool --generate-certificate --load-privkey /etc/ssl/private/x01-test_slapd_key.pem \
     --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem \
     --template /etc/ssl/x01-test.info --outfile /etc/ssl/certs/x01-test_slapd_cert.pem
    

Once you have a certificate, key, and CA cert installed, use ldapmodify to add the new configuration options:

sudo ldapmodify -Y EXTERNAL -H ldapi:///
Enter LDAP Password:
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem

modifying entry "cn=config"

[Note]

Adjust the ldap01_slapd_cert.pem, ldap01_slapd_key.pem, and cacert.pem names if yours are different.

Next, edit /etc/default/slapd uncomment the SLAPD_SERVICES option:

SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"

Now the openldap user needs access to the certificate:

sudo adduser openldap ssl-cert
sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem
sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem
[Note]

If the /etc/ssl/private and /etc/ssl/private/server.key have different permissions, adjust the commands appropriately.

Finally, restart slapd:

sudo /etc/init.d/slapd restart

The slapd daemon should now be listening for LDAPS connections and be able to use STARTTLS during authentication.

[Note]

If you run into troubles with the server not starting, check the /var/log/syslog. If you see errors like main: TLS init def ctx failed: -1, it is likely there is a configuration problem. Check that the certificate is signed by the authority from in the files configured, and that the ssl-cert group has read permissions on the private key.

TLS Replication

If you have setup Syncrepl between servers, it is prudent to encrypt the replication traffic using Transport Layer Security (TLS). For details on setting up replication see the section called “LDAP Replication”.

Assuming you have followed the above instructions and created a CA certificate and server certificate on the Provider server. Follow the following instructions to create a certificate and key for the Consumer server.

  1. Create a new key for the Consumer server:

    mkdir ldap02-ssl
    cd ldap02-ssl
    certtool --generate-privkey > ldap02_slapd_key.pem
    
    [Note]

    Creating a new directory is not strictly necessary, but it will help keep things organized and make it easier to copy the files to the Consumer server.

  2. Next, create an info file, ldap02.info for the Consumer server, changing the attributes to match your locality and server:

    country = US
    state = North Carolina
    locality = Winston-Salem
    organization = Example Company
    cn = ldap02.salem.edu
    tls_www_client
    encryption_key
    signing_key
    
  3. Create the certificate:

    sudo certtool --generate-certificate --load-privkey ldap02_slapd_key.pem \
     --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem \
     --template ldap02.info --outfile ldap02_slapd_cert.pem
    
  4. Copy the cacert.pem to the dicretory:

    cp /etc/ssl/certs/cacert.pem .
    
  5. The only thing left is to copy the ldap02-ssl directory to the Consumer server, then copy ldap02_slapd_cert.pem and cacert.pem to /etc/ssl/certs, and copy ldap02_slapd_key.pem to /etc/ssl/private.

  6. Once the files are in place adjust the cn=config tree by entering:

    sudo ldapmodify -Y EXTERNAL -H ldapi:///
    
    Enter LDAP Password:
    dn: cn=config
    add: olcTLSCACertificateFile
    olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
    -
    add: olcTLSCertificateFile
    olcTLSCertificateFile: /etc/ssl/certs/ldap02_slapd_cert.pem
    -
    add: olcTLSCertificateKeyFile
    olcTLSCertificateKeyFile: /etc/ssl/private/ldap02_slapd_key.pem
    
    modifying entry "cn=config"
    
    
  7. As with the Provider you can now edit /etc/default/slapd and add the ldaps:/// parameter to the SLAPD_SERVICES option.

Now that TLS has been setup on each server, once again modify the Consumer server's cn=config tree by entering the following in a terminal:

sudo ldapmodify -Y EXTERNAL -H ldapi:///
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0

dn: olcDatabase={1}hdb,cn=config
replace: olcSyncrepl
olcSyncrepl: {0}rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=ad
 min,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbas
 e="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" s
 chemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog starttls=yes

modifying entry "olcDatabase={1}hdb,cn=config"

If the LDAP server hostname does not match the Fully Qualified Domain Name (FQDN) in the certificate, you may have to edit /etc/ldap/ldap.conf and add the following TLS options:

TLS_CERT /etc/ssl/certs/ldap02_slapd_cert.pem
TLS_KEY /etc/ssl/private/ldap02_slapd_key.pem
TLS_CACERT /etc/ssl/certs/cacert.pem

Finally, restart slapd on each of the servers:

sudo /etc/init.d/slapd restart

LDAP Authentication

Once you have a working LDAP server, the auth-client-config and libnss-ldap packages take the pain out of configuring an Ubuntu client to authenticate using LDAP. To install the packages from, a terminal prompt enter:

sudo apt-get install libnss-ldap

During the install a menu dialog will ask you connection details about your LDAP server.

If you make a mistake when entering your information you can execute the dialog again using:

sudo dpkg-reconfigure ldap-auth-config

The results of the dialog can be seen in /etc/ldap.conf. If your server requires options not covered in the menu edit this file accordingly.

Now that libnss-ldap is configured enable the auth-client-config LDAP profile by entering:

sudo auth-client-config -t nss -p lac_ldap
  • -t: only modifies /etc/nsswitch.conf.

  • -p: name of the profile to enable, disable, etc.

  • lac_ldap: the auth-client-config profile that is part of the ldap-auth-config package.

Using the pam-auth-update utility, configure the system to use LDAP for authentication:

sudo pam-auth-update

From the pam-auth-update menu, choose LDAP and any other authentication mechanisms you need.

You should now be able to login using user credentials stored in the LDAP directory.

[Note]

If you are going to use LDAP to store Samba users you will need to configure the server to authenticate using LDAP. See the section called “Samba and LDAP” for details.

User and Group Management

The ldap-utils package comes with multiple utilities to manage the directory, but the long string of options needed, can make them a burden to use. The ldapscripts package contains configurable scripts to easily manage LDAP users and groups.

To install the package, from a terminal enter:

sudo apt-get install ldapscripts

Next, edit the config file /etc/ldapscripts/ldapscripts.conf uncommenting and changing the following to match your environment:

SERVER=localhost
BINDDN='cn=admin,dc=example,dc=com'
BINDPWDFILE="/etc/ldapscripts/ldapscripts.passwd"
SUFFIX='dc=example,dc=com'
GSUFFIX='ou=Groups'
USUFFIX='ou=People'
MSUFFIX='ou=Computers'
GIDSTART=10000
UIDSTART=10000
MIDSTART=10000

Now, create the ldapscripts.passwd file to allow authenticated access to the directory:

sudo sh -c "echo -n 'secret' > /etc/ldapscripts/ldapscripts.passwd"
sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
[Note]

Replace secret with the actual password for your LDAP admin user.

The ldapscripts are now ready to help manage your directory. The following are some examples of how to use the scripts:

  • Create a new user:

    sudo ldapadduser george example
    

    This will create a user with uid george and set the user's primary group (gid) to example

  • Change a user's password:

    sudo ldapsetpasswd george
    Changing password for user uid=george,ou=People,dc=example,dc=com
    New Password: 
    New Password (verify): 
    
  • Delete a user:

    sudo ldapdeleteuser george
    
  • Add a group:

    sudo ldapaddgroup qa
    
  • Delete a group:

    sudo ldapdeletegroup qa
    
  • Add a user to a group:

    sudo ldapaddusertogroup george qa
    

    You should now see a memberUid attribute for the qa group with a value of george.

  • Remove a user from a group:

    sudo ldapdeleteuserfromgroup george qa
    

    The memberUid attribute should now be removed from the qa group.

  • The ldapmodifyuser script allows you to add, remove, or replace a user's attributes. The script uses the same syntax as the ldapmodify utility. For example:

    sudo ldapmodifyuser george
    # About to modify the following entry :
    dn: uid=george,ou=People,dc=example,dc=com
    objectClass: account
    objectClass: posixAccount
    cn: george
    uid: george
    uidNumber: 1001
    gidNumber: 1001
    homeDirectory: /home/george
    loginShell: /bin/bash
    gecos: george
    description: User account
    userPassword:: e1NTSEF9eXFsTFcyWlhwWkF1eGUybVdFWHZKRzJVMjFTSG9vcHk=
    
    # Enter your modifications here, end with CTRL-D.
    dn: uid=george,ou=People,dc=example,dc=com
    replace: gecos
    gecos: George Carlin
    

    The user's gecos should now be George Carlin.

  • Another great feature of ldapscripts, is the template system. Templates allow you to customize the attributes of user, group, and machine objectes. For example, to enable the user template edit /etc/ldapscripts/ldapscripts.conf changing:

    UTEMPLATE="/etc/ldapscripts/ldapadduser.template"
    

    There are sample templates in the /etc/ldapscripts directory. Copy or rename the ldapadduser.template.sample file to /etc/ldapscripts/ldapadduser.template:

    sudo cp /etc/ldapscripts/ldapadduser.template.sample /etc/ldapscripts/ldapadduser.template
    

    Edit the new template to add the desired attributes. The following will create new user's as with an objectClass of inetOrgPerson:

    dn: uid=<user>,<usuffix>,<suffix>
    objectClass: inetOrgPerson
    objectClass: posixAccount
    cn: <user>
    sn: <ask>
    uid: <user>
    uidNumber: <uid>
    gidNumber: <gid>
    homeDirectory: <home>
    loginShell: <shell>
    gecos: <user>
    description: User account
    title: Employee
    

    Notice the <ask> option used for the cn value. Using <ask> will configure ldapadduser to prompt you for the attribute value during user creation.

There are more useful scripts in the package, to see a full list enter: dpkg -L ldapscripts | grep bin

Resources

  • The OpenLDAP Ubuntu Wiki page has more details.

  • For more information see OpenLDAP Home Page

  • Though starting to show it's age, a great source for in depth LDAP information is O'Reilly's LDAP System Administration

  • Packt's Mastering OpenLDAP is a great reference covering newer versions of OpenLDAP.

  • For more information on auth-client-config see the man page: man auth-client-config.

  • For more details regarding the ldapscripts package see the man pages: man ldapscripts, man ldapadduser, man ldapaddgroup, etc.