Cómo asegurar los clústeres de Elasticsearch a través de Kerberos | Elastic Blog
Engineering

Cómo asegurar los clústeres de Elasticsearch a través de Kerberos

El feroz perro guardián de tres cabezas que mantiene los datos seguros

Elasticsearch 6.4 añade soporte para la autenticación de Kerberos para subscripciones Platino, que se trata del primer paso hacia un Elastic Stack totalmente "kerberizado". Kerberos es una tecnología consolidada que permite una autenticación segura en sistemas distribuidos. Kerberos proporciona acceso de inicio de sesión único a diferentes servicios sin necesidad de proporcionar nombres de usuario ni contraseñas una y otra vez. Este blog brinda información acerca de cómo configurar Elasticsearch a fin de admitir la autenticación de Kerberos para el tráfico HTTP.

Visión general del despliegue

Consideremos un escenario simple en el que un usuario llamado "Alice" tiene un cluster de nodo único de Elasticsearch. Alice ya cuenta con un realm de Kerberos, "demo.local", y le gustaría asegurar el cluster de Elasticsearch a través de la autenticación de Kerberos. El servidor de autenticación Kerberos tiene la autoridad necesaria para autenticar un host, un servicio o a un usuario dentro del realm. Los comandos que se usan en este artículo se refieren a la implementación de MIT Kerberos. Consulta la documentación de MIT Kerberos para obtener detalles adicionales.

En este simple escenario, se observan tres máquinas host:

  • Host-1 ("kdc.demo.local"): Este es el centro de distribución de claves (Key Distribution Center, KDC) de Kerberos, que suele cumplir con las responsabilidades del servidor de autenticación y del servidor emisor de tickets.
  • Host-2 ("es.demo.local"): Aquí es donde reside el cluster de nodo único de Elasticsearch.
  • Host-3 ("client.demo.local"): Aquí es donde reside el cliente de Elasticsearch.

SimpleESKerberosDeployment

Estos son los pasos para una correcta autenticación de Kerberos:

  1. Alice ("alice@DEMO.LOCAL") inicia sesión en la máquina del cliente ("client.demo.local") con sus credenciales.
  2. La máquina del cliente solicita un ticket emisor de tickets (Ticket Granting Ticket, TGT) del servidor del KDC ("kdc.demo.local").
  3. El cliente accede al servicio de Elasticsearch "https://es.demo.local:9200", que a su vez tendrá una respuesta con un código de estado HTTP de "Unauthorized(401)" e incluirá el encabezado "WWW-Authenticate: Negotiate".
  4. El cliente le solicita un ticket de sesión al TGS para el nombre principal "HTTP/es.demo.local@DEMO.LOCAL" del servicio de Elasticsearch. El nombre principal del servicio de Elasticsearch deriva de la URL que se usa para acceder al servicio.
  5. El cliente presenta este ticket al servicio de Elasticsearch para la autenticación.
  6. El servicio de Elasticsearch valida el ticket de Kerberos y otorga acceso (si el ticket es válido).

Configuremos el realm de Kerberos

Para habilitar el realm de Elasticsearch Kerberos, tienes que preparar la infraestructura de Kerberos:

  • Se deben sincronizar los relojes de todas las máquinas participantes del dominio.
  • Se debe disponer de un dominio DNS activo para todas las máquinas participantes.
  • Se debe disponer de un servidor de KDC.
  • Se deben instalar los nodos del cliente con bibliotecas de Kerberos y archivos de configuración como "kinit", klist".

Una vez preparada la infraestructura de Kerberos, necesita la siguiente información:

  • Archivo de configuración de Kerberos "krb5.conf": Este archivo contiene los detalles necesarios para el entorno de Kerberos, como el realm predeterminado, los servidores del KDC y los mapeos del realm del dominio. En un sistema Linux, este archivo suele encontrarse en el directorio "/etc". La propiedad del sistema JVM "java.security.krb5.conf" debe establecerse en la ruta completa de este archivo de configuración. La JVM cargará esta configuración y la usará para encontrar la información requerida cuando sea necesario.
  • Servicio HTTP de Elasticsearch "keytab": Keytab es un archivo que almacena pares de nombres principales y claves de cifrado. Este es el archivo keytab que usa el servicio HTTP de Elasticsearch para validar los tickets entrantes de los clientes. En general, el (los) nombre(s) principal(es) del servicio suele estar en formato "HTTP/es.demo.local@DEMO.LOCAL", donde la clase de servicio es "HTTP", "es.demo.local" es el nombre de dominio completo para el host de Elasticsearch y "DEMO.LOCAL" es el realm de Kerberos. Este archivo debe colocarse en el directorio de configuración de Elasticsearch. Asegúrate de proteger este archivo otorgándole permisos de archivo de solo lectura al usuario que ejecuta Elasticsearch, ya que este archivo contiene credenciales. El administrador del sistema de Kerberos puede proporcionarte el archivo keytab para el servicio.

Ahora que contamos con estos dos archivos, podemos proceder a configurar el realm de Kerberos en Elasticsearch.

1. Configura la opciones JVM

En primer lugar, debemos editar el archivo de opciones JVM ("jvm.options") para configurar la propiedad del sistema JVM para el archivo de configuración de Kerberos:

# Kerberos configuration
-Djava.security.krb5.conf=/etc/krb5.conf

2. Configura Elasticsearch para Kerberos

Después debemos añadir un realm de Kerberos en el archivo "elasticsearch.yml":

# Kerberos realm
xpack.security.authc.realms.kerb1:
type: kerberos
    order: 1
    keytab.path: es.keytab

Esto configura el realm de Kerberos ("kerb1") del tipo "kerberos" , orden de realm "1", y orienta el archivo "keytab.path" al archivo keytab del servicio de Elasticsearch ("es.keytab") en el directorio de configuración. Para obtener más detalles, consulta la documentación sobre la configuración del realm de kerberos.

3. Reinicia Elasticsearch

Una vez que la configuración esté lista, el nodo de Elasticsearch debe reiniciarse.

4. Mapea los usuarios de Kerberos a sus roles

Kerberos es un protocolo de autenticación que no proporciona detalles de autorización. Para la autorización, podemos usar la API de mapeos de roles para asignar usuarios a roles. Lo siguiente crea mapeos de roles llamados "kerbrolemapping", donde el rol "monitoring_user" se asigna al usuario "alice@DEMO.LOCAL":

$ curl -u elastic -H "Content-Type: application/json" -XPOST http://es.demo.local:9200/_xpack/security/role_mapping/kerbrolemapping -d 

{
    "roles" : [ "monitoring_user" ],
    "enabled": true,
    "rules" : {
    "field" : { "username" : "alice@DEMO.LOCAL" }
    }
}

Para obtener más detalles sobre los mapeos de roles, consulta la documentación sobre mapeos de usuarios y grupos a roles.

Voilà, ¡funciona!

Para asegurarnos de que la autenticación funcione en la máquina del cliente, debemos emitir el comando "kinit" para obtener un ticket emisor de tickets:

$ kinit alice@DEMO.LOCAL  
Password for alice@DEMO.LOCAL:  
$ klist  
Ticket cache: KEYRING:persistent:1000:krb_ccache_NvNtNgS  
Default principal: alice@DEMO.LOCAL  

Valid starting      Expires             Service principal
31/08/18 02:20:07   01/09/18 02:20:04   krbtgt/DEMO.LOCAL@DEMO.LOCAL

Después invoca el "curl" con el parámetro "negotiate" de manera que pueda realizarse la autenticación de Kerberos en HTTP:

$ curl --negotiate -u : -XGET http://es.demo.local:9200/

y ¡listo!

{
    "name" : "Lw7K29R",
    "cluster_name" : "elasticsearch",
    "cluster_uuid" : "qd3iafXORLy0VCfVD_Hp9w",
    "version" : {
    "number" : "6.4.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "595516e",
    "build_date" : "2018-08-17T23:18:47.308994Z",
    "build_snapshot" : true,
    "lucene_version" : "7.4.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
    },
    "tagline" : "You Know, for Search"
}

Conclusión

Como vimos, es fácil configurar un realm de Kerberos una vez que tienes acceso al archivo de servicio con nombre principal keytab del servicio y al archivo de configuración de Kerberos; solo se necesitan unas pocas líneas de configuración de realm de Kerberos para Elasticsearch. El soporte de Kerberos en Elasticsearch es solo el comienzo; continuaremos lanzando servicios de soporte para otros componentes del Elastic Stack en futuras actualizaciones. Permanece alerta.