Autor: | Javier Sánchez-Monedero |
---|---|
Contact: | jsanchezm arroba uco.es |
Organization: | Grupo de Investigación Aprendizaje y Redes Neuronales Artificiales (AYRNA) . Departamento de Informática y Análisis Numérico (Universidad de Córdoba) |
Version: | 1.0 abril 2013 |
Copyright: | CC-BY-SA |
Estos ejercicios complementan la presentación Integración de sistemas y servicios distribuidos con OpenLDAP. Los ejercicios han sido probados en Ubuntu Server 10.04 LTS.
Este manual asume ciertos conocimientos previos sobre LDAP antes de realizar estos ejercicios. En las últimas versiones de OpenLDAP no es necesario reiniciar el servidor para aplicar la configuración. En esta guía se reinicia una sola vez al principio ya que por mi experiencia con OpenLDAP a veces el backend seleccionado da algunos problemas en algunas distribuciones de GNU/Linux, y la forma de detectarlo es esta.
Nota sobre anglicismos y traducciones:
- A menudo muchas personas traducen "Authenticate" por "Autentificar", cuando la palabra correcta es "Autenticar".
- He traducido la palabra "script" por "guión".
Puedes descargar estar web completa en formato tar.gz. Si quieres generarla necesitas la herramienta rts2html:
rst2html --output-encoding=iso-8859-1 --section-numbering --stylesheet=style.css index.rst > index.html
Por favor, respeta la licencia y envía errores y sugerencias.
Probado con:
Linux ubuntu-sod 2.6.32-38-server 83-Ubuntu SMP x86_64 GNU/Linux Ubuntu 10.04.4 LTS
Versión de los paquetes para el servidor y sistemas operativos clientes LDAP:
ii slapd 2.4.21-0ubuntu5.7 OpenLDAP server (slapd) ii ldap-auth-client 0.5.2 meta-package for LDAP authentication ii ldap-auth-config 0.5.2 Config package for LDAP authentication ii ldap-utils 2.4.21-0ubuntu5.7 OpenLDAP utilities ii libldap-2.4-2 2.4.21-0ubuntu5.7 OpenLDAP libraries ii libnss-ldap 264-2ubuntu2 NSS module for using LDAP as a naming servic ii libpam-ldap 184-8.2ubuntu1 Pluggable Authentication Module for LDAP
Versión de los paquetes para la integración de Apache y PHP con LDAP:
ii apache2 2.2.14-5ubuntu8.9 Apache HTTP Server metapackage ii apache2-mpm-prefork 2.2.14-5ubuntu8.9 Apache HTTP Server - traditional non-threade ii apache2-utils 2.2.14-5ubuntu8.9 utility programs for webservers ii apache2.2-bin 2.2.14-5ubuntu8.9 Apache HTTP Server common binary files ii apache2.2-common 2.2.14-5ubuntu8.9 Apache HTTP Server common files ii libapache2-mod-php5 5.3.2-1ubuntu4.14 server-side, HTML-embedded scripting languag ii php5 5.3.2-1ubuntu4.14 server-side, HTML-embedded scripting languag ii php5-common 5.3.2-1ubuntu4.14 Common files for packages built from the php ii php5-ldap 5.3.2-1ubuntu4.14 LDAP module for php5
Referencia en inglés: https://help.ubuntu.com/10.04/serverguide/C/openldap-server.html
En lo sucesivo utilizaremos la opción "-w contraseña" por comodidad, en un entorno de producción no conviene usar esta opción en el historial de la línea de comandos y la opción -W, que pregunta por la contraseña, sería más segura.
Instalar el servidor OpenLDAP:
$ sudo apt-get install slapd ldap-utils
Para poder utilizar el servidor LDAP, necesitamos configurarlo mediante la carga de algunos esquemas útiles. Para ello ejecutamos:
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif $ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif $ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
Creamos dos archivos llamados backend.foo.net.ldif y backend-modules.foo.net.ldif, los cuales definen la configuración del servidor y lo añadimos a LDAP con:
$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend-modules.foo.net.ldif $ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend.foo.net.ldif
Añadimos el el administrador del backend directorio y ponemos su contraseña a 'secreto' crea-admin-backend.ldif:
$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f crea-admin-backend.ldif
Si queremos cambiar la contraseña del administrador del backend:
$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f cambia-pass-admin-backend.ldif
Y por último, creamos el archivo frontend.foo.net.ldif el cual añade el usuario administrador de LDAP, los grupos necesarios y un usuario de prueba (este último usuario será utilizado como usuario tipo POSIX para la autenticación):
$ sudo ldapadd -x -D cn=admin,dc=foo,dc=net -w prueba -f frontend.foo.net.ldif
Comprobar que funciona mirando mensajes de log y contenido del backend de configuración:
$ tail /var/log/syslog $ sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: cn=config dn: cn=module{0},cn=config dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}hdb,cn=config $ ldapsearch -x -b "dc=foo,dc=net" -D "uid=prueba,ou=People,dc=foo,dc=net" "uid=*" -w prueba
Reiniciamos y vemos que no hay problemas:
$ sudo service slapd restart $ tail /var/log/syslog
Si se están realizando búsquedas por atributos no indexado obtendremos mensajes de este tipo. Por ejemplo, si venimos de la configuración inicial que hemos hecho, una consulta del tipo como la que sigue:
ldapsearch -x -b "dc=foo,dc=net" -D "uid=prueba,ou=People,dc=foo,dc=net" -w prueba "uid=prueba"
Produciría una serie de mensajes de log:
tail /var/log/syslog Apr 11 12:33:34 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uniqueMember) not indexed Apr 11 12:33:34 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uid) not indexed Apr 11 12:33:34 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uid) not indexed Apr 11 12:33:34 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uidNumber) not indexed Apr 11 12:33:34 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uid) not indexed Apr 11 12:53:30 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uid) not indexed
Cambiamos el nivel de log del servidor (loglevelFilterargs.ldif) para asegurarnos que se informa de búsquedas por atributos no indexados (olcLogLevel: filter args):
$ ldapmodify -x -D cn=admin,cn=config -w secreto -f loglevelFilterargs.ldif Enter LDAP Password: modifying entry "cn=config"
Vamos a configurar OpenLDAP para que indexe los atributos que faltan (fichero index-memberUid.ldif):
Podemos comprobar que se han creado una serie de archivos de índices de estos atributos (tarda un poco en aparecer):
$ sudo ls -l /var/lib/ldap total 1512 -rw-r--r-- 1 openldap openldap 2048 2012-04-11 12:11 alock -rw------- 1 openldap openldap 24576 2012-04-11 12:11 __db.001 -rw------- 1 openldap openldap 319488 2012-04-11 13:48 __db.002 -rw------- 1 openldap openldap 2629632 2012-04-11 13:48 __db.003 -rw------- 1 openldap openldap 98304 2012-04-11 13:48 __db.004 -rw------- 1 openldap openldap 1179648 2012-04-11 13:48 __db.005 -rw------- 1 openldap openldap 32768 2012-04-11 13:48 __db.006 -rw-r--r-- 1 openldap openldap 96 2012-04-11 12:10 DB_CONFIG -rw------- 1 openldap openldap 8192 2012-04-11 12:11 dn2id.bdb -rw------- 1 openldap openldap 32768 2012-04-11 12:11 id2entry.bdb -rw------- 1 openldap openldap 10485760 2012-04-11 13:48 log.0000000001 -rw------- 1 openldap openldap 8192 2012-04-11 13:48 memberUid.bdb -rw------- 1 openldap openldap 8192 2012-04-11 12:11 objectClass.bdb
Hacemos una búsqueda incremental sobre el campo 'cn', que no está indexado:
$ ldapsearch -x -b "dc=foo,dc=net" -D "uid=prueba,ou=People,dc=foo,dc=net" -w prueba "cn=Pru*"
Miramos el log:
$ tail /var/log/syslog Apr 11 13:46:28 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (memberUid) not indexed Apr 11 13:48:22 ubuntu-sod slapd[1422]: <= bdb_equality_candidates: (uid) not indexed Apr 11 13:49:22 ubuntu-sod slapd[1422]: last message repeated 5 times Apr 11 13:49:25 ubuntu-sod slapd[1422]: <= bdb_substring_candidates: (cn) not indexed Apr 11 13:52:39 ubuntu-sod slapd[1422]: <= bdb_substring_candidates: (cn) not indexed Apr 11 13:53:15 ubuntu-sod slapd[1422]: <= bdb_substring_candidates: (cn) not indexed Apr 11 13:53:53 ubuntu-sod slapd[1422]: send_ldap_result: err=0 matched="" text="" Apr 11 13:53:53 ubuntu-sod slapd[1422]: send_ldap_result: err=0 matched="" text="" Apr 11 13:53:53 ubuntu-sod slapd[1422]: connection_get(19)
Vemos que aún hay atributos que se demandan para las búsquedas pero no están indexados y los indexamos (index-uid.ldif e index-cn.ldif):
$ ldapmodify -x -D cn=admin,cn=config -w secreto -f index-uid.ldif $ ldapmodify -x -D cn=admin,cn=config -w secreto -f index-cn.ldif $ sudo ls -l /var/lib/ldap/ total 1540 -rw-r--r-- 1 openldap openldap 2048 2012-04-11 12:11 alock -rw------- 1 openldap openldap 24576 2012-04-11 12:11 __db.001 -rw------- 1 openldap openldap 319488 2012-04-11 13:50 __db.002 -rw------- 1 openldap openldap 2629632 2012-04-11 13:50 __db.003 -rw------- 1 openldap openldap 98304 2012-04-11 13:50 __db.004 -rw------- 1 openldap openldap 1179648 2012-04-11 13:50 __db.005 -rw------- 1 openldap openldap 32768 2012-04-11 13:50 __db.006 -rw-r--r-- 1 openldap openldap 96 2012-04-11 12:10 DB_CONFIG -rw------- 1 openldap openldap 8192 2012-04-11 12:11 dn2id.bdb -rw------- 1 openldap openldap 32768 2012-04-11 12:11 id2entry.bdb -rw------- 1 openldap openldap 10485760 2012-04-11 13:50 log.0000000001 -rw------- 1 openldap openldap 8192 2012-04-11 13:48 memberUid.bdb -rw------- 1 openldap openldap 8192 2012-04-11 12:11 objectClass.bdb -rw------- 1 openldap openldap 8192 2012-04-11 13:50 uid.bdb
Restauramos el nivel de log (cambiamos el valor de la directiva olcLogLevel: none):
$ ldapmodify -x -D cn=admin,cn=config -W -f loglevelNone.ldif Apr 13 18:48:30 ubuntu-sod slapd[562]: connection_get(22) Apr 13 18:48:30 ubuntu-sod slapd[562]: send_ldap_result: err=0 matched="" text="" Apr 13 18:48:30 ubuntu-sod slapd[562]: connection_get(22) Apr 13 18:48:30 ubuntu-sod slapd[562]: conn=1013 op=1 do_modify: dn (cn=config) Apr 13 18:48:30 ubuntu-sod slapd[562]: conn=1013 op=1 modifications: Apr 13 18:48:30 ubuntu-sod slapd[562]: #011replace: olcLogLevel Apr 13 18:48:30 ubuntu-sod slapd[562]: #011#011one value, length 5
En el archivo slapd.conf se indicó un nivel de registro ("logs") mediante el parámetro loglevel, pero, ¿a qué archivo (logfile) es enviada esta información? OpenLDAP por defecto envía su información de registro (log) al Daemon syslog (syslogd) bajo el canal LOCAL4, sin entrar en los detalles de syslogd se deben realizar los siguientes pasos:
Modificar el archivo /etc/syslog.conf o /etc/rsyslog.conf (dependiendo de la distribución de GNU/Linux), agregando una linea como la siguiente (esto indica que hay que enviar todo mensaje del canal LOCAL4 al archivo /var/log/openldap):
local4.* /var/log/openldapReiniciar el demonio syslogd con el comando:
$ sudo killall -HUP syslogdO si está integrado con service:
$ sudo service rsyslog stop $ sudo service rsyslog start
Comprobamos que se ha creado el fichero adecuado y se está llenando:
$ ls /var/log/ -lt|head total 35948 -rw-r----- 1 syslog adm 2018953 2010-03-24 10:57 debug -rw-r----- 1 syslog adm 2378 2010-03-24 10:57 openldap.log -rw-r----- 1 syslog adm 333495 2010-03-24 10:57 syslog -rw-r----- 1 syslog adm 97707 2010-03-24 10:56 kern.log
Si metemos la pata en alguno de los pasos anteriores puede suceder que la base de datos interna de OpenLDAP quede corrupta o no podamos acceder al directorio. Para empezar una instalación limpia del servidor OpenLDAP debemos hacer lo siguiente:
sudo apt-get purge slapd sudo rm -Rf /var/lib/ldap
Si te cansas de copiar y pegar desde este manual puedes copiar y pegar todos estos pasos en el terminal para una instalación y configuración básicas:
sudo apt-get -y install slapd ldap-utils sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend-modules.foo.net.ldif sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f crea-admin-backend.ldif sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f cambia-pass-admin-backend.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend.foo.net.ldif sudo ldapadd -x -D cn=admin,dc=foo,dc=net -w secreto -f frontend.foo.net.ldif tail /var/log/syslog sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn ldapsearch -x -b "dc=foo,dc=net" -D "uid=prueba,ou=People,dc=foo,dc=net" "uid=*" -w prueba sudo service slapd restart tail /var/log/syslog
Referencias en inglés:
Instalamos los módulos PAM (Pluggable authentication module) para autenticar contra LDAP:
$ sudo apt-get install libnss-ldap libpam-ldap
Lo anterior nos abre un diálogo de configuración, como en el ejercicio trabajamos todo en local la IP del servidor es la IP local, en un entorno real debes sustituir esta por la IP del servidor LDAP:
ldapi -> ldap://127.0.0.1 distinguished name -> dc=foo,dc=net Make local root Database admin: -> si Does the LDAP database require login? -> no (si en entornos de producción) LDAP account for root -> cn=admin,dc=foo,dc=net LDAP root account password -> secreto
Si queremos reconfigurar la autenticación con LDAP (estos guiones son un añadido de Ubuntu que en el pasado requería la modificación de varios ficheros del directorio /etc/pam.d/):
sudo dpkg-reconfigure ldap-auth-config
Habilitar los perfiles de autenticación PAM y LDAP
sudo auth-client-config -t nss -p lac_ldap sudo pam-auth-update
En el diálogo habilitamos los perfiles Unix y LDAP (deben estar seleccionados por defecto).
Nota de seguridad: el acceso no autenticado en entornos de producción debe valorarse, así como el uso de conexiones seguras en el intercambio de datos LDAP.
Es interesante conocer los siguientes ficheros para comprender el funcionamiento global del sistema de autenticación y para, por ejemplo, poder realizar modificaciones que no sean posibles con los asistentes de configuración.
El fichero /etc/ldap.conf guarda configuración por defecto para los clientes LDAP de una máquina (incluso si esta máquina no autentica sus usuarios contra LDAP). La rellena el asistente de instalación de libpam-ldap.
El fichero /etc/nsswitch.conf guarda la configuración del Name Service Switch
Nota: estos comentarios asumen que no tenemos otros mecanismos de creación de directorios de usuario en los procesos de altas de usuarios.
Si intentamos entrar con el usuario "prueba" (del directorio) obtendremos el siguiente mensaje de error:
Could not chdir to home directory /home/prueba: No such file or directory
Así por último, debemos configurar PAM para que al iniciar sesión por primera vez se cree el directorio del usuario en la ruta especificada en LDAP. Para ello editamos el archivo /etc/pam.d/common-auth y le añadimos:
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
Los siguientes códigos de ejemplo tienen fines didácticos, no hacen comprobación de errores ni generan contenido HTML válido estricto.
Necesitas instalar los siguientes paquetes y cargar una serie de módulos de Apache:
$ sudo apt-get install apache2 $ sudo a2enmod authnz_ldap $ sudo service apache2 restart
Finalmente creamos la siguiente carpeta:
$ sudo mkdir /var/www/privado
Añadir lo siguiente al fichero /etc/apache2/sites-enabled/000-default:
<VirtualHost *:80> [...] <Directory "/var/www/privado"> AuthType Basic AuthName "Acceso protegido" AuthBasicProvider ldap AuthzLDAPAuthoritative Off AuthLDAPURL "ldap://localhost/ou=People,dc=foo,dc=net" Require valid-user </Directory> [...] </VirtualHost>
Y reiniciar Apache:
sudo service apache2 restart
También podrías incluir el siguiente fichero .htaccess en la carpeta privado, en este caso no sería necesario reiniciar Apache:
AuthType Basic AuthName "Acceso protegido" AuthBasicProvider ldap AuthzLDAPAuthoritative Off AuthLDAPURL "ldap://127.0.0.1/ou=People,dc=foo,dc=net" Require valid-user
Depende de la distribución, el directorio /var/www puede o no permitir sobreescribir su configuración con ficheros .htaccess, por ejemplo la configuración siguiente en /etc/apache2/sites-enabled/000-default no lo permite:
<Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory>
Para permitir sobreescribir la configuración la directiva AllowOverride debe permitirlo y tener el valor siguiente:
AllowOverride All
Para que surja efecto la nueva configuración debemos reiniciar Apache:
sudo service apache2 restart
Nota de seguridad: Lo anterior no es directamente aplicable a entornos de producción, AllowOverride debe aplicarse con precaución y controlar qué directivas se pueden modificar.
Visita: <http://localhost/>__ para ver la página por defecto de Apache
Visita <http://localhost/privado/>__ para ver un directorio restringido, necesitas un usuario del directorio LDAP para pasar.
Necesitas instalar los siguientes paquetes:
$ sudo apt-get install php5 libapache2-mod-php5 php5-ldap
Este código PHP se conecta al servidor LDAP (asumiendo que está en la IP 127.0.0.1), realiza una búsqueda e imprime la información obtenida. Copia el fichero ldap.php a la carpeta por defecto de Apache y Visita <http://localhost/ldap.php>__
Descargar el programa ldap.php
Este código accede a información básica de los usuarios (nombre, login, grupo...). Para esto no hay que hacer nada especial salvo usar el API POSIX, ya que NSS se encarga de proporcionar la información que necesita al API POSIX estándar que ofrece la Glibc y GNU/Linux. El programador no necesita preocuparse de dónde está esa información de usuarios.
Descargar el programa infousuario.c
Ejemplo de ejecución:
$ gcc infousuario.c -o infousuario $ ./infousuario prueba Nombre: local,,, Password: x Home: /home/local Número de grupo principal: 1000 Nombre del grupo principal: local local@ubuntu-sod:~/ficherosdemo$ ./infousuario prueba Nombre: prueba Password: * Home: /home/prueba Número de grupo principal: 4000 Nombre del grupo principal: gpruebas
Desde Thunderbird puedes conectarte a LDAP para utilizarlo como libreta de direcciones remota. Pasos:
Carga el siguiente fichero en el directorio <usuarios.ldif>__:
$ ldapadd -x -D cn=admin,dc=foo,dc=net -w secreto -f usuarios.ldif
- En Mozilla Thunderbid, desde la agenda de direcciones:
- Crear nuevo directorio LDAP
- Rellenar el formulario con los datos de contexión del servidor
Prueba a redactar un mensaje nuevo y escribir el nombre de algún usuario del directorio en la casilla de destinatarios.
(c) Javier Sánchez Monedero 2013 — Código fuente ReStructuredText