Un maño entre gaúchos

Archive for the ‘openLDAP’ tag

LDAP: Introduction

without comments

This is the first post of a LDAP posts collection where I’ll try to explain all what I learned about this technology for the last years.

What is LDAP?

LDAP stands for Lightweight Directory Access Protocol.
LDAP is not a database
LDAP is A protocol to handle information from a Database
One of the most common applications of LDAP is as an authentication backend for an email server. Next, we can see an example:

flujo_ldap_correo

In this picture a happy user tries to check his email from his personal computer. So he sends his login information to the email server. The email server fetches this data and starts talking with the LDAP server. The LDAP server contains all the users information, so if the login information that it is receiving from the mail server matches the information of any user in its database, it is going to return a positive answer to the email server. At this point, the email server knows that the user sent a valid login information, so it will send him his new emails.

In the picture we can see that the email server doesn’t know the physical database where the users information is stored. It only speaks with the LDAP server, and later the LDAP server try to compare the information with the database backend.

LDAP is extremely fast reading and searching information in the database. This is because the elements in a LDAP directory are arranged in a hierarchical tree, so searches are made always downwards. Because of that, LDAP is widely used as an authentication backend for all kind of services, specially the ones with a big amount of users. Write operations are not so fast, but in this kind of applications, users are used to read their personal information from the database, but not to change it.

Data types

In spite of being a hierarchical tree, all elements in the tree are equal. An element has one or more objeClasses that define the element purpose. Every objectclass has one or more required attributes and one or more optional attributes. So, in the end, an element belongs to one or more objectClasses and has one or more attributes depending on the objectClasses it belongs to.
For example, en element representing a person has the person objectClass. So, this element is required to define the attributes sn (surname) and cn (commonName). But at the same time it could have, if it wants it to, the telephoneNumber attribute.

There are a lot of schemas that let the chance to load any kind of data in the tree. You can also create your own schema if there’s not any schema that satisfies your needs.

Structure

Like I said before, a LDAP directory is built with different kinds of elements arranged in a hierarchical tree structure. All the elements have a DN (Distinguished Name) that is an their identity inside the directory. An element DN is built with their own RDN (Relative Distinguished Name) and the RDN of the parent elements to the top element of the tree. This seems a bit confused, so let’s explain it better. Let’s see a small picture:

ldap_diagram2

This is our directory tree. Let’s suppose that I want this directory to authenticate all of the example.com domain users.
Usually when the top element of a tree is a domain, all the parts of the domain name are stored in separated elements. So, com and example are stored in different elements but following the same order.

The com element has the RDN “dc=com“. His RDN is made up with an element attribute. This elements belongs to the dcObject objectclass. This objectClass defines that all element belonging to it has to set the dc (domainComponent) attribute. This element has more attributes but, the main one is dc so it is part of the RDN.

That is the same case with the element example. It belongs to dcObject objectclass. So its dc attribute is part of its RDN. There is another element above, so this elemend DN would be the sum of its RDN and the parent RDN, “dc=example,dc=com“.

Next we have a simple container. We want to store people information, but we could also want to store, for example, groups information. A group and a person are two different kinds of elements. So in that case we would create two different containers in the tree. One for storing people, and another to store groups.
In this case, we only have the People container. This element belongs to organizationalUnit objectClass. This objectClass force the element to set the ou (organizationalUnitName) attribute. So this element RDN is “ou=People”. And its DN is “ou=People,dc=example,dc=com”.

Finally we have the “cn=Luis” element. This is a person and it belongs to the person objectClass. Like I said before, the person objectClass force the element to set the cn and sn attributes. The cn value is “Luis” and the sn value is “Bosque”. We can choose any element attribute to make the RDN. We choosed the cn attribute, but could be also the sn attribute.
So, this element RDN is “cn=Luis” and its DN is “cn=Luis,ou=People,dc=example,dc=com”.

Important: We can’t have two elements in the tree with the same DN. So, in this specific case, we couldn’t have two people with the name “Luis”. It would be possible to have two people with the same attributes but their DN must be different. For example, we can call one of them Luis and the other Luisico.

We can see a bigger example of a LDAP directory tree. This is onle an example. I mean that you can use a LDAP directory to store any kind of information, not only people information. With the right schemas, you can use a directory to create any kind of data structure.

ldap_diagram

LDAP Implementations

There are a lot of servers implementing the LDAP protocol. OpenLDAP, Active Directory, Sun ONE Directory Server, Novell Directory Server, Red Hat Directory Server, etc…

I already worked with some of them but I’m used to work with OpenLDAP, so, in the next posts I will focus on OpenLDAP.
When you install OpenLDAP, in a Linux machine for example, it creates a simple BDB database with a few example data. S

Database Backends

There are also several available database backends to use with OpenLDAP like BDB, HDB, LDIF, etc..
When installing OpenLDAP, the server uses a BDB Database. It happens transparently to the user. So, the people that have just met LDAP don’t need to care about the difference between protocol and database.

Just install openldap and start working on it.

Written by luis

October 23rd, 2009 at 12:25 am

Posted in Sistemas

Tagged with , ,

Ruby, MD5 y OpenLDAP

with 2 comments

Si lo que quieres es almacenar las contraseñas de usuarios de OpenLDAP encriptadas con el algoritmo MD5, hay que tener en cuenta tres cosas.
La primera es que muchos clientes utilizan un recurso para saber de forma automática en que algoritmo está encriptada la contraseña contra la que van a intentar autenticarse. Este recurso, es añadir el nombre del algoritmo delante de la contraseña, por ejemplo:
{MD5}OFj2IjCsPJFfMAxmQxLGPw==

Si no se le fuerza al cliente a que use un algoritmo u otro para autenticarse, mirará (si el cliente está bien implementado) si la contraseña de LDAP tiene entre llaves el nombre del algoritmo y usará en consecuencia ese algoritmo para enviar la contraseña.

Otro tema a tener en cuenta, es el tipo de encriptación MD5. Normalmente la mayoría de librerías de MD5 permiten la encriptación de una cadena en formato hexadecimal y en binario. Para OpenLDAP, no nos sirve ninguno de los dos formatos a pelo. Lo que debemos hacer para que la contraseña esté en el formato correcto en el árbol LDAP, es encriptarla en MD5 binario y codificarla después en Base64 para que sea legible. La implementación de esto en ruby, y más concretamente en un modelo de Rails sería así:

require 'digest/md5'
require 'base64'
class User < ActiveLdap::Base
  before_save :encrypt_password

  def encrypt_password
    self.userPassword = "{MD5}" + Base64.encode64(Digest::MD5.digest(self.userPassword))
  end
end

De ActiveLDAP hablaré un poco otro día.

Lo último a tener en cuenta es que el hecho de guardar contraseñas en MD5 en el árbol LDAP no quiere decir que nuestro sistema sea seguro. Sin contar con todos esos temas de desencriptación por fuerza bruta y todo eso, está el tema del envío de la contraseña por un medio no seguro. Si nuestro cliente (podría ser en este caso una web), no está en la misma máquina que el árbol LDAP, al autenticarse con el método SIMPLE, la contraseña viajará en claro por la red hasta el LDAP.
Para evitar esto tenemos dos opciones. O hacemos que las autenticaciones sean con el método SASL (con DIGEST-MD5 por ejemplo) o simplemente le damos soporte SSL/TLS al slapd, de forma que todo tipo de flujo de paquetes entre el servidor y el cliente vayan encriptados.

Written by luis

May 31st, 2008 at 8:45 am