LDAP
De Guifi.net - Wiki Hispano
LDAP (Lightweight Directory Access Protocol o Protocolo de Acceso Ligero a Directorio) es un protocolo a nivel de aplicación que permite el acceso a un servicio de directorio ordenado y distribuido para buscar diversa información en un entorno de red. LDAP también es considerado una base de datos (aunque su sistema de almacenamiento puede ser diferente) al que pueden realizarse consultas.
Habitualmente, almacena la información de login (usuaria y contraseña) y es utilizado para autenticarse, aunque también es posible almacenar otra información (datos de contacto de la usuaria, ubicación de diversos recursos de la red, permisos, certificados, etc).
En conclusión, LDAP es un protocolo de acceso unificado a un conjunto de información sobre una red.
LDAP Escucha por defecto en el puerto 389. Para cambiar el puerto utiliza:
slapd -h ldap://servidor:nuevo puerto
Contenido
Implementación de ejemplo (en Blogx Populi)
Tenemos montado un servidor ldap en estella64 (antiguo disco duro de orwell), conectado a la red, que mantiene el directorio, que es una base de datos jerárquica, modificable y consultable desde cualquier otra máquina de la red, respecto a una organización, por ejemplo un dominio de internet. Podemos hacer consultas y modificaciones en el directorio, del tipo cambiar el email de la ficha de una persona (ver ejemplos).
OpenLDAP
Existen diversas implementaciones del protocolo LDAP, nosotras nos basamos en la implementación libre openLDAP.
OpenLDAP tiene su propia licencia, la OpenLDAP Public License. Es multiplataforma, aunque nosotras lo usamos sobre Debian GNU/Linux.
OpenLDAP tiene cuatro componentes principales:
- slapd - demonio LDAP autónomo (dentro del paquete slapd).
- slurpd - demonio de replicación de actualizaciones LDAP autónomo (dentro del paquete slapd).
- Librerías de soporte del protocolo LDAP (dentro del paquete libldap2 y otras).
- Utilidades, herramientas y clientes (dentro del paquete ldap-utils).
En este protocolo apuntamos hacia el servidor LDAP principalmente 2 subsistemas del cliente GNU/Linux: pam y nsswitch. Nota: otras aplicaciones pueden ser apuntadas contra LDAP como Exim, Subversion, Trac, MediaWiki, o Samba, por ejemplo.
pam es Pluggable Authentication Modules, y se encarga de librerías para autenticación de aplicaciones y servicios como login, su, passwd, etc.; la configuración de este subsistema está en la #Tabla 2. Archivos del subsistema PAM.
nsswitch es Name Service Switch y se encarga de determinar con qué ficheros autenticar datos como hosts, passwords, grupos, etc.; la configuración de este subsistema está en la #Tabla 3. Archivos del subsistema NSSwitch.
Instalación
Servidor
En Lenny - Version 2.4.11-1
- Se instala el paquete de openLDAP de Debian
apt-get install slapd ldap-utils
en desarrollo
En Etch - Version 2.3.30-5
- Se instala el paquete de openLDAP de Debian
apt-get install slapd ldap-utils
- Se le pone una contraseña y se corre
dpkg-reconfigure
para configurar el servidor
dpkg-reconfigure slapd
- Creación de los contadores uidNumber y gidNumber para que un programa pueda crear entradas LDAP para cuentas Posix:
Crear arhcivo inicializador_del_programa.ldif con el siguiente contenido:
dn: cn=NextFreeUnixId,dc=example,dc=com homeDirectory: /dev/null objectClass: inetOrgPerson objectClass: posixAccount uid: NextFreeUnixId gidNumber: 1000 uidNumber: 1000 sn: NextFreeUnixId cn: NextFreeUnixId
ldapadd -x -D "cn=admin,dc=example,dc=com" -f inicializador_del_programa.ldif -W
En Sarge - Version 2.2.23-8 (la implementación actual en orwell)
- paquetes:
# apt-get install slapd ldap-utils (Se instalarán los siguientes paquetes extras: libiodbc2 libldap-2.3-0) -- configuración slapd: (o dpkg-reconfigure --priority=low slapd) -- do you want to omit the configuration of slapd? - No -- domain name (base) - dc=ldap,dc=example,dc=com -- name organization - ldap.example.com -- admin password - ***elquesea*** -- database backend - BDB -- remove database when slapd is purged? - No -- move old database - depende si empezamos de cero No -- allow protocol ldapv2 - No
aquí, tendríamos que tener un servidor LDAP funcionando:
/etc/init.d/slapd start
comprobar con ps que está en marcha slapd; se puede probar:
$/usr/bin/ldapsearch -x
que tendría que contestar algo aunque no haya registros aún.
- archivo /etc/ldap/slapd.conf
añadimos los índices nuevos y los permisos de modificación
# Indexing options for database #1 index objectClass eq index default sub index cn pres,sub,eq index sn pres,sub,eq # Requerido para soportar pdb_getsampwnam index uid pres,sub,eq # Requerido para soportar pdb_getsambapwrid() index displayName pres,sub,eq # Descomente las siguientes líneas si está almacenando entradas # posixAccount y posixGroup en el directorio index uidNumber eq index gidNumber eq index memberUid eq # Samba 3.* index sambaSID eq index sambaPrimaryGroupSID eq index sambaDomainName eq
- en el mismo archivo:
*access to attrs=sambaLMPassword,sambaNTPassword by dn="cn=manager,dc=ldap,dc=example,dc=com" write by * none
Atención: en el paquete slapd de etch (2.3.30), probablemente la creación de usuario no haga falta, ya que se crea automáticamente el usuario openldap, probablemente se puede omitir lo siguiente:
- añadir usuario slapd
addgroup --system slapd adduser --home /var/lib/ldap --shell /bin/false --no-create-home --ingroup slapd --system slapd chown -R slapd:slapd /etc/ldap /var/lib/slapd /var/lib/ldap /var/run/slapd
- usuario por defecto para slapd en /etc/default/slapd:
SLAPD_USER="slapd" SLAPD_GROUP="slapd"
- creación de los contadores uidNumber y gidNumber
con estas líneas en un archivo (crea_freeId.ldif):
dn: cn=NextFreeUnixId,dc=ldap,dc=example,dc=com objectClass: inetOrgPerson objectClass: sambaUnixIdPool cn: NextFreeUnixId sn: NextFreeUnixId gidNumber: primerGidLibre (escribir el número id) uidNumber: primerUidLibre (escribir el número id)
y el siguiente comando, creamos una entrada especial:
ldapadd -xvWD "cn=manager,dc=ldap,dc=example,dc=com" -f crea_freeId.ldif
que es el registro donde se va a guardar el último uid y gid usados;
hay ejemplos de ficheros de modificaciones para usar con ldapmodify al final de este documento; en una de las instalaciones no ha sido necesario este paso, porque lo hace uno de los interfaces web que hemos instalado phpldapadmin o ldap-account-manager.
- postinstalación:
en función de las aplicaciones que vamos a apuntar al servidor Ldap serán necesarios unos esquemas de atributos u otros; en la instalación del hospital, estamos usando los esquemas que se muestran en la #Tabla 1. Orden de carga de esquemas para el servidor LDAP.
Esquemas
El árbol completo LDAP se genera a partir de archivos-esquema (en /etc/ldap/schema), que definen el árbol de clases y atributos permitidos para la organización; si a una entrada le añadimos
- la clase InetOrgPerson, eso nos permitirá almacenar los atributos propios de esa clase, por ejemplo, el campo mail.
- la clase posixAccount que nos permitirá añadir los campos homeDirectory, loginShell, etc.
Los esquemas que hemos utilizado para nuestra instalación están en la Tabla 1 (hay que ponerlos por ese orden, eso es importante!!):
Tabla 1. Orden de carga de esquemas para el servidor LDAP
archivo /etc/ldap/slapd.conf
include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/misc.schema include /etc/ldap/schema/authldap.schema include /etc/ldap/schema/exim4.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/samba.schema
el esquema exim4.schema lo cargué para hacer unas pruebas sobre el correo, pero no lo estamos usando en este momento, podría eliminarse; si hay algún problema con la carga de los esquemas (faltan ficheros, se carga en otro orden, etc), el servidor slapd no arranca ...
Clientes
instalación cliente ldap para cuentas GNU/Linux
A partir de este directorio central, ajustamos el resto de ordenadores de la red (los que van a ser clientes ldap), para que distintos subsistemas suyos (el subsistema de usuarias, o las usuarias de subsistemas samba, etc.) utilicen algunos campos del directorio del servidor para realizar acciones que normalmente harían con información local; por ejemplo, si un equipo GNU/Linux normalmente autentifica sus usuarias contra /etc/password, /etc/shadow y otros archivos locales, al convertirlo en cliente ldap ya no buscará los datos de sus usuarias en esos archivos locales, sino en algunos campos de la base de datos del servidor ldap, por ejemplo, actuará según las siguientes equivalencias:
datos de usuaria | archivo sin cliente ldap | campo con cliente ldap |
---|---|---|
id_usuaria | /etc/password
|
cn
|
shell | /etc/password
|
loginShell
|
directorio Home | /etc/password
|
homeDirectory
|
grupo | /etc/groups
|
gidNumber
|
Resumiendo, cuando haces login en una máquina cuyo sistema de usuarios es cliente ldap, la máquina se conecta al servidor, le pide los datos de tu ficha y te toma como usuaria local, dándote la shell que diga loginShell, colocando tus ficheros donde diga homeDirectory, etc.
Como contrapartida, por supuesto, si no existe tu ficha, o estás marcado como cuenta desactivada, o hay algún problema, te quedas sin entrar en ninguna de las máquinas que tienes como clientes ldap, hasta que arregles tu ficha ldap, o hasta que vuelvas a apuntar el sistema de usuarias a los ficheros locales; el cliente se puede configurar de las dos maneras, para que admita usuarias ldap además de las usuarias locales, o sólo una de ambas, depende de la arquitectura que buscamos.
Subsistema PAM:
- libldap2 ........ (viene instalado); cambiar en /etc/ldap/ldap.conf) los valores BASE y URI apuntando al servidor LDAP:
BASE dc=ldap,dc=example,dc=com URI ldap://ip_servidor_ldap
- libpam-ldap ..... (apt): cambiar en /etc/pam_ldap.conf los valores:
base dc=ldap,dc=example,dc=com ldap_version 3 rootbinddn cn=manager,dc=ldap,dc=example,dc=com
- crear el fichero /etc/ldap.secret (modo 0600) con el password del manager de ldap
- cambiar en /etc/pam.d los ficheros de PAM, según Tabla 2:
- instalar libpam-cracklib (apt; no se configuran archivos, lo usa common-password)
Tabla 2. Archivos del subsistema PAM
- archivo /etc/pam.d/common-account
account required pam_unix.so account sufficient pam_ldap.so
- archivo /etc/pam.d/common-auth
auth sufficient pam_unix.so auth sufficient pam_ldap.so try_first_pass auth required pam_env.so auth required pam_securetty.so auth required pam_unix_auth.so auth required pam_warn.so auth required pam_deny.so
- archivo /etc/pam.d/common-password
password required pam_cracklib.so retry=3 minlen=8 difok=4 password sufficient pam_unix.so use_authtok md5 shadow password sufficient pam_ldap.so use_authtok password required pam_warn.so password required pam_deny.so
archivo /etc/pam.d/common-session
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 session required pam_limits.so session required pam_unix.so session optional pam_ldap.so
Subsistema NSSwitch
- nscd
instalado con apt, archivo de configuración en /etc/nscd.conf, mantenemos versión por defecto;
- libnss-ldap
instalado con apt, arranca el programa de configuración y pide ip del servidor, base del dominio, version de LDAP, modo 0600; usa /etc/libnss-ldap.conf
- libpam-dotfile
instalado con apt, contiene el programa pamtest para testear la autenticación contra diferentes servicios y usuarios
Y ahora, para convertir el sistema en cliente:
- cambiar /etc/nsswitch.conf, para convertir el sistema en cliente ldap, según Tabla 3
- hay que recargar el demonio de ssh (/etc/init.d/ssh reload) para que los usuarios LDAP pudieran acceder por ssh.
Tabla 3. Archivos del subsistema NSSwitch
archivo /etc/nsswitch.conf
# /etc/nsswitch.conf # Example configuration of GNU Name Service Switch functionality. # If you have the `glibc-doc' and `info' packages installed, try: # `info libc "Name Service Switch"' for information about this file. passwd: compat ldap group: compat ldap shadow: compat ldap hosts: files dns ldap networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: ldap nis
Administración
Servidor
Todas las tareas de administración modificaciones, altas, cambios, copias de seguridad del árbol ldap, etc. se pueden hacer con las ldap-utils desde linea de comandos, pero hay excelentes interfaces web libres y escritas en php para hacer todo esto muy fácil, de forma que podremos hacer cualquier modificación en datos de usuaria desde cualquier navegador de cualquier máquina de la red (activar usuarios, cambiar password,...)
Log
Para activar el log de LDAP se edita el archivo /etc/syslog.conf
# guardar log de OpenLDAP local4.* /var/log/ldap.log
Y se reinicia el demonio del syslog para que el cambio tenga efecto:
/etc/init.d/sysklogd reload
De forma que el log quedará en el archivo /var/log/ldap.log
Para marcar el nivel de detalle del log se define en el archivo /etc/ldap/slapd.conf
en la directiva loglevel
, siendo 256 un valor recomendable. El grado de detalle del log se define en la página del manual de slapd.conf
:
loglevel <integer> Specify the level at which debugging statements and operation statistics should be syslogged (currently logged to the syslogd(8) LOG_LOCAL4 facility). Log levels are additive, and available levels are: 1 trace function calls 2 debug packet handling 4 heavy trace debugging 8 connection management 16 print out packets sent and received 32 search filter processing 64 configuration file processing 128 access control list processing 256 stats log connections/operations/results 512 stats log entries sent 1024 print communication with shell backends 2048 entry parsing
Clientes
También se simplifica al máximo la administración de los clientes, básicamente copias de los datos de usuaria, porque todos los datos de usuarias, grupos, permisos, etc. están en el servidor; para remontar un cliente GNU/Linux que se ha roto, se instala un sistema base, se restauran de las copias los $home de los usuarios y se pone como cliente ldap; todo el mundo tiene ya su usuaria, password, etc. de siempre
Actualización
Servidor
Vía phpldapadmin del origen, opción Exportar, seleccionar "Todo el sub-árbol" y "Guardar sistema de atributos" en ldif. "Proceder".
Vía phpldapadmin del destino, opción Importar, seleccionar el archivo ldif anteriormente guardado.
Ejemplos
- Mostrar campos
description
,homeDirectory
ymail
del registro cuyocn=carlos
(-LLL salida corta)
# ldapsearch -x cn=carlos description homeDirectory mail -LLL dn: uid=carlos,ou=usuarios,dc=ldap,dc=example,dc=com description: Carlos González mail: carlos@example.com homeDirectory: /home/carlos
- ver listado de usuarias
ldapsearch -x uid
- consulta de los uidNumber de usuario para controlar que no se están duplicando:
ldapsearch -x uidNumber -LLL|grep uidNumber|cut -f2 -d:|sort
- búsqueda con autenticación simple en formato minicorto
ldapsearch -x cn=carlos -LLL
- modificaciones de registros ldap basadas en un archivo de modificación
ldapmodify -D "cn=manager,dc=ldap,dc=example,dc=com" -x -W -f mail.ldif
donde el archivo mail.ldif contiene las modificaciones a realizar:
dn: uid=carlos,ou=usuarios,dc=ldap,dc=example,dc=com changetype: modify replace: mail mail: carlos@example.com
- copia y restauración de la base de datos LDAP completa
# slapcat -l todo_ldap.ldif
... modificaciones pertinentes al fichero antes de la carga ...
# slapadd -l todo_ldap.ldif
- ejemplos de lectura de datos LDAP desde bash para su uso en shell scripts
export email=`ldapsearch -x cn=carlos mail -LLL|grep 'mail:'|cut -f2 -d' '`
- establecer el password del usuario fgonzalez a 'passguord' (hay que poner el dn: del usuario que se modifica entero, tal como lo saca ldapsearch sin 'dn:'):
# ldappasswd -xvWD "cn=manager,dc=example,dc=com" -s passguord "uid=fgonzalez,ou=usuarios,dc=example,dc=com"
Enter LDAP Password: (aquí te pide el del manager de ldap) ldap_initialize( <DEFAULT> ) Result: Success (0)
- si queremos que se lo pida al usuario interactivamente:
# ldappasswd -xvWD "cn=manager,dc=example,dc=com" -S "uid=fgonzalez,ou=usuarios,dc=example,dc=com"
New password: (el nuevo de fgonzalez) Re-enter new password: (otra vez) Enter LDAP Password: (el del manager de ldap) ldap_initialize( <DEFAULT> ) Result: Success (0)
- añadir usuarios desde bash:
creamos el archivo crea_user.ldif con las siguientes líneas:
dn: uid=graso,ou=usuarios,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount givenName: Gregorio sn: Raso cn: graso uid: graso uidNumber: 10018 gidNumber: 10000 homeDirectory: /home/graso loginShell: /bin/bash userPassword: {CRYPT}6Ycc3R9YxCbnI gecos: Gregorio Raso description: Gregorio Raso mail: graso@example.com
el valor de userPassword: lo he obtenido con:
# slappasswd -h {CRYPT} -v New password: soygraso Re-enter new password: soygraso {CRYPT}6Ycc3R9YxCbnI
copiando lo que nos devuelve {CRYPT}6Ycc3R9YxCbnI y pegándolo en el campo userPassword: del archivo crea_user.ldif; y por fín añadimos el usuario con:
# ldapmodify -axvWD "cn=manager,dc=example,dc=com" -f /home/manager/crea_user.ldif donde: -a: añadir al árbol ldap (no es modificación) -x: autenticación simple (sin SSL, etc.) -v: verbose -W: pídeme el password del DN con que me autentifique -D "dn": el dn: completo del usuario que hace la modificación o que añade (el manager de LDAP, generalmente) -f fichero: fichero donde escribo las modificaciones
- reiniciar el demonio que cachea nombres:
/etc/init.d/nscd restart
- el $HOME de usuarias ldap lo crea el primer ssh;
- el $HOME/Maildir/... lo crea el MTA al llegar el primer email si ya existe $HOME;
- formato de almacenamiento de password en ldap-account-manager; se indica en
/var/lib/ldap-account-manager/config/lam.conf pwdhash: CRYPT
de momento hacemos gestión de password desde lam, si hubiera que hacerla desde shell scripts:
- cambios de password d usuaria desde shell scripts:
# export pas=`slappasswd -h {CRYPT}` New password: Re-enter new password: # export bind='cn=superwoman,dc=example,dc=com' # ldapmodify -xvWD $bind << Eot dn: uid=milogin,ou=usuarios,dc=example,dc=com changetype: modify replace: userPassword userPassword: $pas Eot
Resolución de problemas habituales
El cliente de correo no funciona bien a la hora de autenticar aunque el servidor de LDAP esté funcionando
en desarrollo
Solución rápida
Reiniciar el servidor virtual donde está alojado el servidor de correo.
Solución buena
en desarrollo
Solución definitiva (el problema no vuelve a ocurrir)
en desarrollo
Origen del problema
El servidor LDAP estuvo caído y el servidor de correo intentó conectar con él en ese momento seguramente a través de una petición de un cliente, al no poder conectar con él se queda con algún tipo de marca y, aunque el servidor LDAP vuelva al servicio habitual el servidor de correo mantiene la marca.