Beruflich Dokumente
Kultur Dokumente
Toby Burress
kurin@causa-sui.net
Este documento pretende servir como un punto de partida de la configuración de un servidor LDAP
(principalmente un servidor OpenLDAP) para la autenticación en FreeBSD. Esto es muy útil en
situaciones cuando muchos servidores necesitan las mismas cuentas de usuario, por ejemplo cuando uno
quiere reemplazar NIS.
Tabla de contenidos
1. Prefácio ......................................................................................................................................................................1
2. Configuración de LDAP ...........................................................................................................................................2
3. Configuración del cliente..........................................................................................................................................6
4. Consideraciones de seguridad................................................................................................................................10
A. Herramientas útiles................................................................................................................................................12
B. Certificados OpenSSL para LDAP .......................................................................................................................12
1. Prefácio
Este documento intentará exponer los conocimientos necesarios para configurar un servidor LDAP. Tratará de
proveer una explicación de net/nss_ldap para usar con los servicios clientes y con el servidor LDAP.
Cuando haya terminado, el lector será capaz de configurar y montar un servidor FreeBSD que pueda gestionar un
directorio LDAP y otro servidor FreeBSD que pueda autenticarse a través del directorio LDAP.
Este artículo no pretende ser una guía exhaustiva de seguridad, robustez, o las mejores condiseraciones y práticas de
la configuración de LDAP o los otros servicios mencionados aquí. A pesar del mayor esfuerzo del autor para hacer
todo correctamente, no trataremos de los temas de seguridad más allá de un alcance general. Este artículo debe
1
Autenticación LDAP
considerarse sólo un fondo teórico. Una implementación verdadera debe realizarse con un profundo análisis de
requerimientos.
2. Configuración de LDAP
LDAP significa “Lightweight Directory Access Protocol” (“Protócolo Simple de Acceso de Directorios”) y es un
derivado del protócolo X.500 Directory Access Protocol. Su especificación más reciente está disponible en RFC4510
(http://www.ietf.org/rfc/rfc4510.txt) y sus derivados. Escencialmente, esto es una base de datos que está optimizada
más para la lectura que para la escritura.
En los ejemplos de este documento se usará el servidor LDAP OpenLDAP (http://www.openldap.org/). No obstante,
los principios aquí expuestos generalmente funcionarán con distintos servidores pero la mayoría de la administración
concreta es específica de OpenLDAP. Existen varias versiones del servidor en el Ports Collection, por ejemplo
net/openldap23-server. Los servidores necesitarán las correspondientes bibliotecas de
net/openldap23-client.
Básicamente, existen dos partes del servicio LDAP que tienen que configurarse. La primera es la configuración del
servidor para que acepte conexiones apropiadamente, y la segunda es agregar entradas en el directorio del servidor
para que las herramientas de FreeBSD sepan cómo interactuar con él.
Nota: Esta sección es específica para OpenLDAP. Si usa otro servidor, debe consultar la documentación
adecuada.
# cd /usr/ports/net/openldap24-server
# make install clean
Esto instala los binarios slapd y slurpd, además de todas las bibliotecas requeridas por OpenLDAP.
2
Autenticación LDAP
servidor SMTP, el cual emplea TLS escuchará las conexiones a través del puerto convencional que es el 25, al igual
que un servidor LDAP escuchará a través del 389.
SSL significa “Secure Sockets Layer” (“Capa de conexión segura”), y los servicios que implementan SSL no
escuchan a través de los mismos puertos como su contraparte sin implementar SSL. Por esta razón SMTPS escucha a
través del puerto 465 (en vez del 45), HTTPS escucha a través del 443, y LDAPS a través del 636.
La razón por la que SSL usa otro puerto diferente que TLS es porque la conexión TLS comienza en texto plano y
cambia al tráfico cifrado después de la directiva STARTTLS. Las conexiones SSL se cifran desde el comienzo. Aparte
de esto, no hay mucha diferencia entre ambos.
Nota: Ajustaremos OpenLDAP con TLS, debido a que SSL se considera obsoleto.
Una vez que OpenLDAP esté instalado desde el Ports Collection, se podrá habilitar TLS con los siguientes
parámetros de configuración en el fichero /usr/local/etc/openldap/slapd.conf:
security ssf=128
TLSCertificateFile /path/to/your/cert.crt
TLSCertificateKeyFile /path/to/your/cert.key
TLSCACertificateFile /path/to/your/cacert.crt
Aquí, la directiva ssf=128 especifica que OpenLDAP requerirá un cifrado de 128 bit para todas las conexiones, es
decir, para la búsqueda y para la actualización. Este parámetro puede emplearse según las necesidades de seguridad
que tenga su infraestructura pero rara vez tendrá que reducirlo debido a que la mayoría de las bibliotecas cliente de
LDAP soportan cifrado fuerte.
Los ficheros cert.crt, cert.key, y cacert.crt son necesarios para que los clientes lo identifiquen como el
servidor válido LDAP. Si simplemente quiere un servidor que funcione, puede crear un certificado propiamente
firmado con OpenSSL:
En este punto tiene que introducir varios valores. Puede introducir cualquier valores según sus preferencias pero es
importante que el valor “Common Name” sea el nombre de dominio completamente calificado del servidor
OpenLDAP. En nuestro caso, y en los ejemplos aquí expuestos, el servidor se llama server.example.org .
Introducir incorrectamente este valor causará que los clientes fallarán cuando pretenden establecer las conexiones.
Esto puede causar una gran frustación, así que asegúrese de seguir estos pasos al pie de la letra.
Finalmente, el pedido de firmado del certificado necesita firmarse:
3
Autenticación LDAP
% openssl x509 -req -in cert.csr -days 365 -signkey cert.key -out cert.crt
Signaustedre ok
subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd
Getting Private key
Esto creará un certificado propiamente firmado que puede usarse a través de las directivas en slapd.conf, donde
cert.crt y cacert.crt son el mismo fichero. Si usa varios servidores OpenLDAP (con replicación por slurpd)
deberá ver en Apéndice B cómo generar una clave CA y usarla para firmar los certificados de los servidores.
Una vez que esto esté hecho, ponga lo siguiente en el fichero /etc/rc.conf:
slapd_enable="YES"
Luego ejecute /usr/local/etc/rc.d/slapd start. Esto arrancará el servicio OpenLDAP. Confirme que el
servicio escuche a través del puerto 389:
% sockstat -4 -p 389
ldap slapd 3261 7 tcp4 *:389 *:*
base dc=example,dc=org
uri ldap://server.example.org/
ssl start_tls
tls_cacert /path/to/your/cacert.crt
Nota: Es importante que sus clientes tengan acceso al fichero cacert.crt ya que sin éste, no serán capaces
de conectarse.
Nota: Hay dos ficheros llamados ldap.conf. Éste es el primero del que se trata ahora. Éste pertenece a las
bibliotecas de OpenLDAP y define la comunicación con el servidor. El segundo es el fichero
/usr/local/etc/ldap.conf y pertenece a pam_ldap.
En este punto ya será capaz de ejecutar ldapsearch -Z en el cliente. La opción -Z habilita el uso de TLS. Si
encuentra un error algo estará mal configurado. En la mayoría de los casos es algo relacionado a sus certificados. Use
s_client y s_server de openssl(1) para asegurarse de que los tiene configurados y firmados apropiadamente.
4
Autenticación LDAP
dn: ou=people,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: people
dn: uid=fulano,ou=people,dc=example,dc=org
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: top
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/ustedser
loginShell: /bin/csh
uid: ustedser
cn: ustedser
Yo comienzo los UID de mis usuarios de LDAP desde 10000 para evitar interferencias con las cuentas del sistema.
Usted puede configurar otro número según prefiere pero tenga en cuenta que debe ser menor de 65536.
También necesitamos las entradas de los grupos. Éstos pueden configurarse como las entradas de los usuarios pero
por defecto usaremos lo siguiente:
dn: ou=groups,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: groups
5
Autenticación LDAP
dn: cn=ustedser,ou=groups,dc=example,dc=org
objectClass: posixGroup
objectClass: top
gidNumber: 10000
cn: ustedser
Para proceder este cambio en su base de datos puede ejecutar slapadd o ldapadd con un fichero que contenga
estas entradas. Alternativamente, puede usar sysutils/ldapvi.
La utilidad ldapsearch en el cliente ya debe reconocer estas entradas. Si es así, su base de datos está debidamente
configurada para ser un servidor de autenticación LDAP.
3.1. Autenticación
El port security/pam_ldap se configura en /usr/local/etc/ldap.conf.
Así de este modo, tenemos que copiar todos nuestros originales parámetros de configuración de
openldap/ldap.conf al nuevo fichero ldap.conf. Una vez que esté hecho, tenemos que comunicarle a
security/pam_ldap lo que tiene que comprobar en el servidor del directorio.
Identificamos nuestros usuarios con el atributo uid. Para configurar esto (aunque éste es el comportamiento por
defecto), cambie la directiva pam_login_attribute en ldap.conf:
pam_login_attribute uid
Con este cambio, security/pam_ldap buscará el ditectorio LDAP entero bajo base por el valor uid=username.
Si encuentra una y sólo una entrada intentará conectarse con ese usuario y la contraseña introducida. Si puede
conectarse correctamente, entonces permitirá el acceso. En caso de que no sea así fallará.
6
Autenticación LDAP
3.1.1. PAM
PAM, el cual significa “Pluggable Authentication Modules”, (“módulos extensibles de autenticación”) es el método
por el cual FreeBSD autentica la mayoría de sus sesiones. Para comunicarle a FreeBSD que nosotros deseamos usar
un servidor LDAP tendremos que agregar una línea apropiada en el fichero de PAM.
La mayoría del tiempo el fichero apropiado de PAM es /etc/pam.d/sshd. Si quiere usar SSH (recuerde ajustar las
opciones revelantes en /etc/ssh/sshd_config o en caso contrario SSH no usará PAM).
Para usar PAM para la autenciación, agregue la siguiente línea:
La ubicación exacta de esta línea en el fichero y las opciones de la cuarta columna determinan el mecanismo exacto
de autenticación. Véase pam.d(5).
Con esta configuración será capaz de autenticar un usuario a través de un directorio LDAP. PAM conectará con sus
credenciales y si tiene éxito le comunicará a SSH que permita el acceso.
Sin embargo, no es una buena idea permitir acceso a cada usuario en el directorio a cada cliente. Con la
configuración actual todo lo que uno necesita para conectarse a una máquina es una entrada en el directorio LDAP.
Afortunadamente, existen unas cuantas maneras de restringir el acceso de un usuario.
El fichero ldap.conf dispone de una directiva pam_groupdn. Cada usuario que se conecta a esta máquina tiene
que ser un miembro del grupo especificado aquí. Por ejemplo, si tiene
pam_groupdn cn=servername,ou=accessgroups,dc=example,dc=org
en ldap.conf, entonces sólo los miembros de ese grupo serán capaces de ingresarse. Sin embargo, hay unas
cuantas consideraciones para tener en cuenta.
Los miembros de este grupo se especifican en uno o más atributos memberUid, y cada atributo tiene que tener el
nombre distintivo completo del miembro. Así que memberUid: menganito no funcionará sino que tiene que ser:
memberUid: uid=menganito,ou=people,dc=example,dc=org
Además, esta directiva no se verifica durante la autenticación de PAM sino que durante la gestión de la cuenta, así
que necesitará una segunda línea en sus ficheros PAM bajo account. Esto requerirá que cada usuario esté incluido
en el grupo, lo cual no necesariamente es conveniente. Para no bloquear usuarios que no están en el directorio LDAP
tiene que habilitar el atributo ignore_unknown_user. Finalmente, debe habilitar la opción
ignore_authinfo_unavail para que no esté bloqueado en cada cliente cuando el servidor LDAP está fuera de
servicio.
Su pam.d/sshd debería parecer a algo como esto:
7
Autenticación LDAP
Nota: Ya que agreguemos estas líneas específicamente a pam.d/sshd, esto tendrá sólo un efecto en las
sesiones SSH. Los usuarios de LDAP no serán capaces de ingresarse por la consola. Para cambiar este
comportamiento examine los otros ficheros en /etc/pam.d y modifíquelos apropiadamente.
group: compat
passwd: compat
con
Esto le permitirá a mapear los nombres de usuario a los UID y los UID a los nombres de usuario.
¡Felicitaciones! En este punto ya tendrá la autenticación funcionando con LDAP.
3.3. Advertencias
Desgraciadamente, al mismo tiempo que esto era escrito, FreeBSD no soportaba el cambio de contraseñas de usuario
con passwd(1). Por eso la mayoría de los administradores implementa una solución propia. Enumeramos algunos
ejemplos aquí. Recuerde que si escribe su propio script de cambio de contraseñas, hay algunos asuntos de seguridad
que debe tener en cuenta. Véase Sección 4.3.
#!/bin/sh
stty -echo
read -p "Old Password: " oldp; echo
read -p "New Password: " np1; echo
read -p "Retype New Password: " np2; echo
stty echo
8
Autenticación LDAP
fi
ldappasswd -D uid="$USER",ou=people,dc=example,dc=org \
-w "$oldp" \
-a "$oldp" \
-s "$np1"
AtenciónEste script casi no verifica los errores pero lo importante es que sea muy cuidadoso con el
almacenamiento de las contraseñas. Si escribe un script como éste, al menos ajuste el valor sysctl
security.bsd.see_other_uids:
# sysctl security.bsd.see_other_uids=0.
Una solución más flexible (y probablemente más segura) puede ser escribir un programa customizado, o incluso una
interfaz web. Lo siguiente es parte de una biblioteca Ruby que puede cambiar contraseñas de LDAP. Éste maneja
tanto con la línea de comandos como con la web.
require ’ldap’
require ’base64’
require ’digest’
require ’password’ # ruby-password
ldap_server = "ldap.example.org"
luser = "uid=#{ENV[’USER’]},ou=people,dc=example,dc=org"
# get the new password, check it, and create a salted hash from it
def get_password
pwd1 = Password.get("New Password: ")
pwd2 = Password.get("Retype New Password: ")
salt = rand.to_s.gsub(/0\./, ”)
pass = pwd1.to_s
hash = "{SSHA}"+Base64.encode64(Digest::SHA1.digest("#{pass}#{salt}")+salt).chomp!
reustedrn hash
end
# We’ll just replace it. That we can bind proves that we either know
# the old password or are an admin.
9
Autenticación LDAP
Aunque no garantiza que esté libre de huecos de seguridad (por ejemplo, la contraseña se almacena en la memoria)
esto es más limpio y más flexible que un simple script sh.
4. Consideraciones de seguridad
Ahora que sus máquinas (y posiblemente otros servicios) se autentican a través de su servidor LDAP, este servidor
necesita una protección por lo menos tan fuerte que el fichero /etc/master.passwd tendría en un servidor regular
y posiblemente incluso más así que un servidor LDAP crackeado o roto rompería el servicio en cada cliente.
Recuerde que esta sección no es exhaustiva. Debe continuamente revisar su configuración y sus procedimientos para
mejorar el servicio.
access to dn.subtree="ou=people,dc=example,dc=org"
attrs=userPassword
by self write
by anonymous auth
by * none
access to *
by self write
by * read
Esto no permitirá la lectura del atributo userPassword, mientras que todavía está permitido que los usuarios
cambien sus propias contraseñas.
Además, también querrá evitar que los usuarios puedan cambiar algunos de sus propios atributos. Por defecto, los
usuarios pueden cambiar cualquier atributo (excepto aquellos cuyos propios esquemas del directorio LDAP
denieguen cambios) incluso su uidNumber. Para evitar este riesgo, modifique lo de encima por:
access to dn.subtree="ou=people,dc=example,dc=org"
attrs=userPassword
by self write
10
Autenticación LDAP
by anonymous auth
by * none
access to attrs=homeDirectory,uidNumber,gidNumber
by * read
access to *
by self write
by * read
Esto parará a los usuarios de ser capaces de enmascararse como otros usuarios.
dn: cn=homemanagement,dc=example,dc=org
objectClass: top
objectClass: posixGroup
cn: homemanagement
gidNumber: 121 # required for posixGroup
memberUid: uid=fulano,ou=people,dc=example,dc=org
memberUid: uid=menganito,ou=people,dc=example,dc=org
Ejemplo 11. Listas de control de acceso (ACL) para un grupo de administración del directorio home
access to dn.subtree="ou=people,dc=example,dc=org"
attr=homeDirectory
by dn="cn=homemanagement,dc=example,dc=org"
dnattr=memberUid write
Ahora fulano y menganito pueden cambiar los directorios home de otros usuarios.
11
Autenticación LDAP
En este ejemplo les hemos dado una componente de poder administrativo a ciertos usuarios sin darles poder en otros
dominios. La idea es que una cuenta de usuario no tenga simplemente todo el poder de una cuenta root pero cada
poder de root tiene que tenerlo al menos un usuario. La cuenta root entonces llega a ser innecesaria y puede
borrarse.
A. Herramientas útiles
Existen unos cuantos programas que pueden ser útiles, particularmente si tiene muchos usuarios y no quiere
configurar nada a mano.
El port security/pam_mkhomedir es un módulo de PAM que siempre triunfa. Su propósito es crear directorios
home para los usuarios que no lo tengan. Si tiene una docena de servidores y clientes y cientos de usuarios, esto es
mucho más fácil de usar y construir el esqueleto de directorios que preparar cada directorio de home
independientemente.
El port sysutils/cpu es una utilidad parecida a pw(8) que puede usarse para administrar los usuarios en el
directorio LDAP. Puede ejecutarlo directamente, o utilizarlo en un script. Éste puede manejar ambos TLS (con la
opción -x) y SSL (directamente).
El port sysutils/ldapvi es una excelente herramienta para la edición de valores en el directorio LDAP con una
sintáxis del tipo LDIF. El directorio (o subsección del directorio) se presenta en el editor escogido por la variable de
entorno EDITOR. Esto facilita mucho realizar cambios a gran escala en el directorio sin tener que crear una solución
propia.
El port security/openssh-portable tiene la habilidad de conectarse a un servidor LDAP para verificar las
claves SSH. Esto es extremadamente útil si tiene muchos servidores y no quiere copiar sus claves públicas a todos
ellos.
12
Autenticación LDAP
Para crear una autoridad certificadora, sólo hace falta un certificado propiamente firmado y la clave. Los pasos para
crearlos son:
Éste será su certificado y clave root CA. Problemente querrá cifrar la clave y almacenarla en un lugar seguro.
Cualquiera con acceso a éstos puede enmascararse como uno de sus servidores LDAP.
A continuación, usando el primero de los dos pasos encima creamos una clave ldap-server-one.key y un pedido
de firmado de un certificado ldap-server-one.csr. Una vez que firme el pedido de firmado con root.key, será
capaz de usar ldap-server-one.* en sus servidores LDAP.
Nota: No olvide usar el nombre de dominio completamente calificado para el atributo “common name” cuando
se genera el pedido de firmado del certificado ya que si no hace así los clientes rechazarán la conexión y esto
puede ser bastante difícil de diagnosticar.
El fichero de salida será el certificado que puede usarse en sus servidores LDAP.
Finalmente, para que los clientes confíen en todos sus servidores, distribuya root.crt (el certificado, ¡no la clave!)
en cada cliente y especifíquelo en la directiva TLSCACertificateFile en ldap.conf.
13