jueves, 1 de abril de 2021

Integración de OpenSSL con GnuTLS y el atributo olcTLSCipherSuite

Hoy una entrada rápida sobre OpenSSL y GnuTLS o, más concretamente, sobre los casos en los que, en una arquitectura, existen sistemas que emplean una u otra.

Ambas soluciones son bibliotecas que implementan los protocolos SSL y TLS que nos permiten, entre otras cosas, cifrar las comunicaciones entre sistemas. Es importante saber que hay distribuciones Linux que emplean OpenSSL, como CentOS, mientras que otras emplean GnuTLS, como es el caso de Debian. Por tanto, si en una arquitectura ya existente, es necesario integrar un nuevo servicio que empleará cifrado o si estamos bastionando la arquitectura por motivos de seguridad, es muy importante tener en cuenta las diferencias entre ambas bibliotecas.

La primera diferencia a tener en cuenta entre ambas bibliotecas es como se definen las cifras y protocolos, que luego podremos configurar en cualquier servicio empleando las opciones correspondientes. De forma simple, podemos consultar las cifras soportadas o disponibles en ambos casos del siguiente modo:

Consultando cifras disponibles en OpenSSL.

Consultndo cifras disponibles en GnuTLS.

Una de las primeras diferencias que podemos observar, es como se especifican las cifras en el caso de GnuTLS. Para poder ver la lista de cifras soportadas, así como protocolos y su versión, es necesario que especifiquemos una cadena de prioridad, las cuales son una manera simple y compacta de especificar un conjunto de cifras, protocolos, algortimos de intercambio de claves, etc. Las cadenas de pioridad disponibles, así como su significado, están disponibles aquí y quizás son la parte más importante para integrar correctamente un sistema que está trabjanado con OpenSSL con otro que emplea GnuTLS.

En concreto ¿cual es el problema al hacer este tipo de integraciones? Recordando el post en el que comenzábamos el bastionado de una arquitectura basada en OpenLDAP, desplegábamos unos certificados de servidor para cifrar las comunicaciones entre los diferentes elementos, principalmente para proteger el tráfico de replicación entre ambos servidores OpenLDAP.

Si generamos el certificado de servidor con OpenSSL, utilizando una configuración por defecto y luego fijamos que conjuntos de cifras queremos utilizar en cada extremo, en este caso en cada servidor OpenLDAP, nos encontraremos con problemas de compatibilidad derivados del hecho de que no todas las cifras o algoritmos estarán incluidas en cada implementación.

Recordando que un servidor OpenLDAP que replica información desde otro podemos verlo como un cliente LDAP, al establecer la conexión y solicitar la extensión StartTLS, realizará una comprobación del certificado proporcionado por el servidor y dicha conexión fallará en caso de encontrarse algún algoritmo o cifrado no soportado.

Podemos comprobar este problema de una manera muy sencilla utilizando el comando gnutls-cli, con las opciones necesarias para establecer una conexión StartTLS con un servidor remoto y especificando la cadena de prioridad que queremos utilizar en el lado cliente. Por ejemplo, desde el servidor OpenLDAP réplica, podemos conectar con el servidor OpenLDAP master y comenzar uan conexión StartTLS con un comando como el siguiente:

Conexión mediante gnutls-cli - SECURE128.

En este ejemplo, especificando como parámetros la ruta al fichero que contiene el certificado de la CA que ha firmado el certificado del servidor remoto, así como que queremos establecer una conexión TLS mediante protocolo LDAP, el certificado se valida y la conexión TLS se establece correctamente. El punto importante del comando es la cadena de prioridad que hemos especificado, en este caso la denominada SECURE128. La documentación de GnuTLS establece que al especificar SECURE128, se están empleando aquellas cifras consideradas seguras que ofrecen un nivel de seguridaad de 128 bits o superior y que se establece un perfil de comprobación de certificado bajo.

Si repetimos el comando pero pasamos a especificar una cadena de prioridad SECURE192, en la cual se están empleando cifras consideradas seguras que ofrecen un nivel de seguridaad de 192 bits o superior y que se establece un perfil de comprobación de certificado alto, veremos que sucede lo siguiente:

Conexión mediante gnutl-cli - SECURE192.

Por tanto, al incrementar el nivel de seguridad que deseamos usar, el certificado del servidor ya no es válido por usar un algoritmo inseguro, basado en la cadena de prioridad que hemos especificado en este caso.

Esta configuración es la que establecemos en el atributo olcTLSCipherSuite de OpenLDAP, el cual debe estar soportado por la biblioteca SSL usada para comnpilar el servidor OpenLDAP. Así, para un OpenLDAP que emplea OpenSSL, el valor de dicho atributo podría ser TLSv1.2, mientras que para un servidor OpenLDAP que emplea GnuTLS, el valor de dicho atributo debería ser una de las cadenas de prioridad soportadas, por ejemplo SECURE128.

Por tanto y en resumen, a la hora de tener que integrar sistemas que usen diferente biblioteca SSL, es muy importante analizar que algoritmos, cifras, protocolos de intercambio de claves, etc. están soportados en cada caso y cuales están incluidos si usamos las cadenas de prioridad de GnuTLS, pero, en la medida de lo posible, lo más sencillo es usar la misma distribución para evitar este tipo de problemas.