295 lines
11 KiB
Markdown
295 lines
11 KiB
Markdown
# ldapdock
|
|
*_a configurable container running openLDAP_*
|
|
|
|
Step by step approach on how to setup and run the openLDAP server on a classic systemd-less Docker image container
|
|
|
|
_note about the dockerfile and running the generated image container on FG (foreground) or BG (background): by default the dockerfile generates an image to be run in FG, it expects to be run into it and launch slapd (openLDAP server) manually; to run the image container in BG and start slapd automatically without any user intervention, uncomment the line number 31 of the dockerfile._
|
|
|
|
## _Creating the ldapdock image container_
|
|
|
|
build ldapdock
|
|
```
|
|
> docker build -t ldapdock /path/to/dockerfile
|
|
```
|
|
|
|
after build, check the docker image has been created properly with the given REPOSITORY name
|
|
```
|
|
> docker images
|
|
REPOSITORY TAG IMAGE ID CREATED SIZE
|
|
ldapdock latest 0e4a1521b346 6 hours ago 138MB
|
|
```
|
|
|
|
You can run into the container in an interactive way already with this command:
|
|
```
|
|
> docker run -h example.com -i -t ldapdock /bin/bash
|
|
```
|
|
With -h we are specifying the name of the host, we are using example.com, this is very important.
|
|
|
|
## _Explaining DN, parentDN, CN, and DC as parameters_
|
|
|
|
One of the key configuration of LDAP is our "DC" or "parent DN" and other terms, which to explain it in a pure pragmatic way, we will use some examples: we use per defect example.com as our domain, so the DC (Distinguished Name) that we would use it is **"dc=example,dc=com"**, instead, if our domain would be for example "ideas.lab.com", the parent DN would be "dc=ideas,dc=lab,dc=com". This configuration it's very often passed with the CN (Common Name) in concatenation with the DN (Distinguished Name), and the result it's very simple, in the case of the domain example.com, it is **DN: "cn=config,dn=example,dn=com"**, or for ideas.lab.com DN: "cn=config,dn=ideas,dn=lab,dn=com".
|
|
|
|
## _Inside the ldapdock image container_
|
|
|
|
make sure to use the following command to start openLDAP
|
|
```
|
|
root@example:/# slapd -h "ldap:/// ldapi:///" -g openldap -u openldap -F /etc/ldap/slapd.d
|
|
```
|
|
|
|
test connectivity to slapd
|
|
```
|
|
root@example:/# ldapsearch -x -H ldap://localhost -b "dc=example,dc=com" -s base "(objectclass=*)"
|
|
# extended LDIF
|
|
#
|
|
# LDAPv3
|
|
# base <dc=example,dc=com> with scope baseObject
|
|
...
|
|
```
|
|
|
|
<!-- optional tests to understand what are LDAP directories (LDAP OU)
|
|
prepare new test LDAP directories (LDAP OU) and create two attributes/branches with People and Group
|
|
```
|
|
root@example:/# vim base.ldif
|
|
dn: ou=People,dc=example,dc=com
|
|
objectClass: organizationalUnit
|
|
ou: People
|
|
|
|
dn: ou=Groups,dc=example,dc=com
|
|
objectClass: organizationalUnit
|
|
ou: Group
|
|
```
|
|
|
|
create the test directory in our LDAP server, the password in the dockerfile by default is _admin_
|
|
```
|
|
root@example:/# ldapadd -x -D cn=admin,dc=example,dc=com -W -f base.ldif
|
|
Enter LDAP Password:
|
|
adding new entry "ou=People,dc=example,dc=com"
|
|
|
|
adding new entry "ou=Groups,dc=example,dc=com"
|
|
```
|
|
|
|
verify the entries in the LDAP server
|
|
```
|
|
root@example:/# ldapsearch -x -LLL -b dc=example,dc=com 'ou=People' dn
|
|
dn: ou=People,dc=example,dc=com
|
|
root@example:/# ldapsearch -x -LLL -b dc=example,dc=com 'ou=Groups' dn
|
|
dn: ou=Groups,dc=example,dc=com
|
|
```
|
|
now we have an **Organizational Unit (ou=People, ou=Group, etc.)** with users and groups within an LDAP directory structure correctly created -->
|
|
|
|
## _Users administrative tasks_
|
|
|
|
### <ins>_Reset root password_</ins>
|
|
|
|
Build line by line, the **.ldif** file we will need to reset root password, starting with the following command:
|
|
```
|
|
root@example:/# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(olcSuffix=dc=example,dc=com)' dn > rootpw.ldif
|
|
```
|
|
which writes to the rootpw.ldif file, the current rootDN (Distinguised Name): `dn: olcDatabase={1}mdb,cn=config`\
|
|
The next command will add the 'changetype' (modify, add, etc.) and what object are we working with:
|
|
```
|
|
root@example:/# echo -e 'changetype: modify\nreplace: olcRootPW: ' >> rootpw.ldif
|
|
root@example:/etc/ldap# cat rootpw.ldif
|
|
dn: olcDatabase={1}mdb,cn=config
|
|
|
|
changetype: modify
|
|
replace: olcRootPW
|
|
```
|
|
We run a simple sed command to delete blank lines
|
|
```
|
|
root@example:/# sed '/^$/d' rootpw.ldif > chrootpw.ldif
|
|
root@example:/# cat chrootpw.ldif
|
|
dn: olcDatabase={1}mdb,cn=config
|
|
changetype: modify
|
|
replace: olcRootPW
|
|
```
|
|
It's time to write our new password (_newpasswd_):
|
|
```
|
|
root@example:/# slappasswd -s 1234
|
|
{SSHA}2xbd33S4ZumAZW4Oks0GJidBFJYEVBPz
|
|
```
|
|
The last line it's our password 1234 hashed in SSHA cryptography. We will need to copy and paste it in the following command:
|
|
```
|
|
root@example:/# echo "olcRootPW: {SSHA}2xbd33S4ZumAZW4Oks0GJidBFJYEVBPz" >> chrootpw.ldif
|
|
```
|
|
The file that describes the variables needed to change our root password, **chrootpw.ldif** should be ready, we finally run:
|
|
```
|
|
root@example:/etc/ldap# ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif
|
|
modifying entry "olcDatabase={1}mdb,cn=config"
|
|
```
|
|
If successful, the output will show the modified entry.
|
|
|
|
### <ins>_Add users_</ins>
|
|
|
|
create a new LDAP directory called Supergirls (LDAP OU) with the following data
|
|
```
|
|
root@example:/# vim add_ou.ldif
|
|
dn: ou=Supergirls,dc=example,dc=com
|
|
objectClass: organizationalUnit
|
|
ou: Supergirls
|
|
```
|
|
|
|
create it in our LDAP server, when asked for the root password, remember in the dockerfile by default is _admin_
|
|
```
|
|
root@example:/# ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f add_ou.ldif
|
|
Enter LDAP Password:
|
|
adding new entry "ou=Supergirls,dc=example,dc=com"
|
|
```
|
|
|
|
verify the entry in the LDAP server
|
|
```
|
|
root@example:/# ldapsearch -x -LLL -b "dc=example,dc=com" "(ou=Supergirls)" dn
|
|
dn: ou=Supergirls,dc=example,dc=com
|
|
```
|
|
|
|
create a new LDAP password to manage our new directory, annotate both the entered _plain password_ and the result _hashed password_
|
|
```
|
|
root@example:/# slappasswd
|
|
New password:
|
|
Re-enter new password:
|
|
{SSHA}hashedpasswd
|
|
```
|
|
|
|
create a .ldif file with the necessary attributes to insert in our Supergirls directory
|
|
```
|
|
root@example:/# vim add_user_supergirls.ldif
|
|
dn: uid=marisa,ou=Supergirls,dc=example,dc=com
|
|
objectClass: inetOrgPerson
|
|
objectClass: posixAccount
|
|
cn: Marisa
|
|
sn: Kirisame
|
|
givenName: Marisa
|
|
displayName: Marisa Kirisame
|
|
uid: marisa
|
|
uidNumber: 1001
|
|
gidNumber: 5000
|
|
homeDirectory: /home/marisa
|
|
loginShell: /bin/bash
|
|
userPassword: {SSHA}hashedpasswd
|
|
mail: marisa@example.com
|
|
```
|
|
|
|
insert the new user (marisa) in our Supergirls directory (LDAP OU), still using the root password _admin_
|
|
```
|
|
root@example:/# ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f add_user_supergirls.ldif
|
|
Enter LDAP Password:
|
|
adding new entry "uid=marisa,ou=Supergirls,dc=example,dc=com"
|
|
```
|
|
|
|
verify the user (marisa) has been added to the Supergirls OU
|
|
```
|
|
root@example:/# ldapsearch -x -LLL -b "dc=example,dc=com" "(uid=marisa)" dn
|
|
dn: uid=marisa,ou=Supergirls,dc=example,dc=com
|
|
```
|
|
|
|
### <ins>_Modify users attributes_</ins>
|
|
|
|
create a new .ldif file with the attributes we want to change\
|
|
in this case we want to modify the _mail_ marisa@example.com of the user (_uid_) marisa from the group (_ou_) Supergirls
|
|
```
|
|
root@example:/home# vim modify_user.ldif
|
|
dn: uid=marisa,ou=Supergirls,dc=example,dc=com
|
|
changetype: modify
|
|
replace: mail
|
|
mail: marisa.kirisame@example.com
|
|
```
|
|
|
|
run the modify file, when asked for the root password, remember in the dockerfile by default is _admin_
|
|
```
|
|
root@example:/home# ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f modify_user.ldif
|
|
Enter LDAP Password:
|
|
modifying entry "uid=marisa,ou=Supergirls,dc=example,dc=com"
|
|
```
|
|
|
|
verify the _mail_ attribute of the user marisa has been changed to marisa.kirisame@example.com
|
|
```
|
|
root@example:/home# ldapsearch -x -LLL -b "dc=example,dc=com" "(uid=marisa)" mail
|
|
dn: uid=marisa,ou=Engineering,dc=example,dc=com
|
|
mail: marisa.kirisame@example.com
|
|
```
|
|
|
|
### <ins>_Modify user password_</ins>
|
|
|
|
In this examples, we are changing user uid marisa from ou Supergirls **password**.\
|
|
\
|
|
In order to change the password interactively (writing in the prompt when asked), we can run this command:
|
|
```
|
|
root@example:/etc/ldap# ldappasswd -H ldap:/// -x -D "uid=marisa,ou=Supergirls,dc=example,dc=com" -W -S "uid=marisa,ou=Supergirls,dc=example,dc=com"
|
|
New password: newpasswd
|
|
Re-enter new password: newpasswd
|
|
Enter LDAP Password: oldpasswd
|
|
```
|
|
_newpasswd_ being the new password we want to use, and _oldpasswd_, the last password we were using for the user uid marisa.\
|
|
\
|
|
To change the password in an non interactive (sending the password directly via the command), we can run this:
|
|
```
|
|
root@example:/etc/ldap# ldappasswd -H ldap:/// -x -D "uid=marisa,ou=Supergirls,dc=example,dc=com" -w newpasswd "uid=marisa,ou=Supergirls,dc=example,dc=com"
|
|
New password: 6vUj/2lE
|
|
```
|
|
_newpasswd_ being the new password we want to use. We can also notice the hashed output of our new password is not a typical LDAP SSHA hash, this is due to security implementations.
|
|
|
|
### <ins>_Reset user password_</ins>
|
|
|
|
In the likely common event that we forgot the password of an specific user, we need to reset it.\
|
|
In this example we forgot the password of the user uid marisa, we can reset it with this command:
|
|
```
|
|
root@example:/etc/ldap# ldappasswd -H ldap:/// -x -D "cn=admin,dc=example,dc=com" -W -S "uid=marisa,ou=Supergirls,dc=example,dc=com"
|
|
New password: newpasswd
|
|
Re-enter new password: newpasswd
|
|
Enter LDAP Password: admin
|
|
```
|
|
Note we need to use the **root** password (_admin_ by default) in the last query ("Enter LDAP Password") to reset an user's password.
|
|
|
|
### <ins>_Query as an specific user_</ins>
|
|
|
|
we already created the user (_uid_) marisa, and established the user's own password using slappasswd\
|
|
now we are gonna query our LDAP server using the user (_uid_) marisa credentials, and _the password we entered during slappasswd, called plain password (plainpasswd)_
|
|
```
|
|
root@example:/etc/ldap# ldapsearch -D uid=marisa,ou=Supergirls,dc=example,dc=com -b "dc=example,dc=com" -w plainpasswd
|
|
# extended LDIF
|
|
#
|
|
# LDAPv3
|
|
# base <dc=example,dc=com> with scope subtree
|
|
# filter: (objectclass=*)
|
|
# requesting: ALL
|
|
#
|
|
|
|
# example.com
|
|
dn: dc=example,dc=com
|
|
objectClass: top
|
|
objectClass: dcObject
|
|
objectClass: organization
|
|
o: nodomain
|
|
dc: example
|
|
|
|
# Supergirls, example.com
|
|
dn: ou=Supergirls,dc=example,dc=com
|
|
...
|
|
```
|
|
|
|
we can narrow this search to get only specific attributes of the user marisa, remember we are using _the plainpasswd when asked_
|
|
```
|
|
root@example:/etc/ldap# ldapsearch -D uid=marisa,ou=Supergirls,dc=example,dc=com -b "dc=example,dc=com" -w plainpasswd givenName uidNumber gidNumber homeDirectory
|
|
# extended LDIF
|
|
#
|
|
# LDAPv3
|
|
# base <dc=example,dc=com> with scope subtree
|
|
# filter: (objectclass=*)
|
|
# requesting: givenName uidNumber gidNumber homeDirectory
|
|
#
|
|
|
|
# example.com
|
|
dn: dc=example,dc=com
|
|
|
|
# Supergirls, example.com
|
|
dn: ou=Supergirls,dc=example,dc=com
|
|
|
|
# marisa, Supergirls, example.com
|
|
dn: uid=marisa,ou=Supergirls,dc=example,dc=com
|
|
givenName: Marisa
|
|
uidNumber: 1001
|
|
gidNumber: 5000
|
|
homeDirectory: /home/marisa
|
|
```
|
|
|
|
<!--ldappasswd -H ldap://server_domain_or_IP -x -D "cn=admin,dc=example,dc=com" -W -S "uid=bob,ou=people,dc=example,dc=com"--> |