OpenLDAP Setup

Containerized Setup

Using Docker:

1docker run \
2 -d \
3 -p 389:389 \
4 --name ldap-service \
5 --hostname ldap-service \
6 --env LDAP_ORGANISATION="GLauth" \
7 --env LDAP_DOMAIN="glauth.com" \
8 --env LDAP_ADMIN_PASSWORD="password" \
9 --env LDAP_CONFIG_PASSWORD="password" \
10 --env LDAP_BASE_DN="dc=glauth,dc=com" \
11 -v $PWD/data/config:/etc/ldap/slapd.d \
12 -v $PWD/data/db:/var/lib/ldap \
13 osixia/openldap:latest

Setup a management container:

1docker run \
2 -d \
3 -p 443:443 \
4 --name phpldapadmin-service \
5 --hostname phpldapadmin-service \
6 --link ldap-service:ldap-host \
7 --env PHPLDAPADMIN_LDAP_HOSTS=ldap-service \
8 osixia/phpldapadmin:latest

Test query:

1ldapsearch -H ldap://localhost -bdc=glauth,dc=com \
2 -D cn=admin,dc=glauth,dc=com \
3 -w password "(objectclass=*)"

To add users, groups, and other objects visit https://<your host>

Overlays and Group Membership

OK, now let’s build on top of this. A commonly misunderstood process is how a user becomes a “memberOf” a group, and that is because it’s a very “OpenLdap” feature. Actually, it relies on OL’s overlay feature.

First, let’s check that our container is running OpenLDAP with that overlay enabled and configured:

1docker exec ldap-service slapcat -n 0

We should find a couple entries in there, the first one listing the “memberOf” overlay and further down another one representing its configuration.

So, step-by-step, let’s create users, assign them to Posix Groups, and to Groups of Unique Names (the latter triggering the mechanism by which users will end up being “memberOf” groups)

Long story short: we are going to structure our database so that we have users, and these users will be found under posixGroups.
These users will also belong to OpenLDAP-specific groups, AKA “groupOfUniqueNames” which, thanks to the “memberOf” overlay will be retrieved alongside other user information as part of single user queries.

Select the root DN (dc=glauth,dc=com)
Create two Organisational Unit entries:

  • users
  • groups

Select the “ou=users” entry
Click: Create a child entry; Default: posixGroup
Enter: “cn”, “superheros”,“5501”
We will repeat these steps with:

  • “cn”, “svcaccts”,“5501”
  • “cn”, “vpn”,“5503”

Select the “cn=superheros” entry
Click: Create a child entry; Generic: User Account
“John”, “Doe”, “johndoe”, “johndoe”, “dogood”, “dogood”, “superheros”
Create user, then change its uidNumber to “5002”

Now, add the user to the “superheros” group:
Select the “cn=superheros” entry
Click: Add new attribute; select “memberUid”
Enter “johndoe” and save.

At this point, it is possible to retrieve the “johndoe” user by querying its group. But we cannot, yet, retrieve a group by querying the user itself.

Let’s create our OpenLDAP group.
Select “ou=groups”
Click: Create a child entry; Default: groupOfUniqueNames
Enter: “cn”, “superheros”
Browser the users’ list and add a uniqueMember: John Doe. Now, create our entry.

If you inspect the John Doe user again, you will find that it now has a “memberOf” attribute. Done.

Test our configuration:

1ldapsearch -LLL -H ldap://localhost:389 \
2 -D cn=admin,dc=glauth,dc=com -w password \
3 -x -bdc=glauth,dc=com \
4 "(objectclass=posixgroup)"
5 
6ldapsearch -LLL -H ldap://localhost:389 \
7 -D cn=admin,dc=glauth,dc=com -w password \
8 -x -bdc=glauth,dc=com \
9 "(cn=johndoe)"
10 
11ldapsearch -LLL -H ldap://localhost:389 \
12 -D cn=admin,dc=glauth,dc=com -w password \
13 -x -bdc=glauth,dc=com \
14 "(memberOf=cn=superheros,ou=groups,dc=glauth,dc=com)"

Allowing an account to perform searches

First, list your configuration databases:

1docker exec openldap-service slapcat -b cn=config \
2 | grep '^dn: olcDatabase'

So, let’s say that you found that your work database is dn: olcDatabase={1}mdb,cn=config you then create a file called e.g. grantserviceuser.ldif with these instructions:

1dn: olcDatabase={1}mdb,cn=config
2changetype: modify
3delete: olcAccess
4-
5add: olcAccess
6olcAccess: to attrs=userPassword,shadowLastChange by self write by dn="cn=serviceuser,cn=svcaccts,ou=users,dc=glauth,dc=com" write by anonymous auth by * none
7olcAccess: to * by self write by dn="cn=serviceuser,cn=svcaccts,ou=users,dc=glauth,dc=com" write by users read by * none

and use it (as your config admin user):

1ldapmodify -H ldap://localhost:389 \
2 -D cn=admin,cn=config -w password \
3 -x -f grantserviceuser.ldif

You should now be able to use the serviceuser account to query the database.

Copyright 2021