martes, 4 de agosto de 2020

Kubernetes - Notas adicionales sobre PODs y Services

En esta nueva entrada sobre Kubernetes profundizaremos un poco más en los detalles de la relación entre los PODs y los objetos de tipo service, que ya vimos en la anterior entrada de esta serie sobre Kubernetes.

Resumiendo lo visto hasta ahora, Kubernetes controla nuestra infraestructura de contenedores asegurándose que el estado del cluster coincide exactamente con el estado que definamos. Esto quiere decir que se asegurará de que existan los objetos en el cluster que hayamos establecido en nuestra configuración, arrancando y parando los contenedores que sean necesarios.

También hemos visto que un POD es la unidad mínima de ejecución en Kubernetes y que es la encapsulación de un contenedor, por ejemplo de Docker, que le permite al cluster de Kubernetes el control del mismo. Los PODs, por defecto, no son accesibles desde el exterior del cluster con lo cual, para publicar sus servicios, tendremos que crear un objeto de tipo service el cual "conectará" los PODs con el exterior, haciendo así accesibles los servicios a clientes externos.

Como vimos, esta conexión entre un objeto de tipo service y un POD se hace en función del campo selector del service y de las etiquetas del POD, campos que se definen dentro de la sección spec del objecto service y en el caso de los objetos POD, en la seción metadata de los mismos.

Sabemos que un objeto de Kubernetes se define con un fichero que sigue la siguiente estructura:

Spec de un objeto de Kubernetes.
Definición de un objeto de Kubernetes.

Por tanto, para definir un POD básico que ejecute la imagen oficial del servidor web Apache, podemos establecer la siguiente definición:

Definición POD simple
Definición POD simple.

Como sabemos, basta con aplicar este fichero de definición al cluster para arrancar un POD con estas características:

Ejecución de POD simple
Ejecución de POD simple.

Este POD, aunque controla un contenedor ejecutando una imagen de un servidor web que expone el puerto 80, no es accesible desde el exterior del cluster y sabemos que necesitamos un servicio para poder conectarlo o publicarlo al exterior.

La definición de este servicio será tan simple como la siguiente:

Definición de un servicio simple
Definición de un servicio simple.

Como podemos ver, he creado la definición de este servicio sin especificar el campo selector a pesar de lo cual podemos aplicarlo perfectamente al cluster:

Aplicación de la definición de servicio
Aplicación de la definición de servicio.

Comprobamos que efectivamente el servicio se ha creado en el cluster con el comando kubectl get all:

El objeto servicio aplicado al cluster
El objeto servicio aplicado al cluster.

Como es lógico y ya vimos, ahora mismo tenemos un POD que no es accesible y un servicio que no está redirigiendo conexiones a ningún POD de nuestro cluster, ya que no hay ningún selector definido en el mismo.

Podemos realizar esta comprobación usando el subcomando describe, el cual sabemos que nos proprociona mucha información, o bien podemos usar el comando get sobre objectos específicos y además indicar que nos muestre las etiquetas de los objetos. Así, por ejemplo, podemos mostrar solo los PODs existentes en el cluster con sus etiquetas usando el siguiente comando:

Mostrando las etiquetas de los PODs
Mostrando las etiquetas de los PODs.

Como podemos ver, la definición de este POD no contiene ninguna etiqueta. Para solucionar esto podemos modificar el fichero con la definición del POD, añadir las etiquetas necesarias y volver a aplicar la configuración al cluster o bien, podemos usar la opción --overwrite para modificar dicho campo. Esto último lo haríamos más o menos del siguiente modo:

Modificación de la etiqueta de un POD
Modificación de la etiqueta de un POD.

Como vemos, este cambio se realiza en caliente y es aditivo, es decir, podemos añadir tantas etiquetas como necesitemos al POD. Es importante tener en cuenta que, al hacer el cambio del campo label por comando, debemos cambiar el fichero de definición del POD si estas etiquetas son necesarias ya que el cambio no se aplica al fichero de definición del POD.

Para modificar nuestro servicio tendremos que editar el fichero, añadir el campo selector con la etiqueta necesaria y aplicar de nuevo la configuración al cluster.

Modificamos la definición del servicio y aplicamos al cluster
Modificamos la definición del servicio y aplicamos al cluster.

De este modo, al obtener la descripción del servicio podremos comprobar que en el campo endpoints aparece la IP del POD webserver y que este es accesible desde el exterior:

Servicio configurado y con endpoint disponible
Servicio configurado y con endpoint disponible.

Servicio web accesible
Servicio web accesible.

Hasta aquí hemos revisado y ampliado un poco lo que ya sabíamos y vimos en el post anterior pero, ¿que ventajas nos proporciona desacoplar el servicio del POD?

Supongamos que el equipo de desarrollo ha creado una versión 0 de la aplicación que debemos desplegar. Para esto han modificado la imagen oficial del servidor Apache, han incluido todos los cambios necesarios y han subido la imagen al repositorio interno de imágenes. Partiendo de este caso, podemos hacer un despliegue como el siguiente donde usamos la misma configuración que hemos establecido hasta ahora, es decir, identificamos el POD con la etiqueta application=webapp y establecemos el selector del service para seleccionar los PODs con dicha etiqueta. En este caso hariamos algo parecido a lo siguiente:

Creación del POD con version 0
Creación del POD con version 0.

En el caso de no disponer de un repositorio de imágenes, y estar usando el repositorio de imágenes de Docker local del propio host, debemos añadir la opción imagePullPolicy: Never en la definición del POD ya que por defecto Kubernetes siempre intentará descargar la imagen de Docker Hub.

Con esto podemos comprobar que el objeto service tiene un endpoint y que podemos acceder al servicio web:

Descripción del servicio webservice
Descripción del servicio webservice.

Acceso al servicio web V0
Acceso al servicio web V0.

Si ahora tenemos que desplegar una nueva versión del servicio web, supongamos que nos proporcionan la imagen de la versión 1 del mismo servicio web, podemos definir y aplicar al cluster el siguiente POD:

Definición del nuevo POD v1
Definición del nuevo POD v1.

Aplicamos la definición del POD v1
Aplicamos la definición del POD v1.
 
Con esto vemos que, en un mismo fichero, podemos incluir la definición de diferentes objetos. Al aplicar la definición al cluster, Kubernetes comprueba la configuración de todos los objetos ya existentes y aplica los cambios que puedan existir o indica que los objetos no han cambiado.

Al llegar a este punto, y teniendo en cuenta cual es el selector del servicio webservice, ¿cual es el resultado obtenido? Como ambos PODs tienen la misma etiqueta y el selector del servicio redirige el tráfico a cualquier pod con la etiqueta application=webapp estaríamos sirviendo ambas versiones del servicio web simultaneamente. Esto podemos verlo al hacer la descripción del servicio y comprobar que hay dos endpoints, uno correspondiente a cada POD. Además, al acceder al servicio accederíamos a ambas versiones:

Servicio con endpoints en PODs v0 y v1
Servicio con endpoints en PODs v0 y v1.

Acceso al servicio web v1
Acceso al servicio web v1.

Como es lógico esta situación no es la que queremos, ya que serviríamos ambas versiones simultaneamente a los clientes. Por tanto, para evitar esto, es necesario que definamos correctamente las labels de nuestros PODs y especifiquemos correctamente el selector del objeto service. Para corregirlo haríamos algo como lo siguiente:

Añadimos etiquetas a cada POD con la versión
Añadimos etiquetas a cada POD con la versión.

Modificacióon del selector del objeto service
Modificacióon del selector del objeto service.

Con esta modificación, y como el campo selector de un objeto service hace un and de todas las etiquetas que especifiquemos, ahora solamente hay un endpoint disponible para el servicio y por tanto solo servimos el servicio web correcto.

Servicio web con el endpoint correcto
Servicio web con el endpoint correcto.

En resumen, está claro que desacoplar el servicio del POD nos proporciona mucha flexibilidad a la hora de hacer despliegues de servicios.

Como veremos más adelante, lo habitual no es trabajar directamente con PODs y services de este modo, pero es importante entender como funcionan y se relacionan entre ellos. Esto nos permitirá comprender objetos más complejos, que se basan en estos y que veremos que proporcionan muchas características y funcionalidades adicionales.

sábado, 18 de julio de 2020

OpenLDAP - Integración de Kerberos 5 con un backend LDAP

Vamos con otra entrada rápida sobre OpenLDAP y más concretamente, cómo podemos integrar Kerberos para usar un servidor OpenLDAP como backend.

Y ¿en que consiste exactamente esto? Como ya sabemos, Kerberos es un protocolo de autenticación de red basado en el intercambio de tickets para la validación de usuarios y servicios. Como cualquier servicio de autenticación, Kerberos necesita una base de datos para almacenar su información así que, lo que veremos en este artículo es como podemos configurarlo para que esa base de datos sea un servidor OpenLDAP. Para más información sobre Kerberos os recomiendo consultar la web del MIT donde podréis encontrar información detallada al respecto.

Como es lógico, partimos de un servidor donde tendremos instalado OpenLDAP y donde instalaremos los paquetes necesarios para poder crear nuestro servidor Kerberos, incluyendo el que permite usar un LDAP como backend. En el caso de un sistema CentOS 7.8, estos paquetes son:

Paquetes necesarios para un servidor Kerberos5.
A continuación necesitamos extender el schema del servidor OpenLDAP para añadir los atributos y clases de objeto necesarios para Kerberos. Esta extensión de schema, para la carga dinámica en OpenLDAP, es un fichero proporcionado con el código fuente de Kerberos distribuido por el MIT. Por tanto necesitamos descargarnos las fuentes de Kerberos de al menos la versión 1.18.1, la cual incluye un fichero de schema específico para OpenLDAP. Sin embargo, si utilizas un servidor LDAP diferente como 389 Directory Server, el paquete krb5-server-ldap incluye los ficheros de schema compatibles con dicho servidor de directorio:

Ficheros de schema incluidos en el paquete krb5-server-ldap.
Para extender el schema solo tenemos que realizar una operación add con un usuario con permisos en la rama config de OpenLDAP. Para esto usaríamos un comando como el siguiente:

Extensión del schema de OpenLDAP.
Los siguientes pasos consisten en realizar toda la configuración necesaria para establecer un reino Kerberos, especificando que vamos a utilizar como backend un servicio LDAP.

De forma muy resumida, un servidor Kerberos se basa en dos servicios diferentes, el Key Distribution Center (KDC), encargado de validar a los usuarios y hosts y proporcionarles los tickets o claves correspondientes para acceder a los diferentes servicios y el servidor de administración de Kerberos (kadmind), encargado de realizar operaciones de administración sobre la base de datos de Kerberos.

La integración de Kerberos con un backend LDAP implica la creación de un objeto contenedor en el árbol del servidor de directorio, el cual contendrá toda la información del reino Kerberos. Para controlar el acceso a dicho contenedor, es necesario definir un DN específico que será el único con permisos sobre el mismo y crear dicho DN en nuestro árbol de directorio. Este DN debemos especificarlo en el fichero de configuración del KDC y crearlo manualmente antes de continuar, con lo que tendríamos algo parecido a lo siguiente:

Creación del DN necesario para la administración del contenedor Kerberos.
Esta cuenta o DN, puede ser de cualquier clase de objeto que contenga un campo password. Es importante que guardemos bien esta contraseña porque la necesitaremos en un paso posterior.

Una vez creada esta entrada en el servidor LDAP, podemos crear los ficheros de configuración necesarios para Kerberos. En concreto es necesario que modifiquemos los ficheros:
  • /etc/krb5.conf, que contiene la confiiguración del cliente Kerberos 5 del servidor.
  • /var/kerberos/krb5kdc/kdc.conf, que contiene la configurción del servicio KDC del servidor.
El contenido básico del fichero /etc/krb5.conf es similar al siguiente:

Fichero /etc/krb5.conf.
Uno de los cambios importantes a realizar en este fichero son las líneas dns_lookup_realm y dns_lookup_kdc que, en un entorno productivo donde tengamos un servicio DNS, deberían ser iguales a true, lo cual implicaría la creación de determinados RRs en el servicio DNS.

Respecto al fichero de configuración /var/kerberos/krb5kdc/kdc.conf, el contenido básico, puede ser algo parecido a lo siguiente:

Fichero /var/kerberos/krb5kdc/kdc.conf.
En este fichero podemos ver la especificación del DN que hemos creado anteriormente, así como la especificación del servidor o servidores que emplearemos como backend para nuestro servidor Kerberos. También es importante destacar la línea de configuración ldap_kerberos_container_dn que especifica el DN que se creará para almacenar la información del reino Kerberos. El nombre de dicho DN esté especificado con un atributo commonName (cn) debido a que la clase de objeto que se creará en el momento de creación del reino Kerberos, requiere un atributo commonName.
Otro punto importante, para evitar problemas, si especificamos en dicho fichero alguna ruta que no existe, es importante crearla manualente antes de continuar.

Con esta configuración ya establecida, el siguiente paso consistirá en crear el fichero con la password de servicio, definido por la opción ldap_service_password_file. Este fichero contendrá la password que emplearán los servicios KDC y kadmin, para conectarse al servidior LDAP. Por tanto, esta password debe coincidir con la que hemos especificado antes al crear el DN que accederá al contenedor del reino Kerberos en LDAP. El comando que empleamos es el siguiente:

Creación del fichero con la password de servicio.
Ahora crearemos el reino Kerberos, así como el fichero stash con la password maestra de la base de datos con lo que es importante tener en cuenta los siguientes puntos:
  • Al usar LDAP como backend, el comando a utilizar para la creación del reino es kdb5_ldap_util.
  • Debemos decidir si queremos que los principales se creen en un subtree diferente al del contenedor del reino Kerberos. Este punto podemos establecerlo con la opción -subtrees, donde especificaremos el DN donde queremos almacenar los principales del reino Kerberos.
  • Debemos especificar el servidor LDAP así como un DN con permisos de escritura en el árbol de directorio.
  • Al crear el fichero stash especificaremos una password que no tiene porque ser igual que la password de servicio LDAP especificada anteriormeente.
De forma muy simple, podemos crear el reino usando un comando como el siguiente:

Creación del reino Kerberos.
Con este comando creamos el contenedor Kerberos en el árbol del servidor OpenLDAP y, al no usar la opción -subtrees, los principales se crearán en el contenedor correspondiente al reino Kerberos.
Si comprobamos el árbol de directorio, podremos ver que ahora aparece una nueva entrada que contiene la información básica de nuestro reino Kerberos:

Contenedor Kerberos creado en el árbol del servidor LDAP.
Para asegurar que solamente los DNs establecidos en la configuración del KDC, especificados con las opciones ldap_kdc_dn y ldap_kadmind_dn, pueden acceder al contenedor del reino Kerberos y evitar accesos no permitidos, creamos unas ACLs básicas. Estas ACLs podemos crearlas usando un editor LDAP en la rama cn=config, correspondiente a la base de datos que contenga el contenedor de Kerberos, del servidor OpenLDAP. Unas ACLs básicas serían las siguientes:

ACLs básicas para el control de acceso.
Además es recomendable añadir un índice de tipo igualdad (eq) para el atributo krbPrincipalName, lo cual acelarará las búsquedas en el servidor. Para añadir el atributo solo tenemos que modficar la configuración de la base de datos correspondiente del siguiente modo:

Añadiendo un índice eq para el atributo krbPrincipalName.
Con esta configuración establecida, podemos arrancar los servicios krb5kdc y kadmind:

Arranque de los servicios KDC y kadmind.
Una vez arrancados los servicios, podemos comprobar que todo funciona correctamente creando un principal y comprobando que este aparece en el contenedor del reino Kerberos. Podemos crear un principal de forma simple usando el comando kadmin.local:

Creación de nuevos principales.
Y como podemos comprobar, este nuevo principal aparece en el contenedor del reino Kerberos:

Nuevo principal en contenedor Kerberos del reino LAB.INT.
De este modo comprobamos que la integración entre el servicio Kerberos y el servidor OpenLDAP es correcta. Si borramos el principal reciend creado con el comando kadmin.local, el cual solo debe lanzarse desde el servidor que contenga el kdc, tendríamos lo siguiente:

Borrado de un principal.
Principal eliminado en OpenLDAP.
Por tanto, hemos integrado Kerberos con OpenLDAP para usar este último como backend o base de datos de un servicio Kerberos. La principal ventaja que conseguimos al hacer esto es que ahora podemos instalar más servidores OpenLDAP y Kerberos y, utilizando las características de replicación proporcionadas por OpenLDAP, tener un servicio de nombres y autenticación distribuido y tolerante a fallos.

Por último, si queremos asegurarnos que el servicio Kerberos arranca correctamente, es necesario que incluyamos una dependencia en los servicios krb5kdc y kadmin con el servicio slapd del siguiente modo:

Incluyendo dependencia con slapd.

En próximas entradas veremos como configurar esta replicación entre varios servidores OpenLDAP y como podemos configurar SASL en OpenLDAP para emplear el mecanismo de autenticación GSSAPI para la validación de usuarios y servicios. 

sábado, 30 de mayo de 2020

OpenLDAP - Autenticación passthrough usando SASL

Hoy vamos con una entrada rápida sobre OpenLDAP en la cual vamos a revisar como podemos configurar la autenticación passthrough de OpenLDAP.

Y ¿que es exactamente la autenticación passthrough? De forma muy resumida es la capacidad de la que dispone OpenLDAP para, utilizando la biblioteca SASL, delegar el proceso de autenticación a un servicio de autenticación externo.

Este tipo de configuración puede ser útil en determinados casos, como por ejemplo, si la organización de nuestro servidor de directorio divide las entradas de usuarios por secciones o unidades organizativas y cada una de ellas debe usar diferentes tipos de servicios de autenticación o para validar usuarios desde aplicaciones web.

Esta característica de delegación del proceso de autenticación se basa en el uso del servicio saslauthd. Este servicio puede configurarse para recibir peticiones de autenticación de otros procesos que soporten SASL, realizando la autenticación al servicio externo que hayamos configurado y devolviendo el resultado del proceso de autenticación.

Partiendo de un sistema donde ya se encuentra instalado un servidor OpenLDAP, el cual debe tener compilado el soporte de la biblioteca SASL, usaremos un servicio Kerberos 5 para validar a los usuarios mediante saslauthd. En el caso de CentOS 7.8.2003, se incluye OpenLDAP versión 2.4.44 con soporte SASL.

Por tanto, a partir del sistema anterior y de forma muy resumida, el proceso se basa los siguientes pasos:
  1. Primero necesitamos instalar el servicio saslauthd con las bibliotecas necesarias. Es importante tener en cuenta que vamos a instalar el paquete básico de la biblioteca SASL sin ningún mecanismo de autenticación adicional. Por tanto solo tenemos que buscar el paquete que proporciona el servicio saslauthd:
  2. Servicio saslauthd.

  3. Como queremos usar Kerberos 5 como servicio de autenticación, tenemos que instalar los paquetes que proporcionan los servidores de Kerberos. Es recomendable instalar también los paquetes que incluyan las herramientas como kinit para poder hacer pruebas y administrar correctamente el servicio:
  4. Instalación de Kerberos 5.
  5. Una vez instalado Kerberos 5 es necesario crear lo que, en terminología de Kerberos, se denomina un reino de autenticación. De forma muy resumida podemos entender un reino de autenticación de Kerberos como el dominio sobre el cual un servidor de Kerberos tiene la autoridad para autenticar a un usuario, host o servicio. De momento, y para resumir, la forma más rápida de crear un reino Kerberos es mediante la configuración del fichero /var/kerberos/krb5kdc/kdc.conf que contiene la configuración del servidor kdc que implementa y proprociona el servicio Kerberos. Una configuración básica es más o menos la siguiente:
  6. Configuración básica servidor kdc.
  7. Una vez realizada la configuración del servidor kdc, ya podemos inicializar el reino Kerberos. Este proceso crea la base de datos de Kerberos y el denominado fichero stash. El fichero stash contiene la contraseña maestra usada para encriptar la base de datos de Kerberos. Sin este fichero, el proceso krb5kdc del servidor no será capaz de arrancar de forma automática solicitando la password maestra en el arranque, con lo que es muy importante que creemos dicho fichero. Para inicializar el reino y crear el fichero solo necesitamos ejecutar un comando como el siguiente:
  8. Inicialización del reino Kerberos LAB.INT.
  9. En este punto ya está inicializado el reino Kerberos pero no hay ningún usuario o cuenta creada en la base de datos. Cada una de las entradas de una base de datos de Kerberos se denomina principal, independientemente de si corresponde a un usuario, host o servicio. Por tanto el primer paso consiste en crear el principal del administrador, que tendrá permisos sobre todos los principales del reino Kerberos. Para esto solo necesitamos hacer algo como lo siguiente:
  10. Creación del principal administrador.
  11. Para restringir el acceso a los ficheros de base de datos de Kerberos al principal del administrador, es necesario que establezcamos una ACL que incluya únicamente a dicho principal. Es importante señalar que un servidor Kerberos está constituido por dos servicios diferentes, el krb5kdc que implementa el servicio Kerberos y el servicio kadmind para las tareas de administración de la base de datos. Por tanto necesitamos establecer una ACL para el servidor kadmind que restrinja las operaciones sobre la base de datos del reino que hemos creado para el principal que hemos denominado como administrador. Para esto solo es necesario que editemos el fichero /var/kerberos/krb5kdc/kadm5.acl del siguiente modo:  
  12. ACL para el administrador.
Ya tenemos la configuración básica necesaria para crear un reino Kerberos. Ahora, para poder realizar pruebas, creamos unos cuantos principales que mapearemos a un objeto de usuario que luego crearemos en el servidor OpenLDAP. Para crear principales solo es necesario que ejecutemos un comando como el que utilizamos para crear el principal con el rol adminsitrador:
Creación de principales de usuarios.
Llegado este punto tenemos un servidor OpenLDAP recién instalado y un reino Kerberos creado, cuyos servicios podemos arrancar si no lo hemos hecho antes. Suponiendo que nuestra idea es crear un servidor de nombres para sistemas Unix/Linux basado en LDAP, usando como servicio de autenticación Kerberos 5, es necesario que extendamos el schema del servidor OpenLDAP. Esta extensión del schema es necesaria para incluir los atributos y clases de objeto necesarios para el uso de un LDAP como servicio de nombres según la RFC 2307. Esta RFC establece como debe ser la estructura, atributos y clases de objeto para poder usar un servidor LDAP como servicio de nombres.

Con la distribucion de OpenLDAP se incluyen varios schemas adicionales que se pueden cargar si es necesario con solo usar el comando ldapadd. En el caso del paquete OpenLDAP incluido con CentOS 7, estos ficheros de schema están en la ruta /etc/openldap/schema:

Schemas incluidos con OpenLDAP.
De esta manera podremos extender el schema básico del servidor OpenLDAP en caso de ser necesario con alguno de los incluidos en caso de ser necesario.

Un punto importante a tener en cuenta a la hora de extender el schema de cualquier servidor de directorio es que, en general, pueden existir dependencias entre diferentes schemas. Esto se debe a que un schema puede requerir un atributo que está definido por otro schema y, por tanto, será necesario cargar ambos schemas siguiendo el orden de dependencia entre ellos.

Teniendo en cuenta lo anterior, los siguientes pasos serían:
  1. Extendemos el schema de OpenLDAP añadiendo el schema nis, que es el que cumple con la RFC 2307. Este schema depende de los schemas core y cosine, con lo que ambos deben ser añadidos previamente. Para extender el schema solo es necesario usar un comando como el siguiente:
  2. Extensión del schema de OpenLDAP.
  3. A continuación creamos cuentas de usuario y de grupo en el servidor OpenLDAP para poder usarlo como servicio de nombres. Para esto podemos usar cualquier editor LDAP o mediante el comando ldapadd y ficheros ldif. En definitiva, lo que es necesario hacer es crear objetos de los tipos posixAccount para las cuentas de usuario y posixGroup para las de grupo. Una vez creados, tendríamos algo como lo siguiente:
  4. Cuentas de usuario y de grupo en el servidor OpenLDAP.
  5.  A continuación configuramos los sistemas Unix/Linux de la infraestructura para que utilicen el servidor OpenLDAP como servicio de nombres y el servidor Kerberos 5 como servicio de autenticación. Este paso dependerá de la distribución Linux que estemos utilizando. En el caso de distribuciones basadas en Red Hat, como CentOS, es muy recomendable utilizar authconfig-tui. En resumen será necesario configurar el cliente LDAP así como el cliente Kerberos 5 del sistema operativo cliente. Una configuración muy básica, y muy mejorable, para ambos servicios es la siguiente:
Configuración básica cliente Kerberos 5.

Configuración básica cliente LDAP.
Con esta configuración podemos comprobar que el sistema está correctamente configurado con solo realizar búquedas de información de usuarios y grupos así como validaciones mediante el comando kinit:

Pruebas de validación de principales Kerberos.
Comprobación del servicio de nombres.
Por tanto, en este punto, el servicio de nombres y autenticación funciona correctamente y los sistemas desplegados pueden utilizarlo como servicio centralizado de nombres y autenticación.

A continuación nos falta configurar saslauthd y OpenLDAP para poder delegar la validación de usuarios al servicio Kerberos 5 mediante la característica de passthrough de la que he hablado al principio del artículo.

Para este caso, la configuración de saslauthd utilizará como mecanismo de validación de contraseñas el sistema PAM del propio servidor. Para establecer esta configuración solo tenemos que modificar el fichero de configuración /etc/sysconfig/saslauthd como se muestra en la siguiente imagen:

Configuración saslauthd.
Ahora es necesario establecer la configuración de OpenLDAP necesaria para que emplee SASL y más concretamente saslauthd, para realizar el passthrough del proceso de autenticación. Este proceso de configuración de OpenLDAP se resume en los siguientes pasos:
  1. Creamos el fichero /etc/sasl2/slapd.conf que le indicará al servicio slapd de OpenLDAP que debe usar saslauthd para validar contraseñas:
  2. Configuración fichero /etc/sasl2/slapd.conf.
  3. Ahora es necesario modificar la configuración del propio servidor OpenLDAP para añadir una serie de atributos de configuración relacionados con SASL. Estos atributos establecen que host va a realizar el procesado SASL siendo en este caso el propio servidor, así como cual es el reino SASL por defecto y las características de seguridad. Utilizando la configuracióon dinámica de OpenLDAP, quedaría del siguiente modo:
  4. Configuración SASL de OpenLDAP.
  5. El último paso de configuración necesario en OpenLDAP debe realizarse en todas aquellas entradas que representen las cuentas de usuario cuya autenticación queramos delegar a saslauthd. Este punto se basa en establecer el atributo userPassword de cada entrada de usuario usando una cadena como {SASL}principal@REINO lo cual indica a OpenLDAP que, al recibir una petición de validación que incluya el DN correspondiente a dicha entrada de usuario, esta debe delegarse al host SASL configurado en el paso anterior. Esta validación se realizará mediante el uso de saslauthd el cual, al haberlo configurado para usar el mecanismo PAM del servidor, realizará la autenticación contra el servicio Kerberos 5. Una entrada de usuario quedaría, por tanto, del siguiente modo:
Cuenta de usuario.
Hagamos una prueba de validación del usuario operator1 mediante la ejecución de un comando ldapsearch:

Búsqueda en OpenLDAP.
Como vemos la autenticación ha fallado y, si revisamos los logs del sistema encontraremos que se debe a que, al intentar validar al usuario mediante PAM, saslauthd intenta usar el módulo PAM para el servicio ldap el cual no existe por defecto:

Error de validación saslauthd.
Una forma rápida de solucionarlo, pero no la mejor ni la más adecuada, es hacer un enlace simbólico en el servidor para crear el fichero del servicio ldap usando la configuración de autenticación general del sistema. En caso de un sistema CentOS, algo tan sencillo como lo siguiente:

Creación entrada servicio ldap para PAM.
Al hacer esto, si volvemos a realizar la búsqueda ahora el resultado será satisfactorio y podremos comprobar en el log del servidor kdc como llega la petición de autenticación del usuario:

Búsqueda realziada correctamente.
Petición de validación del usuario.
En resumen, podemos configurar un servidor OpenLDAP para delegar la autenticación de todas o de ciertas entradas que representen usuarios, utilizando así el mecanismo de autenticación del propio servidor OpenLDAP para determinados usuarios y mecanismos externos, como Kerberos 5, en el caso de otros.

Como puntos importantes a revisar para futuras entradas, es el funcionamiento de PAM y como crear una entrada correcta para el servicio LDAP que utiliza saslauthd en una configuración como esta así como establecer una configuración más segura del cliente LDAP del sistema operativo cliente.