LDAP is a protocol to access services representing data in the shape of a directory. Roughly, a directory is a browsable hierarchy of entries, each of which can have a number of attributes. The semantics of the attributes is defined in a schema. This information model is rather different from the table-based one you might be familiar with from relational databases. It is often used to represent details of persons grouped by units of an organisation, or specifically for those persons' user account details.
I forked the Docker image building context for
dinkel/openldap
;
my version with a few adjustments can be found
on GitHub.
It can be built directly from the Git repository.
docker build -t openldap:withtools https://github.com/fedde-s/docker-openldap.git#master
Create an isolated Docker network in which the container can communicate with other containers, unless you want to reuse an existing one.
docker network create authnet
Run the slapd
server in a container connected to this network,
initialising it with a domain and and admin user password and giving
it read-write access to persistent data volumes for its configuration
and data.
docker run -d --restart=always \
--name=ldap-server \
--net=authnet \
-v ldap-conf:/etc/ldap \
-v ldap-data:/var/lib/ldap \
-e SLAPD_PASSWORD=mysecretpassword \
-e SLAPD_DOMAIN=cbio.local \
openldap:withtools
To add user entries to this database, create an LDIF file defining
their uniquely qualified distinguished names (dn
), the object
class of the entries that you use to represent your user details,
and any attributes that have been defined to make sense for these
object classes. A nicely browsable list of commonly used classes can
be found here. The
distinguished name places the entries somewhere in the tree, often in
terms of internet domain components (dc
) and organisational units
(ou
).
In this example, the inetOrgPerson
class requires them to have
surnames (the sn
attribute), and common names (cn
), and states
that it makes sense for them to have email addresses (mail
) and user
IDs (uid
), among other attributes.
dn: ou=people,dc=cbio,dc=local
objectclass: organizationalUnit
ou: people
dn: uid=foo,ou=people,dc=cbio,dc=local
objectclass: inetOrgPerson
uid: foo
sn: Vanderfoo
cn: Foo Vanderfoo
cn: Foo Tiberius Vanderfoo
dn: uid=bar,ou=people,dc=cbio,dc=local
objectclass: inetOrgPerson
uid: bar
sn: Barson
cn: Bar Barson
mail: bar@cbio.local
These users can then be loaded into the database by running ldapadd in
a container that has read access to the ldif file, binding to the
database using simple authentication (-x
) with a password prompt
(-W
) for the admin user, identified by the user's distinguished
name.
docker run --rm -it \
--net=authnet \
-v "$PWD/<your_file_name>.ldif:/in.ldif:ro" \
openldap:withtools \
ldapadd -H ldap://ldap-server -xWD cn=admin,dc=cbio,dc=local -f /in.ldif
Next, the users should be granted passwords so that they can log
in. This will (for now) set the userPassword
attributes of the user
entries, storing salted SHA-1 hashes. The following command will
prompt for a password for the first user in the example file above,
while (again) authenticating as the admin user to make the change:
docker run --rm -it \
--net=authnet \
openldap:withtools \
ldappasswd -H ldap://ldap-server -xWD cn=admin,dc=cbio,dc=local -S \
uid=foo,ou=people,dc=cbio,dc=local
You can use the ldapsearch
command to look at the data in the
database. The command line below will list the surnames and common
names of any entries that have a surname starting with van within
our domain, displayed in a minimal format (specified by -LLL
).
docker run --rm -it \
--net=authnet \
openldap:withtools \
ldapsearch -H ldap://ldap-server -xWD cn=admin,dc=cbio,dc=local \
-LLL -b dc=cbio,dc=local '(sn=van*)' sn cn
The argument to -b
specifies the subtree to be searched, the
parenthesised text is a filter string (other operators are available
for more complex queries), and the enumeration of attribute types
specifies which attributes to display. The latter two both default to
displaying all if left out.
See the man page on the
ldapmodify(1)
command to modify entries according to specifications in the LDIF
format, or try ldapdelete(1)
to delete individual entries or
recursively delete subtrees.
TODO: suggest a bind role with read-only access