Servidor Kerberos en Debian
Contenido |
Resumen
Instalación, configuración y puesta en marcha de un servidor Kerberos con LDAP como almacén de datos en Debian Jessie
Introducción
Kerberos es un sistema de autenticación que podría considerarse para muchos como una panacea: Credenciales que nunca viajan por la red, SSO, cifrado por defecto... Active Directory, por ejemplo, no es más que una enorme y complicada implementación kerberos, e IPA anda por lo mismo. El éxito relativo de ambas reside en que solventan las dificultades que ambos presentan a la hora de configurar. Sí, definitivamente esto no es sencillo
Procedimiento
Configuración de LDAP para soporte de Kerberos
Instalación de paquetes
apt-get install slapd ldap-utils krb5-kdc-ldap
Aparecen un par de pantallas con unos cuadros de diálogo para la configuración:
Contraseña del administrador: <<introduzca una contraseña para el administrador del árbol ldap>>> Confirme la contraseña: <<introduzca una contraseña para el administrador del árbol ldap>>>
Tengo que sincerarme en este punto: Para la mayoría de instalaciones, toda la configuración inicial basta con lo ya hecho. Si se quiere hacer un par de configuraciones adicionales (Y que luego no podrá cambiar), como por ejemplo, el cambio de la base, podría usar:
dpkg-reconfigure slapd
Y en ese caso, iría contestando de la siguiente forma:
¿Desea omitir la configuración del servidor OpenLDAP?: No Introduzca el nombre de dominio DNS: sv Nombre de la organización: Ministerio de Salud de El Salvador Contraseña del administrador: <<introduzca una contraseña para el administrador del árbol ldap>>> Confirme la contraseña: <<introduzca una contraseña para el administrador del árbol ldap>>> Motor de base de datos a utilizar: MDB ¿Desea que se borre la base de datos cuando se purgue el paquete slapd?: No ¿Desea mover la base de datos antigua?: Sí ¿Desea permitir el protocolo LDAPv2?: No
Configuración de SSL/TLS
Existe una guía sobre como hacer esta configuración Configuración de SSL/TLS
Configuración Esquema
Agregamos el kerbe ldap con el esquema correspondiente
mkdir esquemas.d zcat /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz > kerberos.schema
Lo siguiente puede complicarse. Necesitamos un fichero donde señalemos los schemas disponibles actualmente en el servidor ldap. Estos pueden consultarse de la siguiente forma:
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config objectClass=olcSchemaConfig cn -LLL
A continuación, por ejemplo, considero los esquemas que vienen configurados por defecto para Debian; agregando el esquema para kerberos al final del siguiente fichero, esquemas.scheme
:
include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/inetorgperson.schema include kerberos.schema
Ahora corremos el comando para, precisamente, crear un ldif válido
slaptest -f esquemas.scheme -F esquemas.d/
Lo desplegamos
cp esquemas.d/cn\=config/cn\=schema/cn\=\{4\}kerberos.ldif /etc/ldap/slapd.d/cn\=config/cn\=schema/ chown -R openldap:openldap /etc/ldap/slapd.d/cn\=config/cn\=schema/ systemctl restart slapd.service
Configuración de Indíces y Permisos
Creamos un fichero modificaciones.ldif con las siguientes modificaciones a las ACL y los índices. NOTA: Este es un parte bastante experimental. Aunque creación de dos usuarios destinados a esta actividad particular es un avance, aún no estoy del todo seguro de estos permisos. Mirá, por exceso y por el momento, funcionan.
dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcAccess olcAccess: {0}to attrs=userPassword,userPKCS12,krbPrincipalKey by dn.exact="cn=kdc-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=adm-service,dc=salud,dc=gob,dc=sv" write by self write by * auth - add: olcAccess olcAccess: {1}to attrs=shadowLastChange by self write by * read - add: olcAccess # Providing access to realm container olcAccess: {2}to dn.subtree="cn=SALUD.GOB.SV,cn=krbcontainer,dc=salud,dc=gob,dc=sv" by dn.exact="cn=admin,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=kdc-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=adm-service,dc=salud,dc=gob,dc=sv" write by * none - add: olcAccess # Providing access to principals, if not underneath realm container olcAccess: {3}to dn.subtree="ou=Users,dc=salud,dc=gob,dc=sv" by dn.exact="cn=kdc-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=adm-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=admin,dc=salud,dc=gob,dc=sv" write by self write by * read - add: olcAccess # Providing access to principals, if not underneath realm container olcAccess: {4}to dn.subtree="dc=salud,dc=gob,dc=sv" by dn.exact="cn=kdc-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=adm-service,dc=salud,dc=gob,dc=sv" write by dn.exact="cn=admin,dc=salud,dc=gob,dc=sv" write by self write by * read - add: olcAccess olcAccess: {5}to * by * read dn: olcDatabase={1}mdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: krbPrincipalName eq,pres,sub
Lo aplicamos ejecutando el siguiente comando como root:
ldapmodify -Y EXTERNAL -H ldapi:/// -f modificaciones.ldif
Configuración de la estructura del árbol LDAP
NOTA: Este apartado no debe considerarse tanto experimental como necesario de personalización respecto a su implementación. Por consejo de las guías más oficiales al respecto, he considerado un contenedor especial para los Principal kerberos.
Nuestro dominio es salud.gob.sv
, por tanto, la base debería ser dc=salud,dc=gob,dc=sv
, pero como he configurado al servidor LDAP para que empiece en dc=sv, necesito de las dos primeras entradas en el siguiente archivo para crear la base necesaria. Fichero estructura.ldif
# mafi, sv dn: cn=mafi,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: mafi description: Usuario Lectura LDAP userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # gob.sv dn: dc=gob,dc=sv objectClass: top objectClass: dcObject objectClass: organization o: Ministerio de Salud dc: gob # mafi, gob.sv dn: cn=mafi,dc=gob,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: mafi description: Usuario Lectura LDAP userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # salud.gob.sv dn: dc=salud,dc=gob,dc=sv objectClass: top objectClass: dcObject objectClass: organization o: Oficinas Administrativas del Ministerio de Salud dc: salud # admin, salud.gob.sv dn: cn=admin,dc=salud,dc=gob,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: Administrador LDAP userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # mafi, salud.gob.sv dn: cn=mafi,dc=salud,dc=gob,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: mafi description: Lector privilegiado LDAP userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # adm-service, salud.gob.sv dn: cn=adm-service,dc=salud,dc=gob,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: adm-service description: Usuario para KADMIN userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # kdc-service, salud.gob.sv dn: cn=kdc-service,dc=salud,dc=gob,dc=sv objectClass: simpleSecurityObject objectClass: organizationalRole cn: kdc-service description: Usuario para KRB5KDC userPassword: {SSHA}sygQcjcZOF1GTb8YlyDKQtDZJNJT7uOu # Users, salud.gob.sv dn: ou=Users,dc=salud,dc=gob,dc=sv objectClass: organizationalUnit ou: Users # Groups, salud.gob.sv dn: ou=Groups,dc=salud,dc=gob,dc=sv objectClass: organizationalUnit ou: Groups # Computers, salud.gob.sv dn: ou=Computers,dc=salud,dc=gob,dc=sv objectClass: organizationalUnit ou: Computers
Podemos agregarlo de la siguiente forma:
ldapadd -x -D cn=admin,dc=sv -W -f estructura.ldif
Configuración de Kerberos
Instalación de paquetes
aptitude install krb5-admin-server krb5-kdc-ldap
Aparece una pantalla que avisa sobre la configuración de este paquete, aunque en realidad ya esta configurado.
Es normal que entre todos los mensaje de instalación, en Debian, hallemos algo como esto.
Job for krb5-kdc.service failed. See 'systemctl status krb5-kdc.service' and 'journalctl -xn' for details.
Configuración
Por exceso, la configuración en /etc/krb5.conf
es útil. Pero como le vamos a agregar nuestro dominio, aprovechamos y lo reducimos un poco:
[libdefaults] default_realm = SALUD.GOB.SV # The following krb5.conf variables are only for MIT Kerberos. krb4_config = /etc/krb.conf krb4_realms = /etc/krb.realms kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true [realms] SALUD.GOB.SV = { kdc = kerberos.salud.gob.sv admin_server = kerberos.salud.gob.sv } [domain_realm] .salud.gob.sv = SALUD.GOB.SV salud.gob.sv = SALUD.GOB.SV [login] krb4_convert = true krb4_get_tickets = false
Otra parte de la configuración reside en /etc/krb5kdc/kdc.conf
, la configuramos de la siguiente forma:
[kdcdefaults] kdc_ports = 750,88 [realms] SALUD.GOB.SV = { kdc = kerberos.salud.gob.sv admin_server = kerberos.salud.gob.sv default_domain = kerberos.salud.gob.sv database_module = salud_ldap_config acl_file = /etc/krb5kdc/kadm5.acl kdc_ports = 750,88 max_life = 10h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = des3-hmac-sha1 supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3 default_principal_flags = +preauth } [dbdefaults] ldap_kerberos_container_dn = cn=krbcontainer,dc=salud,dc=gob,dc=sv [dbmodules] salud_ldap_config = { db_library = kldap ldap_kdc_dn = cn=kdc-service,dc=salud,dc=gob,dc=sv ldap_kadmind_dn = cn=adm-service,dc=salud,dc=gob,dc=sv ldap_service_password_file = /etc/krb5kdc/salud.keyfile ldap_servers = ldap://kerberos.salud.gob.sv ldap_conns_per_server = 5 }
Ya que estamos en eso, creamos el fichero /etc/krb5kdc/kadm5.acl
, que se encarga de los permisos dentro del servidor kerberos
cat <<EOF >/etc/krb5kdc/kadm5.acl # This file Is the access control list for krb5 administration. # When this file is edited run /etc/init.d/krb5-admin-server restart to activate # One common way to set up Kerberos administration is to allow any principal # ending in /admin is given full administrative rights. # To enable this, uncomment the following line: */admin * EOF
NOTA: A partir de esta parte, entramos en grandes supuestos, lo más probable es que esto cambie en un futuro.
kdb5_ldap_util -D cn=admin,dc=salud,dc=gob,dc=sv create -subtrees dc=salud,dc=gob,dc=sv -r SALUD.GOB.SV -s -H ldaps:///kerberos.salud.gob.sv
Lo que aparece a continuación es uno de los mensajes más confusos que alguna vez haya visto. La clave a usar debe ser lo más complicada posible. Aunque es imperativo guardarla, en realidad hemos de usarla pocas veces.
Password for "cn=admin,dc=salud,dc=gob,dc=sv": Initializing database for realm 'SALUD.GOB.SV' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: Re-enter KDC database master key to verify:
Almacenamos las credenciales para kdc-service
mediante el siguiente comando.
kdb5_ldap_util -D cn=admin,dc=salud,dc=gob,dc=sv stashsrvpw -f /etc/krb5kdc/salud.keyfile cn=kdc-service,dc=salud,dc=gob,dc=sv
Y para adm-service
mediante el siguiente comando, y sí, estamos usando el mismo archivo.
kdb5_ldap_util -D cn=admin,dc=salud,dc=gob,dc=sv stashsrvpw -f /etc/krb5kdc/salud.keyfile cn=adm-service,dc=salud,dc=gob,dc=sv
E iniciamos los servicios correspondientes, que no lo estaban por falta de configuración:
systemctl start krb5-kdc.service systemctl start krb5-admin-server.service
Pruebas de la configuración
¿Pruebas exhaustivas?. Nada, bastará con que veamos el contenido del servidor kerberos en LDAP
ldapsearch -x -D cn=kdc-service,dc=salud,dc=gob,dc=sv -W -b cn=krbcontainer,dc=salud,dc=gob,dc=sv
En este punto, tienen que aparecer un par de entradas que se crearon al ejecutar kdb5_ldap_util
Primeros pasos en la administración
Crearemos un principal admin/admin, básicamente, un usuario de administración general.
kadmin.local Authenticating as principal root/admin@SALUD.GOB.SV with password. kadmin.local: add_principal admin/admin WARNING: no policy specified for admin/admin@SALUD.GOB.SV; defaulting to no policy Enter password for principal "admin/admin@SALUD.GOB.SV": Re-enter password for principal "admin/admin@SALUD.GOB.SV": Principal "admin/admin@SALUD.GOB.SV" created. kadmin.local:
Y ya. Por la longitud de este texto, continuaré en otra guía.