Google
Web dns.bdat.net

87. Ejemplo de configuración de OpenLDAP

Una buena manera de explicar el funcionamiento y configuración de un servidor LDAP es mediante un ejemplo común de la vida real. A continuación se explicará como migrar la base de datos de usuarios y grupos para poder realizar la autenticación a través del protocolo LDAP.

87.1. Configurando el back-end

Editando el archivo /etc/openldap/slapd.conf, se agrega una base de datos de la siguiente manera:

database    ldbm
suffix      "dc=ejemplo,dc=net"
rootdn      "cn=root,dc=ejemplo,dc=net"
rootpw      {MD5}kuJhGtfsDfglwjhHUTQNmd==
directory   /var/lib/ldap
index       objectClass,uid,uidNumber,gidNumber    eq
index       cn,mail,surname,givenname              eq,subinitial

La primer línea especifica el back-end de base de datos a utilizar, “ldbm” es la opción mas frecuentemente utilizada. La segunda línea declara el DN de la entrada raíz del árbol LDAP. La tercer y cuarta entrada definen los datos del usuario administrador (algo así como su nombre de usuario y contraseña), ya que esta cuenta no puede estar incluida en la base de datos LDAP antes que se haya configurado. La quinta entrada sirve para definir el directorio donde se almacenarán los archivos correspondientes a esta base de datos y las últimas dos entradas establecen los tipos de índice que se van a utilizar en las distintas entradas, para búsquedas.

La contraseña rootpw está cifrada con el algoritmo MD5, esto se puede generar con el comando slappasswd de la siguiente manera:

# slappasswd -h {MD5}

87.2. Configurando las listas de control de acceso

El siguiente paso es configurar las listas de control de acceso, que definirán la clase de acceso que los distintos tipos de usuarios tendrán en el árbol LDAP.

En el archivo /etc/openldap/slapd.conf o en /etc/openldap/slapd.access.conf se agrega lo siguiente:

access to dn=".*,dc=ejemplo,dc=net" attr=userPassword
       by dn="cn=root,dc=ejemplo,dc=net" write
       by self write
       by * auth

Esta primer lista de control de acceso se puede interpretar como: Para los atributos userPassword de todas las entradas bajo "dc=ejemplo,dc=net", se dará permiso de escritura al usuario administrador, al usuario propietario, y al resto se les permitirá la operación de autenticación.

Pero, ¿dónde están los usuarios?. El concepto de usuario tal como se lo conoce normalmente aquí no se aplica, sino que se habla de Bind DN, cada cliente LDAP debe autenticarse con el servidor enlazándose (bind) a éste en una determinada entrada de la jerarquía de la base de datos (DN), que necesariamente deberá poseer un atributo userPassword.

Con esta ACL lo que se hace es proteger el atributo de contraseña para que no cualquier pueda siquiera inspeccionarlo. Luego siguen otras ACLs:

access to dn=".*,dc=ejemplo,dc=net" attr=mail
       by dn="cn=root,dc=ejemplo,dc=net" write
       by self write
       by * read

Este es un ejemplo similar al anterior, pero se permite la lectura del atributo mail (es decir, la dirección de correo electrónico) a cualquiera, mientras que se permite su modificación a la cuenta administrativa y al dueño del atributo.

Si bajo la entrada con DN “ou=People,dc=ejemplo,dc=net” se almacenan las cuentas de usuario del sistema, entonces deberíamos permitir sólo la lectura de estos datos a todo el mundo (sin permitir la modificación de por ejemplo, el nombre de usuario, ni siquiera al propio usuario) de esta manera:

access to dn=".*,ou=People,dc=ejemplo,dc=net"
       by * read

Finalmente se agrega el ACL por defecto, que permite la lectura de todos los atributos por cualquiera, y su modificación por el usuario dueño. Se hace esto de la siguiente forma:

access to dn=".*,dc=ejemplo,dc=net"
       by self write
       by * read

Cada ACL se chequeará en el orden en que fueron declaradas, es por eso que la ACL que se agregó última, no debe declararse antes de otras, porque puede llegar a anular su funcionalidad. Un ejemplo claro es la declaración de la penúltima ACL sobre la última. A primera vista, podría parecer que esa penúltima ACL se encuentra incluída en la última y que por lo tanto podría ser obviada, pero observando detenidamente se puede uno dar cuenta que la penúltima ACL no permite escritura a nadie, bajo la entrada ou=People,dc=ejemplo,dc=net, y que por mas que la última entrada si lo permita, la anterior tiene precedencia.

Si estas ACLs se agregaron en su propio archivo /etc/openldap/slapd.access.conf, entonces habrá que cerciorarse que se incluya este archivo en el archivo de configuración principal /etc/openldap/slapd.conf con la siguiente sintaxis:

include /etc/openldap/slapd.access.conf

Para que se tomen los cambios, recordar de reiniciar el servicio LDAP en el sistema.

87.3. Migración del los datos al servidor LDAP

Una vez configurada la base de datos y las listas de control de acceso, se procede a la migración de los datos preexistentes. En la distribución Mandrake, el paquete openldap-migration instala una serie de herramientas para facilitar enormemente esta tarea.

Dentro del directorio /usr/share/openldap/migration/ se deberá editar el archivo migrate_common.ph cambiando las siguientes declaraciones de variable:

$DEFAULT_MAIL_DOMAIN = "ejemplo.net";
$DEFAULT_BASE = "dc=ejemplo,dc=net";
$DEFAULT_MAIL_HOST = "mail.ejemplo.net";
$EXTENDED_SCHEMA = 1;

Lo siguiente es editar el archivo migrate_all_online.sh y comentar aquellos servicios que no queremos migrar, como por ejemplo:

#$PERL -I${INSTDIR} ${INSTDIR}migrate_protocols.pl $ETC_PROTOCOLS >> $DB

Finalmente se ejecuta dicho script ingresando los datos que va pidiendo.

87.4. Configurando el usuario proxy

La siguiente etapa, consiste en la creación de una entrada especial en el servidor LDAP, que servirá como usuario proxy. Este usuario se utilizará para leer las entradas userPassword de las otras entradas, de tal manera de proveer esa información a los clientes que necesiten autenticarse. Con esto, permitiremos autenticar a aquellos servicios que poseen una interfaz con el servidor LDAP, pero que mantienen su propio esquema de autenticación y por lo tanto no usan la operación auth provista por el servidor LDAP.

El primer paso entonces es crear un archivo LDIF, por ejemplo en /tmp/proxy.ldif cuyo contenido sea el siguiente:

dn: cn=proxyuser,dc=ejemplo,dc=net
cn: proxyuser
sn: proxyuser
objectclass: top
objectclass: person
userPassword: {MD5}kihwqmIGdaIhnqLjashOKJ==

La contraseña se debe crear con el comando slappasswd como se vió anteriormente. Una vez escrito correctamente el archivo LDIF, se lo agrega al servidor ejecutando el comando ldapadd de esta manera:

# ldapadd -x -D "cn=root,dc=ejemplo,dc=net" -W -f /tmp/proxy.ldif

Este comando pedirá la contraseña que se estableció como rootpw en el archivo de configuración, y si todo está correcto, agregará la entrada donde corresponde en la jerarquía de árbol del servidor LDAP.

Una vez agregado el usuario proxy, habrá que permitirle el acceso de lectura al atributo userPassword para que pueda ser utilizado por los mecanismos de autenticación que a continuación configuraremos. Para darle el permiso necesario al usuario proxy, deberemos modificar el primer ACL definido anteriormente, para que quede de esta forma:

access to dn=".*,dc=ejemplo,dc=net" attr=userPassword
       by dn="cn=root,dc=ejemplo,dc=net" write
       by dn="cn=proxyuser,dc=ejemplo,dc=net" read
       by self write
       by * auth

Una vez hecho este cambio, se debe reiniciar el servicio LDAP para que tome la nueva configuración. A continuación se puede realizar una consulta al servidor LDAP mediante el comando ldapsearch:

# ldapsearch -LL -H ldap://localhost -b"dc=ejemplo,dc=net" -W -x -D "cn=proxyuser,dc=ejemplo,dc=net" "(uid=pedro)"

Este comando, después de ingresar la clave correspondiente al usuario proxy, muestra en formato LDIF el resultado de la búsqueda de entradas que tengan el atributo uid con el nombre “pedro”, a partir de la entrada dc=ejemplo,dc=net en adelante (es decir, todo el árbol). Si todo estuvo correctamente configurado, y existe una entrada con tal atributo, entonces se mostrarán todos sus datos, incluyendose el atributo userPassword como se muestra a continuación:

version: 1

dn: userid=pedro,ou=People,dc=ejemplo,dc=net
objectClass: top
objectClass: account
objectClass: person
objectClass: userSecurityInformation
uid: pedro
sn: Picapiedras
cn: Pedro
userPassword:: e01ENX1HcWFsOUpQQWowMHV5VkFVb1MyL3dnPT0=
telephoneNumber: 431-2125

87.5. Configuración de los clientes LDAP

Lo que queda pendiente es configurar aquellas máquinas que vayan a funcionar como clientes del servidor LDAP recién configurado.

Lo primero que se debe hacer es editar el archivo /etc/openldap/ldap.conf y agregarle la siguiente información:

host         <IP_del_servidor_LDAP>
base         dc=ejemplo,dc=net     # Esta entrada es igual al suffix
rootbinddn   cn=proxyuser,dc=ejemplo,dc=net
scope        one

pam_filter                      objectclass=posixaccount
pam_login_attribute             uid
pam_member_attribute            gid
pam_template_login_attribute    uid
pam_password                    md5

nss_base_passwd     ou=People,dc=ejemplo,dc=net?one
nss_base_shadow     ou=People,dc=ejemplo,dc=net?one
nss_base_group      ou=Group,dc=ejemplo,dc=net?one
nss_base_hosts      ou=Hosts,dc=ejemplo,dc=net?one

El campo rootbinddn especifica a qué usuario el root se va a cambiar al intentar conectarse desde la máquina cliente, y la contraseña la va a leer desde el archivo /etc/openldap/ldap.secret, que debe tener modo 600 y contener la contraseña del proxyuser, finalizando con una línea en blanco.

Esto va a permitir que los clientes LDAP para autenticación al querer acceder como root se cambien al usuario proxy y puedan leer los campos userPassword de cada usuario para lograr su finalidad. el inconveniente es que el comando passwd utilizado para que cada usuario se cambie su propia contraseña no funcionaría porque el usuario proxy sólo tiene acceso de lectura sobre ese campo, pero cada usuario podría modificar su contraseña utilizando el comando ldapmodify.

Si quisiéramos hacer que el comando passwd funcione para cambiar las contraseñas de usuario, deberíamos cambiar el ACL del servidor para que el usuario proxy tenga acceso de escritura al campo userPassword, pero esto podría ser un problema de seguridad en aquellos casos que las máquinas cliente sean controladas por otras personas no confiables, porque el archivo /etc/openldap/ldap.secret de cada máquina cliente sería legible por el root local de cada estación.

87.6. Configurando NSS para que use LDAP

NSS es el Name Service Switch que sirve para decirle al sistema cuales son las fuentes de datos para ciertas informaciones, el archivo de configuración es /etc/nsswitch.conf:

passwd:    files ldap
shadow:    files ldap
group:     files ldap
hosts:     files ldap dns

Esto hará que los sistemas clientes consulten primero sus archivos locales, luego hagan búsquedas en LDAP y en el caso de los hosts, hagan consultas por DNS como último recurso.

En el /etc/hosts de los clientes sólo se debería dejar con la entrada del host local, hostname y del servidor LDAP.