Aprovechando un rato libre, es momento de continuar con la implementación de un servidor de nombres y autenticación basado en OpenLDAP y Kerberos.
En las entradas anteriores de esta serie, fuimos añadiendo servicios sobre la base de un servidor OpenLDAP y llegamos a un punto donde teníamos un servidor de nombres implementado mediante un servidor OpenLDAP, un servidor de autenticación implementado mediante Kerberos y un servidor DNS, usando PDNS. Configuramos Kerberos y el servidor DNS para que usaran OpenLDAP como backend, para lo cual creamos DNs específicos dedicados a cada servicio. Estos DNs permiten a cada servicio realizar consultas o modificaciones, en caso de ser necesario, de la información contenida en el servidor OpenLDAP.
Hoy veremos como integrar un servicio, en este caso PDNS, para que utilice tickets de Kerberos para poder realizar consultas al servidor OpenLDAP en vez de emplear un par DN/contraseña. El objetivo de esta integración consiste en aumentar la seguridad de la infraestructura, además de asegurar que no hay contraseñas de servicio, aunque sean encriptadas, en los ficheros de configuración de los servicios.
Para realizar esta integración es importante recordar, de forma resumida, el flujo de autenticación de Kerberos, teniendo en cuenta que las dos entidades implicadas en este caso son dos servicios que se ejecutarán en el mismo host o en dos hosts separados y por tanto, uno de los servicios actuará como cliente:
- El servicio cliente, en este caso PDNS, ha sido configurado para autenticarse mediante el uso de GSSAPI, con lo que envía la clave almacenada en su keytab al KDC (Key Distribution Center) solicitando un TGT (Ticket Granting Ticket).
- El KDC valida la clave enviada por el servicio remoto y genera el TGT correspondiente.
- El servicio PDNS recibe el TGT, lo que le permitirá solicitar tickets para acceder a otros servicios.
- Empleando el TGT, el cliente solicita al KDC un ticket de servicio para poder consultar el servidor OpenLDAP.
- El KDC recibe la solicitud y tras validarla, devuelve el ticket de servicio correspondiente al cliente.
- El servicio cliente consulta al servicio remoto empleando el ticket de servicio proporcionado por el KDC.
Este flujo de validación que acabamos de ver implica los siguientes puntos:
- En el dominio o reino Kerberos existente debemos crear los principales
necesarios para ambos servicios, tanto el del cliente como el del servidor.
- El servicio cliente debe disponer de la clave necesaria en un keytab accesible por el mismo.
- El servicio cliente debe configurarse para emplear GSSAPI.
- El servicio servidor debe estar configurado para permitir el acceso mediante Kerberos y disponer de un keytab.
- El servicio servidor debe configurarse para acepta GSSAPI como mecanismo de autenticación.
Para implementar todo esto, vayamos punto por punto y empecemos por saber que es un keytab. De forma simple, un keytab es un fichero que almacena claves de kerberos para uno o más principales. En concreto un fichero keytab almacenará la fecha de escritura de la entrada en el fichero, el nombre del principal, un número de versión de la clave que representa la entrada, un tipo de encriptación y la propia clave.
Conviene recordar que un principal o Service Principal Name (SPN) es una entrada en un reino Kerberos, tanto de usuarios como de servicios, con un formato como el siguiente:
Servicio/Nombre de Host@REINO Kerberos
Servicio/Nombre de Host.Dominio@REINO Kerberos
Nombre de Usuario@Reino Kerberos
Los dos primeros tipos suelen emplearse para representar servicios, mientras que el último se utiliza para representar usuarios. Por tanto, en nuestro caso, es necesario que creemos cuatro SPNs nuevos, dos para el servicio LDAP y otros dos para el servicio PDNS, a partir de los cuales podremos crear los keytabs correspondientes.
Teniendo en cuenta lo expuesto hasta aquí, creamos el principal correspondiente para cada servidor LDAP de nuestra infraestructura y los exportamos a un keytab:
Creación principal - Servidor ldap1 |
Creación principal - Servidor ldap2 |
Exportación keytab servidor ldap1. |
Exportación keytab servidor ldap2. |
Ahora realizamos el mismo proceso de creación de SPNs y exportación de los keytab correspondientes para el servicio PDNS, que actuará como cliente del servicio OpenLDAP. ¿Como hacemos esto? Pues como se ve a continuación:
Creación principal - Servidor PDNS1. |
Creación principal - Servidor PDNS2. |
Ahora, al igual que en el caso de los principales de OpenLDAP,
exportamos la clave del principal recién creado a un fichero para su uso por parte de PDNS. Esto debe hacerse desde el servidor master, ya que
al realizar la exportación se realiza un modificación en las entradas
correspondientes en OpenLDAP y por tanto es necesario que el KDC realice operaciones de escritura:
Exportación keytab servidor PDNS1. |
Exportación keytab servidor PDNS2. |
Una vez que tenemos listos los keytabs de todos los servicios, pasamos a realizar la configuración de los mismos para que se utilice Kerberos como mecanismo de autenticación entre ellos.
Para empezar de forma sencilla, comenzamos con el servicio PDNS. PDNS permite configurar el tipo de validación a utilizar con el backend LDAP con las siguientes opciones de configuración:
- ldap-bindmethod, permite especificar las opciones simple, el método básico con un DN y una password o gssapi, para el uso de Kerberos.
- ldap-krb5-keytab, especifica la ruta al fichero que contiene la clave que se usará para la validación.
- ldap-krb5-ccache, especifica la ruta completa al fichero que almacenará la cache de credenciales de Kerberos.
Por tanto, la configuración necesaria del servidor PDNS implica añadir las siguientes lineas al fichero /etc/pdns/pdns.conf:
Configuración de PDNS para usar Kerberos. |
Como es lógico, utilizaremos el keytab específico para cada servidor en cada caso y es muy importante tener en cuenta los permisos de acceso a dicho fichero si configuramos el servicio para que utilice un usuario diferente a root, que es lo más recomendable.
A continuación, configuramos OpenLDAP para que utilice el fichero keytab al arrancar, para lo cual es necesario cambiar el fichero de configuración correspondiente que dependerá de la distribución utilizada. En este caso tenemos lo siguiente para CentOS y Debian:
Configuración keytab OpenLDAP en CentOS |
Configuración keytab OpenLDAP en Debian. |
Al
reiniciar el servicio OpenLDAP este utilizará el keytab especificado.
Como es lógico, es muy importante que tenga los permisos correctos y el propietario del fichero sea el usuario que
ejecuta el servicio slapd.
Como se puede apreciar en la imagen anterior, todavía no hay ninguno disponible, así que tenemos que añadirlos, empezando por el plugin correspondiente de SASL para GSSAPI ya que todos los mecanismos de autenticación adicionales o externos, como Kerberos en este caso, emplean la biblioteca SASL y los plugins proporcionados por dicha biblioteca. Para instalar el plugin, por ejemplo en CentOS, solo es necesario hacer lo siguiente:
Instalación de plugin GSSAPI de SASL. |
Configuración SASL incluyendo mecanismos adicionales. |
Con esta configuración, y tras reiniciar el servidor OpenLDAP, podemos comprobar que se soportan todos los casos:
Búsqueda usando autenticación GSSAPI. |
Búsqueda usando autenticación SIMPLE y passthrough. |
Búsqueda usando autenticación SIMPLE y validación local. |
Como podemos apreciar en los ejemplos anteriores, hemos realizado una operación de consulta al servidor OpenLDAP con las siguientes características:
- En el primer caso, el usuario que realiza la operación debe obtener un ticket de Kerberos. Usando dicho ticket realiza la consulta al servidor OpenLDAP especificando como mecanismo de autenticación GSSAPI. Este proceso es el mismo que queremos configurar para PDNS.
- En el segundo ejemplo, un usuario realiza una consulta empleando el método de autenticación SIMPLE, es decir, presentando un par DN-contraseña. Como ese usuario tiene delegada la autenticación (atributo userPassword: operator1@LAB.INT), OpenLDAP delega la validación del mismo al proceso saslauthd.
- En el último caso, muy similar al anterior, comprobamos que la validación empleando em método de autenticación SIMPLE con un usuario cuya contraseña se encuentra en el propio servidor OpenLDAP, y que por tanto no se delega a ningún autenticador externo, también puede acceder correctamente al servidor OpenLDAP.
Error de caché de credenciales durante el arranque de PDNS. |
Este problema se debe, única y exclusivamente, a que el propietario del directorio de instalación de PDNS, que está en /etc, es el usuario root y no el propio usuario pdns. Por tanto, podemos cambiar el propietario de /etc para que sea del usuario pdns, pero es importante tener en cuenta que, quizás la actualización automática del paquete, pueda cambiar de nuevo dichos permisos. Con esta solución, la configuración de pdns quedaría del siguiente modo:
Configuración corregida de PDNS. Fichero /etc/pdns/pdns.conf. |
Es muy importante asegurar que, en el fichero de descripción del servicio, no esta incluida la opción ProtectSystem=full, ya que esta evita que el proceso escriba en /etc con lo que es necesario cambiarla a false en caso de estar presente. Esto puede incluir que, al para el servicio usando systemctl, dicho fichero de caché de credenciales no se elimine, lo cual provocará un fallo en el siguiente arranque del servicio, con lo que es necesario modificar la descripción del servicio para borrar dicho fichero. Como referencia, una posible solución a estos problemas sería similar a la siguiente:
Modificaciones de la descripción del servicio pdns. |
Con toda esta configuración, ya podemos arrancar el servicio pdns el cual, se valida usando Kerberos para poder realizar operaciones de lectura con el servidor OpenLDAP:
Servicio pdns arrancado. |
Hasta aquí esta entrada y en cuanto saque otro rato, seguiremos integrando servicios con Kerberos para poder asegurar más nuestras infraestructuras.