Welcome the company of trees

Lightweight Directory Access Protocol

2010-08-20

Revision History
Revision 0.12010-08-20FU
Initital version

Background

We will like to log into and authenticate with the server in different ways. Everything from checking email to logging in, setting up mail-lists. Storing access rights for web applications or just a bookmark collection. We want Lightweight Directory Access Protocol (LDAP). There might be other ways that are simpler but we are in it for the torture. Even if we will not use it to the full potential it is about learning to use it.

As we have created password protected certificate for the LDAP directory, we will also use it. That however means that if we reboot the server it will hang waiting for that password we generated for the certificate. That will of course be hard to enter at a terminal that are more than 1200 km away. (if you do not know the metric system now is the time to look up how far away that is). So we want to turn off the startup of LDAP at boot and just allow one user to log in. As that user becomes root he/she can start the LDAP server using the pass phrase. The same system we will use for other important services as well. This has the disadvantage that the server will need intervention when/if it goes down.

The first look at LDAP and LDAP documentation tells you how to install it with configure and make and the whole cha-bang. When it comes to the structure of LDAP there are little help. Installing LDAP under Debian is not very hard. What is hard is to build a good database. Well, there are often simple examples that show maybe how a department could be organized or similar. One helpful resource I found was the LDAP for Rocket Scientists. It discusses at least a bit over LDAP structures. But all and all just relax. LDAP is just a simple database after all.

Setting up the LDAP

First step is to use the help of Debian and run through the

dpkg-reconfigure slapd

. We answer No to [Omit OpenLDAP server configuration?] to generate a database. DNS domain name is of course your domain name, here in the documentation we use example.org. Then we need to give a name for our organization. Lets pick example.org there to and get on with it. Then comes the Administration password. This password can be created with pwsafe, and this password will rule our systems users eventually. We pick the Berkely DB (BDB). We do not want the database to be removed when slapd is purged, since if it happens by accident we don't want to loose the data. If you have some LDAP database you have to decide if it should be moved out of the way. If you just have played with LDAP before we can safely select Yes. We select No on [Allow LDAPv2 protocol?]. No use to use old stuff when we are building something new. Now we have an initial configuration from where we can start. slapd.conf is new and shiny and we might come back later to add more things to it, but for now it is OK.

First we add encryption. Although most communication will come from applications on the localhost the encryption will be there and working also if we later choose to access it from a far. Adding SSL encryption is also not so complex. First however we need to remove slapd from the startup scripts so that we do not get a problem that we need to enter a pass-phrase at boot. We can check first with

ls -l /etc/rc?.d/*slapd

what start and stop numbers are used. K80 and S19 just tells what order slapd gets started in comparison with other services. To remove slapd we can use

update-rc.d -f slapd
      remove

and if we for some reason would like to restore the boot setting we can use

update-rc.d slapd defaults
      19 80

.

Now we edit the /etc/ldap/ldap.conf. We set the BASE to dc=example, dc=org and URI to ldaps://ldap.example.org. TLS_CACERT can be set to /etc/ssl/example.org-cacert.pem so that the client tools know where to find the CA certificate.

In the file /etc/ldap/slapd.conf we add

	TLSCACertificateFile /etc/ssl/example.org-cacert.pem
	TLSCertificateFile /etc/ldap/cert/cert-ldap.example.org-s.pem
	TLSCertificateKeyFile /etc/ldap/cert/key-ldap.example.org.pem
      

Copy the certificates to the respective place. The files with permission r-- and the cert directory with r-x for user openldap. The rest off the access rights should be turned off. We also add password-hash {SSHA} in slapd.conf to ensure that we hash any password with SSHA when we use the Password Modify extended operation (ldappasswd).

The Access Control List (ACL) is a whole science in itself. Here different access patterns can be decided and set up. We will stick with the original to begin with and maybe we can become more advanced later. This should probably grow to its own section.

By checking with this command we can find out what the database contains

ldapsearch -H ldaps://ldap.example.org/ -D
      "cn=admin,dc=example,dc=org" -W -x

. There you see the everything including the admin user and the accompanying password. Now we need to set the password of the admin

ldappasswd -H ldaps://ldap.example.org -D
      "cn=admin,dc=example,dc=org" -W -x -S

.

We can check that it really was set using the {SSHA} method, by again listing the admin details (now supplying the just set password)

ldapsearch -H ldaps://ldap.example.org -D
      "cn=admin,dc=example,dc=org" -W -x

Copy the password field and paste it into a file, password.txt. Then run

cat password.txt | perl -MMIME::Base64 -ne
      'print decode_base64($_) . "\n"'

. That should print {SSHA}XXXXXXXXXXX where X is your hashed password. Now if you are a cracker that have gotten so far to see the password for some reason, this is the hash you have to crack to get the original password. The password cracker tool John the Ripper can be set up to do it, by patches for SSHA support. With this tool you can also check for week passwords, before any cracker does.

Setting up the LDAP database structure

So, now we have a empty LDAP server. It is a blank page waiting to be written. You have the freedom to choose how it will look like. It is a fantastic freedom. But. To pick a working structure is a bit of a chicken and egg problem. If one do not know LDAP, one can not say what structure will be best for the problem. To find a solution for the problem experience is needed. The only way to gain experience is to pick a structure and see how well it fits to the problem.

Tip

I do not have much experience in picking structures for LDAP, but I have learned the normal forms from SQL. Those rules have helped me pick a structure. Read more about it at Wikipedia

LDAP builds its structure from object classes. These object classes are defined in schema files located in /etc/ldap/schema/. To read these files is pretty tedious as the format is very strict. In the future we might want to make our own object classes but for now we stick with the ones available. First we need to represent users. What is a user? In our case it is not so easy. There are users that will access different kind of services, and most users will not need any login access to the actual server. What predefined classes are there to represent a user? Looking at the basic schemas there are not so many. Using Web2LDAP, connecting with the demo to ldap://ldap.openldap.org one can find a schema browser. It gives a few alternatives: person, pilotPerson, organizationalPerson, inetOrgPerson, OpenLDAPperson,residentialPerson. Add to that posixAccount. Yes, confusing.

The objectClass OpenLDAPperson has some nice properties for simple users while objectClass posixAccount is needed to represent system users. We need an unique identifier and uid makes a good identifier. We start out with the objectClass OpenLDAPperson, which is very small. It gives us a uid and a password field. (some of the other classes does not have a password field). So first we need to add the objectClass OpenLDAPperson to pool of available object classes. Then we need to make another schema available. By adding include /etc/ldap/schema/openldap.schema to /etc/ldap/slapd.conf enables among other things the objectClass OpenLDAPperson. Oh, and we need to restart the LDAP server, I hope you have the SSL cert key handy.

We will set up a flat structure regarding persons (users). To add this we need to use a ldif file. ldif is a special format used for adding LDAP records. Now we start with the following adding the following text to a file, people.ldif.

version: 1

## FIRST Level hierarchy - people

dn: ou=people, dc=example,dc=org
ou: people
description: All people
objectclass: organizationalunit

## SECOND Level hierarchy

dn: uid=user1,ou=people,dc=example,dc=org
objectclass: OpenLDAPperson
cn: User Nr1
sn: Nr1
uid: user1
mail: user1@example.org
description: The user nr 1.
      

This is then added to the database with the command

ldapadd -x -W -H ldaps://ldap.example.org/ -D
      "cn=admin,dc=example,dc=org" -f people.ldif

. Now we need to add a password to the user. To set a password one can generate a password automatically with

ldappasswd

.

ldappasswd -x -W -H
      ldaps://ldap.example.org/ -D "cn=admin,dc=example,dc=org"
      "uid=user1,ou=people,dc=example,dc=org"

sets a generated password to the user1 and prints it.

Now we have a user, but we should also add a bind user for the service the user is using. In this case Subversion. We are adding an application branch with the app.ldif

version: 1

## FIRST Level hierarchy - application

dn: ou=applications,dc=example,dc=org
ou: applications
description: All applications
objectclass: organizationalunit

## SECOND Level hierarchy

dn: cn=subversion,ou=applications,dc=example,dc=org
description: All applications
objectclass: person
cn: subversion
sn: subversion
      

and set a password in the same way as for the user.

Now we have a very small initial structure. It is a start. For each application or service we add to the server we have to extend the LDAP database so that the structure can deal with the specific problems of the application. We will in the chapters for the applications go through the problems to be solved by the LDAP structure and come up with a solution.

We also want to extend the structure with groups. We want to be able to sort people into different groups to be able to give them access to different things.