Continuamos con la serie de artículos sobre la seguridad en Apache Kafka. En el artículo anterior se asentaron las bases sobre la importancia de implementar distintas políticas de seguridad sobre Apache Kafka para la creación de un entorno seguro y confiable que nos permita realizar las operaciones de integración y procesamiento de datos en tiempo real.

Además, profundizamos de forma particular en las políticas de encriptación, donde pudimos ver la manera de implementar dichas políticas para garantizar la seguridad y la confidencialidad en las comunicaciones.

En esta ocasión, vamos a sumergirnos todavía más en el mundo de la seguridad de Apache Kafka, centrándonos en el estudio de las políticas de autenticación, las cuales nos van a ayudar a seguir construyendo un sistema de confianza en Apache Kafka.

¿Cómo implementar una política de autenticación en Apache Kafka?

Anteriormente, ya introducimos brevemente la importancia de implementar una política de autenticación en nuestro clúster de Apache Kafka para evitar que cualquier cliente no autorizado pueda acceder a él y realizar operaciones que puedan tener un impacto negativo en nuestro sistema.

Una política de este tipo no es ni más ni menos que un conjunto de reglas y configuraciones que determinan cómo los distintos clientes y brokers de Apache Kafka pueden autenticarse entre sí. En otras palabras, la política de autenticación establece quiénes pueden acceder al clúster de Apache Kafka y bajo qué condiciones.

kafka clients

Esta política desempeña un papel fundamental para garantizar la seguridad de nuestra plataforma y tiene la suficiente flexibilidad para poder ser personalizada según las necesidades de seguridad específicas de cada organización, ya que se puede configurar utilizando diferentes mecanismos de autenticación, como pueden ser SSL/TLS, SASL (Simple Authentication and Security Layer), etc.

A continuación, vamos a ver las principales maneras de implementar las políticas de autenticación dentro de nuestro entorno de Apache Kafka.

Autenticación con TLS

Si recordamos el artículo anterior, se muestra el funcionamiento del protocolo TLS y cómo este nos ayuda a implementar una política de encriptación en Apache Kafka para realizar comunicaciones cifradas entre brokers y clientes, donde el cliente verifica la identidad del broker a través de una autoridad certificadora de confianza (CA) antes de entablar la comunicación. En este punto, el cliente es “anónimo” para el broker.

Apache kafka clients y broker

Como ya adelantamos en dicho artículo, el uso del protocolo TLS no solo es apto para implementar una política de encriptación, ya que también se puede otorgar de identidad al cliente y ofrecer la posibilidad de realizar una autenticación mutua (Two-Way Authentication) entre clientes y brokers para implementar una política de autenticación.

Two-Way Authentication

Ahora bien, ¿cómo hacemos esto?

La configuración necesaria para poder implementar una política de autenticación usando el protocolo TLS no implica cambios significativos en la estructura que hemos visto a la hora de implementar la política de encriptación, ya que tanto los brokers como los clientes continúan coexistiendo y la CA continúa validando la identidad de las entidades necesarias.

Eso sí, para poder llevarla a cabo es necesario añadir una serie de configuraciones adicionales.

Si partimos de la configuración realizada para la política de encriptación que acabamos de ver, dotar de la identidad requerida al cliente se realiza de forma análoga a la de los brokers.

Dotar identidad al cliente

En primer lugar, se tiene que generar el par de claves y el certificado asociado al cliente, por lo que usaremos un comando familiar (si hemos visto el artículo anterior): keytool.

keytool -genkey -keystore kafka.client.keystore.jks -validity 365 -storepass -keypass -dname “CN=kafka-client” -storetype pkcs12 -keyalg RSA

Este comando genera un nuevo par de claves RSA y un certificado asociado al cliente que se guardan en un almacén de claves (KeyStore) con el nombre kafka.client.keystore.jks

Certificado asociado al cliente

Una vez generados el par de claves y el certificado, el siguiente paso es el de firmar dicho certificado a través de nuestra CA. Para ello, volvemos a hacer uso de la herramienta keytool para generar una solicitud de firma de certificado (Certificate Signing Request, CSR).

keytool -keystore kafka.client.keystore.jks -certreq -file client-cert-file -storepass -keypass

El comando genera un archivo de CSR, client-cert-file, con la información necesaria para solicitar la emisión de un certificado digital de confianza. Por ello, el siguiente paso consiste en enviar dicha CSR a nuestra CA confiable para que la firme y proporcione el certificado digital para que el cliente sea reconocido y aceptado por las entidades que confíen en dicha CA.

openssl x509 -req -CA ca-cert -CAkey ca-key -in client-cert-file -out client-cert-signed -days 365 -CAcreateserial -passin pass:

Este comando emite un nuevo certificado digital usando la CSR, el certificado y la clave privada de la CA. El certificado resultante, que es el certificado firmado, se guarda en el archivo client-cert-signed.

Nuevo certificado digital, CSR

Hay que tener en cuenta que en el mundo real, tanto el envío de la CSR como la recepción del certificado firmado se tiene que realizar garantizando su seguridad para que no sean usados por personas no autorizadas.

Una vez hecho esto, hay que importar los certificados generados a nuestro almacén de claves para su posterior uso a la hora de realizar la autenticación.

keytool -keystore kafka.client.keystore.jks -alias CARoot -import -file ca-cert -storepass -keypass -noprompt

keytool -keystore kafka.client.keystore.jks -import -file client-cert-signed -storepass -keypass -noprompt

Como vimos, cuando se importaron los certificados en el almacén de claves del broker, quedarían dos entradas correspondientes a los certificados importados, ya que la anterior entrada referente al cliente se sustituye por el certificado firmado al poseer la misma clave.

Certificado firmado

De esta manera tan sencilla hemos podido dotar de una identidad a nuestro cliente de Apache Kafka.

Para finalizar con la creación de la política de autenticación, simplemente debemos modificar la configuración tanto del broker como del cliente para que acepten la autenticación TLS.

En el caso del broker hay que añadir la configuración adicional necesaria a la ya existente respecto al fichero de configuración server.properties definido en la política de encriptación.

ssl.client.auth=required

En el caso de la configuración del cliente se tiene que añadir la configuración adicional sobre el fichero client.properties, creado en la etapa de encriptación, relacionada con el almacén de claves.

ssl.keystore.location=<path>/kafka.client.keystore.jks
ssl.keystore.password=<password>
ssl.key.password=<password>

Una vez hecho esto, simplemente reiniciando el broker y ejecutando el cliente parametrizado con el fichero de propiedades, ya se tendría la política de autenticación con TLS implementada.

Política de autenticación TLS implementad

Esta forma de autenticación es muy común en soluciones de Apache Kafka gestionadas, como Confluent Cloud y otros servicios similares.

Hay que tener en cuenta que ahora que el cliente tiene una identidad propia, vamos a ser capaces de aplicar ACLs. Esto resulta un aspecto muy importante no solo para las políticas de autenticación, sino también para implementar políticas de autorización que veremos en un futuro.

Autenticación SASL

En esta ocasión, vamos a ver otra manera muy interesante para implementar nuestra política de autenticación dentro del entorno Apache Kafka. El protocolo SASL (Simple Authentication and Security Layer) es un protocolo de autenticación genérico que proporciona un marco flexible para la autenticación de clientes en diversos sistemas y servicios.

SASL se ha convertido en un estándar importante en aplicaciones que requieren seguridad en la autenticación, ya que ofrece una solución robusta que no interfiere con el protocolo de la aplicación subyacente.

Es este aspecto de no interferencia lo que hace que SASL sea especialmente atractivo para aplicaciones como Hadoop y Apache Kafka, donde se utilizan protocolos específicos para el procesamiento de datos y la mensajería.

En nuestro contexto, el protocolo SASL ofrece una gran flexibilidad en su configuración, ya que admite varios mecanismos (o protocolos) de autenticación que permiten adaptarse lo mejor posible a las necesidades de seguridad específicas de cada organización.

Protocolo PLAIN

Este mecanismo de autenticación utiliza un nombre de usuario y una contraseña para la autenticación. Es uno de los mecanismos más simples y se utiliza a menudo en pruebas y desarrollos locales.

Sin embargo, no es el mecanismo más seguro, ya que las credenciales se envían en texto claro si no se utiliza en conjunción con TLS… ¿os suena de algo?

Para configurar la política de autenticación SASL_PLAIN, hay que realizar una serie de configuraciones. En primer lugar, se tiene que habilitar la autenticación de dicho protocolo en el broker a través de su fichero de configuración server.properties.

listeners=SASL_PLAINTEXT://:9092
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=PLAIN
sasl.enabled.mechanisms=PLAIN

Por otro lado, hay que definir las credenciales de los usuarios permitidos. En este caso, se puede usar un archivo de propiedades, una base de datos o cualquier otro medio compatible. A modo de ejemplo, se agrega la configuración en el mismo fichero haciendo uso del marco de seguridad JAAS (Java Authentication and Authorization Service).

sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="user1" password="pass1" \
username="user2" password="pass2" \
...;

Para finalizar, para los clientes que se deseen autenticar con SASL_PLAIN, se debe de añadir la configuración necesaria en su archivo de propiedades.

security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="user1" password="pass1";

Una vez hecho esto, se reinician los servicios y ya se tendría implementada una política de autenticación bajo el protocolo SASL_PLAIN.

SCRAM (Salted Challenge Response Authentication Mechanism)

SCRAM es un conjunto de mecanismos de autenticación que utilizan desafíos y respuestas. En este caso, las contraseñas se almacenan como un hash en lugar de transmitirse en texto claro. Kafka admite varios mecanismos SCRAM, como SCRAM-SHA-256 y SCRAM-SHA-512.

En este artículo no vamos a entrar en detalle en cómo opera este protocolo, ya que nos extenderemos mucho y no es el objetivo.

Eso sí, podemos ver la manera de configurar este protocolo, ya que se hace de forma análoga al protocolo anterior. Los requerimientos son los mismos, por lo que en el caso del broker hay que añadir la configuración para habilitar el uso del protocolo y las credenciales de autenticación en el fichero server.properties.

listeners=SASL_SSL://:9092
security.inter.broker.protocol=SASL_SSL
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256
sasl.enabled.mechanisms=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.plain.ScramLoginModule required \
username="user1" password="pass1" \
username="user2" password="pass2" \
...;

Del mismo modo, para el cliente se debe añadir la configuración necesaria para poder autenticarse con dicho protocolo.

security.protocol=SASL_SSL
sasl.mechanism=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.plain.ScramLoginModule required \
username="user1" password="pass1";

Simplemente, faltaría reiniciar los servicios y ya se tendría implementada una política de autenticación bajo el protocolo SASL_SCRAM. Esta autenticación es una opción más segura que SASL_PLAIN, ya que al no transmitir las contraseñas en texto claro tiene menos riesgo. Sin embargo, se recomienda habilitar también el cifrado SSL/TLS para una mayor seguridad.

GSSAPI (Generic Security Services Application Program Interface)

GSSAPI es un mecanismo que permite la autenticación a través de Kerberos. Se utiliza comúnmente en entornos corporativos y proporciona un alto nivel de seguridad al autenticar a los usuarios a través de un sistema centralizado de gestión de claves y tickets de Kerberos.

Si bien no es objetivo de este artículo explicar qué es Kerberos, sí que invitamos a los lectores a que echen un vistazo a saber cómo funciona para entender la configuración que hay que hacer para implementar una política de autenticación de este tipo.

Para configurar las entidades de Apache Kafka que habilitan el uso de este protocolo, tenemos que añadir configuración específica en los ficheros de configuración, tanto de los brokers como de los clientes, al igual que hemos visto en los anteriores casos. En el caso del broker, hay que añadir dicha configuración en el fichero server.properties.

listeners=SASL_SSL://:9092
security.inter.broker.protocol=SASL_SSL
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.enabled.mechanisms=GSSAPI

Además, hay que añadir la configuración de Kerberos, incluidos los nombres de los servidores y las claves. A modo de ejemplo, se puede hacer mediante la configuración de JAAS vista recientemente.

sasl.jaas.config=org.apache.kafka.common.security.kerberos.KerberosLoginModule required
useKeyTab=true
storeKey=true
keyTab="<path-to-keytab>"
principal="user@YOU.REALM";

El campo keyTab contiene las claves cifradas utilizadas para la autenticación del servicio, mientras que el principal especifica la identidad del servicio o usuario que desea autenticarse. Estos dos componentes son esenciales para la autenticación segura mediante Kerberos y GSSAPI en sistemas distribuidos como Apache Kafka.

Para finalizar, en las propiedades de configuración del cliente también tiene que verse reflejada la configuración de Kerberos además de habilitar la autenticación del protocolo SASL_GSSAPI.

security.protocol=SASL_SSL
sasl.mechanism=GSSAPI
sasl.jaas.config=org.apache.kafka.common.security.kerberos.KerberosLoginModule required
useKeyTab=true
storeKey=true
keyTab="<path-to-keytab>"
principal="user@YOU.REALM";

Y de esta forma, ya tendríamos configuradas las entidades de Apache Kafka para hacer uso del protocolo SASL_GSSAPI y Kerberos.

¿Algo más?

Si bien se ha expuesto los mecanismos más usados en el entorno de Apache Kafka, existen otras maneras interesantes a tener en cuenta a la hora de implementar una política de autenticación en este tipo de entornos:

En resumen, SASL en Kafka es un componente clave para garantizar la autenticación segura de los clientes que desean interactuar con un clúster de Kafka.

Proporciona una capa adicional de seguridad al requerir que los usuarios se autentiquen antes de acceder a los recursos de Kafka y se puede personalizar para satisfacer las necesidades de autenticación específicas de una organización.

¿Qué podemos sacar en claro? Próximos pasos

Como hemos visto, cada mecanismo de autenticación tiene sus propias ventajas y desafíos, y la elección dependerá de los requisitos de seguridad y la infraestructura del entorno en el que estemos. Es importante seleccionar el mecanismo adecuado y configurarlo correctamente para garantizar la seguridad de tu clúster de Kafka.

La convivencia de las políticas de encriptación y de autenticación resulta clave para garantizar la seguridad en nuestro entorno. Es fundamental gestionar de manera segura las credenciales de acceso a Apache Kafka, como contraseñas o claves. Las buenas prácticas de gestión de credenciales son esenciales para mantener la seguridad del sistema.

Si bien en este artículo hemos visto la manera de implementar una política de autenticación y la manera de completarse con la política de encriptación, en próximos artículos vamos a implementar la política de autorización para garantizar la seguridad de nuestro sistema con Apache Kafka. ¡No os lo perdáis!

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.