Nube de tags

Con la colaboración de ...

Preferimos Linux

Síguenos en Facebook

Diario informal de K-nábora

jul 01
2009

Autenticación de ejabberd contra LDAP mediante script externo.

Enviado por K-nábora Bufete Tecnológico en linux

Una de las funciones más interesantes de dicha aplicación es el soporte de LDAP. Sin embargo dicho soporte presenta algunas limitaciones, una de las cuales vamos a intentar resolver aquí.

La verdad es que resulta muy sencillo configurar Ejabberd para que los usuarios con cuentas almacenadas en un servidor LDAP puedan autenticarse. En el caso de utilizar dominios virtuales se pueden indicar configuraciones de LDAP diferentes para cada dominio. Esto permite que para cada dominio se busque a los usuarios en un servidor LDAP distinto o en ramas diferentes de un mismo servidor. Sin embargo, ¿qué ocurre si todas las cuentas de usuario se almacenan en la misma rama de un mismo servidor LDAP y queremos que cada dominio virtual de Ejabbed determine que usuarios pueden ser autentificados utilizando un criterio tal como el grupo al que pertenecen dichos usuarios? Por ejemplo, es bastante común que la información de las cuentas POSIX de todos los usuarios se almacene en ou=People,dc=example,dc=com, mientras que los grupos se guarden en ou=Groups,dc=example,dc=com. Si eso es así podría ser interesante que personas que son miembros de diferentes grupos tengan cuentas de Jabber en diferentes dominios.

Para resolver el problema anterior es necesario que nos olvidemos del soporte LDAP del Ejabber y que utilicemos la autenticación mediante script externo. Para hacerlo basta con añadir las siguientes líneas al archivo de configuración de Ejabberd (/etc/ejabberd/ejabberd.cfg):

{auth_method, external}.
{extauth_program, "/usr/local/sbin/checkpass-ldap"}.

Al igual que con otros mecanismos de autenticación, no es necesario activarlo para todo el servidor, sino que podemos activarlo para dominios virtuales concretos. Para eso sólo es necesario añadir las líneas anteriores dentro de la configuración de los dominios virtuales que nos interesen. Después de cambiar la configuración del servidor sólo tenemos que reiniciarlo para que la nueva configuración surta efecto. A partir de ese momento, cuando un usuario intente acceder al servidor, Ejabberd proporcionará al script indicado en la opción extauth_program el nombre de usuario y la clave del mismo. La tarea del script será la de comprobar si las credenciales son correctas y, en caso de que sea así, notificárselo al Ejabberd para que permita el acceso al usuario.

Así que para resolver el problema comentado he creado un script(hay que recordar quitarle la extesión .txt) en Python que se encarga de autenticar a los usuarios que cumplen con determinados criterios. El script se configurar con un archivo en /etc/ejabberd/checkpass-ldap.conf que podría tal que así:

[DEFAULT]
baseDN: dc=example,dc=com

[staff.example.com]
userBase: ou=People,%(baseDN)s
userFilter: (&(uid=%(user)s)(objectClass=posixAccount))
roleBase: ou=Groups,%(baseDN)s
roleFilter: (&(cn=staff)(memberUid=%(user)s)(objectClass=posixGroup))

El resultado es que cuando un usuario se intenta conectar a un servidor Jabber en el dominio staff.example.com el script hace lo siguiente:

  1. Se conecta al servidor LDAP. En el archivo no se indica esta configuración, por lo que por defecto el script se conecta como anónimo a ldap://127.0.0.1.
  2. Buscar al usuario utilizando como raíz la ruta indicada en userBase y como filtro el indicado en userFilter. Antes de enviar la búsqueda al servidor LDAP, la cadena %(user)s es sustituida por el nombre del usuario. En caso de no encontrar al usuario se le indica al Ejabberd que no es posible autenticar al usuario.
  3. Si se encuentra al usuario se realiza una búsqueda utilizando como raíz la ruta indicada en roleBase y como filtro el indicado en roleFilter. Si la búsqueda no devuelve ningún resultado se le indica al Ejabberd que no es posible autenticar al usuario.
  4. Si la busqueda devuelve algún resultado entonces el script intenta autenticarse en el LDAP utilizando el DN del usuario (que obtuvo en el paso 2) y la clave proporcionada por el mismo. Si son correctas se le indica al Ejabberd que el usuario ha sido autenticado con éxito.

Debido a que se pueden indicar directamente los filtros utilizados en las búsquedas en el LDAP, se pueden establecer todo tipo de criterios para determinar en que dominios virtuales pueden autenticarse un usuario. A continuación paso a resumir las opciones disponibles en el archivos de configuración:

  • Tiene que haber una sección para cada dominio que utiliza el script para autenticar a sus usuarios. Por ejemplo, si queremos autenticar al usuario Esta dirección electrónica esta protegida contra spambots. Es necesario activar Javascript para visualizarla necesitamos una sección [guest.example.com]. La sección especial [DEFAULT] contiene las opciones globales del script.

  • Opciones globales (sección [DEFAULT]):

    • connectionURL: URL del servidor LDAP. Si no se especifica el script utiliza ldap://127.0.0.1.
    • connectionName: DN con el que conectarse al LDAP para realizar las búsquedas. Si no se especifica la conexión será anónima.
    • connectionPassword: Password con la que conectarse al LDAP para realizar las búsquedas.
  • Opciones en la sección de cada dominio (por ejemplo, [guest.example.com]):

    • userBase: DN del objeto en el que buscar al usuario. Es obligatorio indicar esta opción.
    • userFilter: Filtro con el que buscar al usuario (RFC 2254, The String Representation of LDAP Search Filters). Es obligatorio indicar esta opción.
    • userScope: Alcance de la búsqueda. Puede ser uno de los siguientes valores:
      • base: Para buscar en el objeto indicado en userBase en si mismo.
      • one: Para buscar en el objeto indicado en userBase y entre sus hijos inmediatos.
      • sub: Para buscar en el objeto indicado en userBase y entre todos sus descendientes. Es el valor por defecto en el caso de que no se indique esta opción.
    • roleBase: Similar a userBase pero para la segunda búsqueda.
    • roleFilter: Similar a userFilter pero para la segunda búsqueda.
    • roleScope: Similar a userScope pero para la segunda búsqueda.

En las opciones *Base y *Filter se puede utilizar las siguientes variables (utilizando la sintaxis %(variable)s) para que sean sustituidas antes de enviar las búsquedas al servidor LDAP:

  • user. Nombre de usuario de la cuenta.
  • domain. Dominio de la cuenta.
  • jid. JID de la cuenta.
  • dn. Esta variable sólo está definida en roleBase y roleFilter. Contiene el DN encontrado para el usuario en la busqueda definida por userBase y userFilter
  • También se puede utilizar como variable cualquier opción a la que se le asigne un valor en la sección [DEFAULT]
aplatanado - GULIC

Comentarios (0)add
Escribir comentario

security image
Escribe los caracteres de la imagen


busy