[LDAP] How to set up local Open LDAP service

This post will show how to host a OpenLDAP service on the localhost step by step.

1. Prerequisites

  1. docker-compose installed.

2. Prepare LDAP data

We will create some data for LDAP service and populate it when the service runs up. Create a directory, for example openldap, first, and create another sub-directory openldap/data.

The structure of the LDAP data can be described by .ldif file. So we can create below file openldap/data/bootstrap.ldif as the LDAP boostrap data.

dn: cn=developer,dc=example,dc=org
changetype: add
objectclass: inetOrgPerson
cn: developer
givenname: developer
sn: Developer
displayname: Developer User
mail: developer@gmail.com
uid: developer
userpassword: developer_pass

dn: cn=maintainer,dc=example,dc=org
changetype: add
objectclass: inetOrgPerson
cn: maintainer
givenname: maintainer
sn: Maintainer
displayname: Maintainer User
mail: maintainer@gmail.com
uid: maintainer
userpassword: maintainer_pass

dn: cn=admin_gh,dc=example,dc=org
changetype: add
objectclass: inetOrgPerson
cn: admin_gh
givenname: admin_gh
sn: AdminGithub
displayname: Admin Github User
mail: admin_gh@gmail.com
userpassword: admin_gh_pass

dn: ou=Groups,dc=example,dc=org
changetype: add
objectclass: organizationalUnit
ou: Groups

dn: ou=Users,dc=example,dc=org
changetype: add
objectclass: organizationalUnit
ou: Users

dn: cn=Admins,ou=Groups,dc=example,dc=org
changetype: add
cn: Admins
objectclass: groupOfUniqueNames
uniqueMember: cn=admin_gh,dc=example,dc=org

dn: cn=Maintaners,ou=Groups,dc=example,dc=org
changetype: add
cn: Maintaners
objectclass: groupOfUniqueNames
uniqueMember: cn=maintainer,dc=example,dc=org
uniqueMember: cn=developer,dc=example,dc=org

The LDAP data structure looks like

So far, we only have one file bootstrap.ldif under the directory /openldap.

├── data
    └── bootstrap.ldif

3. Prepare docker-compose file

Create /openldap/docker-compose.yaml with the below content.

 1version: '3.7'
 2
 3services:
 4  ldap_server:
 5    image: osixia/openldap:1.5.0
 6    environment:
 7      LDAP_ADMIN_PASSWORD: admin_pass
 8      LDAP_BASE_DN: dc=example,dc=org
 9      LDAP_DOMAIN: example.org
10      LDAP_ORGANISATION: "Example Inc."
11    hostname: ldap.example.org
12    command: --copy-service
13    ports:
14      - 389:389
15    volumes:
16      - ./data/bootstrap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/50-bootstrap.ldif
17
18  ldap_server_admin:
19    image: osixia/phpldapadmin:0.7.2
20    ports:
21      - 8090:80
22    environment:
23      PHPLDAPADMIN_LDAP_HOSTS: ldap_server
24      PHPLDAPADMIN_HTTPS: 'false'

This docker-compose file is composed of two services: LDAP server and LDAP admin panel.

After running up the service with docker-compose up and open the http://localhost:8090 from the web browser. We can see the below page.

We can test whether the bootstrap data is loaded or not by logging in the admin panel.

Note that the Login DN should be cn=admin,dc=example,dc=org and Password is admin_pass created by docker-compose environment.

Then you can see the LDAP data structure as below:

If you see the same result as above, it means the LDAP service is set up successfully.

If you prefer to use command line to test the LDAP server, you can run the below command without installing LDAP clent tool saperately.

docker exec openldap_ldap_server_1 ldapsearch -x -H ldap://localhost:389 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin_pass

The output should be like

# extended LDIF
#
# LDAPv3
# base <dc=example,dc=org> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# example.org
dn: dc=example,dc=org
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Inc.
dc: example

# developer, example.org
dn: cn=developer,dc=example,dc=org
objectClass: inetOrgPerson
cn: developer
givenName: developer
sn: Developer
displayName: Developer User
mail: developer@gmail.com
uid: developer
userPassword:: ZGV2ZWxvcGVyX3Bhc3M=

# maintainer, example.org
dn: cn=maintainer,dc=example,dc=org
objectClass: inetOrgPerson
cn: maintainer
givenName: maintainer
sn: Maintainer
displayName: Maintainer User
mail: maintainer@gmail.com
uid: maintainer
userPassword:: bWFpbnRhaW5lcl9wYXNz

# admin_gh, example.org
dn: cn=admin_gh,dc=example,dc=org
objectClass: inetOrgPerson
cn: admin_gh
givenName: admin_gh
sn: AdminGithub
displayName: Admin Github User
mail: admin_gh@gmail.com
userPassword:: YWRtaW5fZ2hfcGFzcw==

# Groups, example.org
dn: ou=Groups,dc=example,dc=org
objectClass: organizationalUnit
ou: Groups

# Users, example.org
dn: ou=Users,dc=example,dc=org
objectClass: organizationalUnit
ou: Users

# Admins, Groups, example.org
dn: cn=Admins,ou=Groups,dc=example,dc=org
cn: Admins
objectClass: groupOfUniqueNames
uniqueMember: cn=admin_gh,dc=example,dc=org

# Maintainers, Groups, example.org
dn: cn=Maintainers,ou=Groups,dc=example,dc=org
cn: Maintainers
objectClass: groupOfUniqueNames
uniqueMember: cn=maintainer,dc=example,dc=org
uniqueMember: cn=developer,dc=example,dc=org

# search result
search: 2
result: 0 Success

# numResponses: 9
# numEntries: 8

Now, the directory structure of /openldap is like:

├── data
│   └── bootstrap.ldif
└── docker-compose.yml

4. Host the service with custom TLS certificates

I will assume that you already had the custom TLS certificates before this step. You can put them under the directory /openldap/data/certs.

If you don’t have, you can head to my another post How to generate custom TLS certificates with cfssl to generate a new one in 2 minutes.

After adding the custom TLS certificates, the file structure under /openldap should look like

├── data
│   ├── bootstrap.ldif
│   └── certs
│       ├── ldap-ca.pem
│       ├── ldap-key.pem
│       └── ldap.pem
└── docker-compose.yml

Last step, we will need to update the docker-compose file for using our own TLS certificates.

 1version: '3.7'
 2
 3services:
 4  ldap_server:
 5    image: osixia/openldap:1.5.0
 6    environment:
 7      LDAP_ADMIN_PASSWORD: admin_pass
 8      LDAP_BASE_DN: dc=example,dc=org
 9      LDAP_DOMAIN: example.org
10      LDAP_ORGANISATION: "Example Inc."
11      LDAP_TLS_CRT_FILENAME: ldap.pem
12      LDAP_TLS_KEY_FILENAME: ldap-key.pem
13      LDAP_TLS_CA_CRT_FILENAME: ldap-ca.pem
14      LDAP_TLS_VERIFY_CLIENT: try
15    hostname: ldap.example.org
16    command: --copy-service
17    ports:
18      - 389:389
19      - 636:636
20    volumes:
21      - ./data/bootstrap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/50-bootstrap.ldif
22      - ./data/certs:/container/service/slapd/assets/certs 
23
24  ldap_server_admin:
25    image: osixia/phpldapadmin:0.7.2
26    ports:
27      - 8090:80
28    environment:
29      PHPLDAPADMIN_LDAP_HOSTS: ldap_server
30      PHPLDAPADMIN_HTTPS: 'false'

It may take bit longer to run up the above docker-compose than the previous one. If the below logs are shown, it means it’s ready.

Now we can give a test. Unfortunately, we couldn’t take advantage of the image built-in ldapsearch tool docker exec openldap_ldap_server_1 ldapsearch like before.

It’s because the certificate path is passed by the docker-compose environment variable, so we cannot really see the effect with custom TLS certificate.

In this case, I would suggest to install the ldapsearch binary on your localhost or use the services that supports LDAP feature.

With the ldapsearch binary, you may run the below command to test.

env LDAPTLS_CACERT=/path/to/cert ldapsearch -x -H ldaps://localhost:636 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin_pass

With other services that supports LDAP feature, I would suggest to try with Portainer even though it can do much much more than only testing LDAP service.

You can find the completed implementation from my github repository oscarzhou/openldap.

While I was learning the knowledge about ldap, I searched quite a lot of online sites, pages. Thanks to the authors of the below contents.

  1. Github osixia/openldap
  2. Build an OpenLDAP Docker Image That’s Populated With Users
  3. ldapwiki

If this post helped you to solve a problem or provided you with new insights, please upvote it and share your experience in the comments below. Your comments can help others who may be facing similar challenges. Thank you!
Buy Me A Coffee
DigitalOcean Referral Badge
Sign up to get $200, 60-day account credit !