Configuración de SSL, TLS y HTTPS para asegurar Elasticsearch, Kibana, Beats y Logstash

¿Ejecutas el Elastic Stack 6.7.x/7.0.x o anterior? Entonces echa un vistazo al blog “How to set up TLS...” (Cómo configurar TLS...) para obtener ayuda sobre cómo asegurar las comunicaciones en tus versiones. Las características de seguridad gratuitas que se abordan en este blog requieren el Elastic Stack 6.8/7.1 o posterior.

Elastic lanzó algunas características de seguridad de manera gratuita como parte de la distribución predeterminada (licencia Basic) a partir del Elastic Stack 6.8 y 7.1. Esta oferta de característica nueva incluye la capacidad de encriptar el tráfico de red usando SSL, crear y administrar usuarios, definir roles que protejan el acceso a nivel del índice y el cluster, y asegurar Kibana por completo. En nuestro blog de primeros pasos que se publicó poco después del lanzamiento, se explica cómo usar la comunicación TLS entre Elasticsearch y Kibana. El blog siguiente amplía estas pautas para abordar otros componentes del Elastic Stack, incluidos Logstash y Beats. En él, se analiza la habilitación de TLS entre componentes y la encriptación de comunicaciones del cliente HTTP.

Ten en cuenta que si bien no es obligatorio habilitar TLS en la capa HTTP, es muy recomendable hacerlo para lograr una seguridad integral y proteger los datos, especialmente para evitar la interceptación de la información de nombre de usuario y contraseña, lo que comprometería el cluster. Si deseas saber más acerca de la encripción TLS, la autenticación, los scripts restringidos o el aislamiento, visita el blog Tips to secure Elasticsearch clusters for free with encryption, users, and more (Consejos para asegurar los clusters de Elasticsearch de forma gratuita con encripción, usuarios y más).

Como nota adicional, las características de seguridad que se habilitan a continuación vienen incluidas con el Elasticsearch Service en Elastic Cloud. Si estás usando Elasticsearch Service, puedes avanzar directamente al paso 5.

Pasos para asegurar el Elastic Stack

  1. Preparaciones
  2. Crear certificados SSL y habilitar TLS para Elasticsearch en node1
  3. Habilitar TLS para Kibana en node1
  4. Habilitar TLS para Elasticsearch en node2
  5. Preparar usuarios de Logstash en node1
  6. Habilitar TLS para Logstash en node1
  7. Ejecutar Filebeat y configurar TLS en node1
  8. Usar Filebeat para ingestar datos

Diagrama del Elastic Stack

Paso 1. Preparaciones

Descarga los componentes siguientes del Elastic Stack 7.1 o posterior:

[1-1] Configurar el archivo /etc/hosts

En este ejemplo, nuestro node1 tiene un navegador instalado, por lo que kibana.local permitirá el acceso a la página web de Kibana.

# archivo /etc/hosts para [node1] (necesitamos kibana.local y logstash.local)
127.0.0.1 kibana.local logstash.local
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2
# archivo /etc/hosts para [node2] (no necesitamos kibana.local y logstash.local en este caso)
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2

Paso 2. Crear certificados SSL y habilitar TLS para Elasticsearch en node1

[2-1] Configurar las variables de entorno (adaptar estas rutas de variables según dónde y cómo se descargó Elasticsearch)

[root@node1 ~]# ES_HOME=/usr/share/elasticsearch
[root@node1 ~]# ES_PATH_CONF=/etc/elasticsearch

[2-2] Crear la carpeta tmp

[root@node1 ~]# mkdir tmp
[root@node1 ~]# cd tmp/
[root@node1 tmp]# mkdir cert_blog

[2-3] Crear el archivo instance.yml

[root@node1 cert_blog]# vi ~/tmp/cert_blog/instance.yml
# agregar la información de la instancia al archivo yml
instances:
  - name: 'node1'
    dns: [ 'node1.elastic.test.com' ]
  - name: "node2"
    dns: [ 'node2.elastic.test.com' ]
  - name: 'my-kibana'
    dns: [ 'kibana.local' ]
  - name: 'logstash'
    dns: [ 'logstash.local' ]

[2-4] Generar certificados del servidor y CA (una vez instalado Elasticsearch)

[root@node1 tmp]# cd $ES_HOME
[root@node1 elasticsearch]# bin/elasticsearch-certutil cert --keep-ca-key --pem --in ~/tmp/cert_blog/instance.yml --out ~/tmp/cert_blog/certs.zip

[2-5] Descomprimir los certificados

[root@node1 elasticsearch]# cd ~/tmp/cert_blog
[root@node1 cert_blog]# unzip certs.zip -d ./certs

[2-6] Configuración de TLS de Elasticsearch

[2-6-1] Copiar archivo cert a la carpeta config

[root@node1 ~]# cd $ES_PATH_CONF
[root@node1 elasticsearch]# pwd
/etc/elasticsearch
[root@node1 elasticsearch]# mkdir certs
[root@node1 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca* ~/tmp/cert_blog/certs/node1/* certs
[root@node1 elasticsearch]# ll certs
total 12
-rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.crt
-rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.key
-rw-r--r--. 1 root elasticsearch 1509 Apr 12 08:47 node1.crt
-rw-r--r--. 1 root elasticsearch 1679 Apr 12 08:47 node1.key
[root@node1 elasticsearch]#

[2-6-2] Configurar elasticsearch.yml

[root@node1 elasticsearch]# vi elasticsearch.yml 
## agregar los contenidos siguientes
node.name: node1
network.host: node1.elastic.test.com
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.key: certs/node1.key
xpack.security.http.ssl.certificate: certs/node1.crt
xpack.security.http.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.key: certs/node1.key
xpack.security.transport.ssl.certificate: certs/node1.crt
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
discovery.seed_hosts: [ "node1.elastic.test.com" ]
cluster.initial_master_nodes: [ "node1" ]

[2-6-3] Iniciar y comprobar el log del cluster

[root@node1 elasticsearch]# grep '\[node1\] started' /var/log/elasticsearch/elasticsearch.log 
[o.e.n.Node               ] [node1] started

[2-6-4] Configurar contraseña del usuario integrado

[root@node1 elasticsearch]# cd $ES_HOME
[root@node1 elasticsearch]# bin/elasticsearch-setup-passwords auto -u "https://node1.elastic.test.com:9200"
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
The passwords will be randomly generated and printed to the console.
Please confirm that you would like to continue [y/N] y
Changed password for user apm_system
PASSWORD apm_system = <apm_system_password>
Changed password for user kibana
PASSWORD kibana = <kibana_password>
Changed password for user logstash_system
PASSWORD logstash_system = <logstash_system_password>
Changed password for user beats_system
PASSWORD beats_system = <beats_system_password>
Changed password for user remote_monitoring_user
PASSWORD remote_monitoring_user = <remote_monitoring_user_password>
Changed password for user elastic
PASSWORD elastic = <elastic_password>

[2-6-5] Acceder a la API _cat/nodes mediante HTTPS

[root@node1 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic 'https://node1.elastic.test.com:9200/_cat/nodes?v'
Enter host password for user 'elastic':
ip          heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.0.2           16          95  10    0.76    0.59     0.38 mdi       *      node1
Cuando generamos nuestros certificados SSL en los pasos 2 a 4, proporcionamos la opción --keep-ca-key, que significa que el archivo certs.zip contiene un archivo ca/ca.key junto con el archivo ca/ca.crt. Si en algún momento decides agregar más nodos a tu cluster de Elasticsearch, querrás generar certificados de nodos adicionales; y para hacerlo necesitarás ambos archivos “ca” además de la contraseña que usaste para generarlos. Mantén una copia de estos archivos ca y la contraseña usada para generarlos en un lugar seguro.

Paso 3. Habilitar TLS para Kibana en node1

[3-1] Configurar las variables del entorno

Adapta estas rutas de variables según dónde y cómo se descargó Kibana:

[root@node1 ~]# KIBANA_HOME=/usr/share/kibana
[root@node1 ~]# KIBANA_PATH_CONFIG=/etc/kibana

[3-2] Crear las carpetas config y config/certs, y copiar los certificados (una vez instalado Kibana)

Copia los archivos de certificación creados previamente en el paso 2-4 y pégalos en kibana/config/certs.

[root@node1 kibana]# ls config/certs
total 12
ca.crt
my-kibana.crt
my-kibana.key

[3-3] Configurar kibana.yml

Recuerda usar la contraseña anterior generada para el usuario integrado. Debes reemplazar <kibana_password> con la contraseña definida en el paso 2-6-4.

[root@node1 kibana]# vi kibana.yml 
server.name: "my-kibana"
server.host: "kibana.local"
server.ssl.enabled: true
server.ssl.certificate: /etc/kibana/config/certs/my-kibana.crt
server.ssl.key: /etc/kibana/config/certs/my-kibana.key
elasticsearch.hosts: ["https://node1.elastic.test.com:9200"]
elasticsearch.username: "kibana"
elasticsearch.password: "<kibana_password>"
elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/config/certs/ca.crt" ]

[3-4] Iniciar Kibana y probar el inicio de sesión en Kibana

Accede a https://kibana.local:5601/ desde un navegador. Inicia sesión con el usuario elastic y la contraseña definida en el paso 2-6-4. En este ejemplo, nuestro node1 tiene un navegador instalado, por lo que kibana.local permitirá el acceso a Kibana.

Iniciar sesión en Kibana

Las autoridades de confianza pública tienen prácticas de auditoría y estándares muy estrictos para asegurarse de que no se cree un certificado sin validar la propiedad de la identidad adecuada. En este blog, crearemos un certificado autofirmado para Kibana (lo que significa que el certificado generado se firma usando su propia clave privada). Como los clientes no confían en certificados de Kibana autofirmados, verás un mensaje similar al siguiente en tus logs de Kibana, hasta que se establezca la confianza adecuada con el uso de certificados generados por una empresa o CA pública (este es el enlace al problema en el repositorio de Kibana). Este problema no afecta tu capacidad para trabajar en Kibana:

[18:22:31.675] [error][client][connection] Error: 4443837888:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/s3_pkt.c:1498:SSL alert number 46

Paso 4. Habilitar TLS para Elasticsearch en node2

[4-1] Configurar las variables del entorno

[root@node2 ~]# ES_HOME=/usr/share/elasticsearch
[root@node2 ~]# ES_PATH_CONF=/etc/elasticsearch

[4-2] Configurar TLS en node2

Puedes usar el comando scp para copiar certificados de node1 a node2. Ambos nodos requieren el certificado y la clave para asegurar la conexión. En un entorno de producción, se recomienda usar una clave correctamente firmada para cada nodo. Para fines de demostración, estamos usando un certificado de CA generado automáticamente y un certificado de nombre de host multi-DNS firmado por nuestra CA generada.

[root@node2 ~]# cd $ES_PATH_CONF
[root@node2 elasticsearch]# pwd
/etc/elasticsearch
[root@node2 elasticsearch]# mkdir certs
[root@node2 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca.crt ~/tmp/cert_blog/certs/node2/* certs  
[root@node2 elasticsearch]# 
[root@node2 elasticsearch]# ll certs
total 12
-rw-r--r--. 1 root elasticsearch 1834 Apr 12 10:55 ca.crt
-rw-r--r--. 1 root elasticsearch 1509 Apr 12 10:55 node2.crt
-rw-r--r--. 1 root elasticsearch 1675 Apr 12 10:55 node2.key

[4-3] Configurar elasticsearch.yml

[root@node2 elasticsearch]# vi elasticsearch.yml 
node.name: node2
network.host: node2.elastic.test.com
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.key: certs/node2.key
xpack.security.http.ssl.certificate: certs/node2.crt
xpack.security.http.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.key: certs/node2.key
xpack.security.transport.ssl.certificate: certs/node2.crt
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
discovery.seed_hosts: [ "node1.elastic.test.com" ]

[4-4] Iniciar y comprobar el log del cluster

[root@node2 elasticsearch]# grep '\[node2\] started' /var/log/elasticsearch/elasticsearch.log 
[o.e.n.Node               ] [node2] started

[4-5] Acceder a la API _cat/nodes mediante HTTPS

[root@node2 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic:<password set previously> 'https://node2.elastic.test.com:9200/_cat/nodes?v'
ip          heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.0.2           25          80   5    0.18    0.14     0.30 mdi       *      node1
192.168.0.3           14          96  44    0.57    0.47     0.25 mdi       -      node2

Paso 5. Preparar usuarios de Logstash en node1

[5-1] Crear logstash_write_role

Puedes crear el rol de varias formas.

Puedes crearlo usando la UI Roles de Kibana: 

Creación de un logstash_write_role

O puedes crearlo usando la API en la pestaña Dev Tools (Herramientas de desarrollo) de Kibana:

POST /_security/role/logstash_write_role
{
    "cluster": [
      "monitor",
      "manage_index_templates"
    ],
    "indices": [
      {
        "names": [
          "logstash*"
        ],
        "privileges": [
          "write",
          "create_index"
        ],
        "field_security": {
          "grant": [
            "*"
          ]
        }
      }
    ],
    "run_as": [],
    "metadata": {},
    "transient_metadata": {
      "enabled": true
    }
}

Y obtendrás la respuesta:

{"role":{"created":true}}

Los usuarios con este rol asignado no podrán eliminar ningún documento. Este rol restringe a los usuarios a la creación de índices solo si comienzan con logstash o indexan documentos en esos índices.

Nota para los usuarios de ILM: Para que logstash_writer_role funcione con la gestión de ciclo de vida (ILM) —habilitada de forma predeterminada en la versión 7.3 y posteriores— deben estar incluidos los privilegios siguientes:


"privileges": ["write","create","delete","create_index","manage","manage_ilm"]
        

[5-2] Crear el usuario logstash_writer (cambiar la contraseña del usuario logstash_writer)

Puedes crear el usuario de varias formas.

Puedes crearlo usando la UI Users (Usuarios) de Kibana:

Creación del usuario logstash_writer

O puedes crearlo usando la API en la pestaña Dev Tools (Herramientas de desarrollo) de Kibana:

POST /_security/user/logstash_writer
{
  "username": "logstash_writer",
  "roles": [
    "logstash_write_role"
  ],
  "full_name": null,
  "email": null,
  "password": "<logstash_system_password>",
  "enabled": true
}

Y obtendrás la respuesta:

{"user":{"created":true}}

Paso 6. Habilitar TLS para Logstash en node1

[6-1] Crear carpeta y copiar certificados

[root@node1 logstash]# ls -l
total 24
ca.crt
logstash.crt
logstash.key

[6-2] Convertir logstash.key a formato PKCS#8 para el plugin de entrada de Beats

[root@node1 logstash]# openssl pkcs8 -in config/certs/logstash.key -topk8 -nocrypt -out config/certs/logstash.pkcs8.key

[6-3] Configurar logstash.yml

Recuerda usar la contraseña autogenerada para el usuario logstash_system. Usa la contraseña definida en el paso 2-6-4.

[root@node1 logstash]# vi logstash.yml

Luego edita lo siguiente:

node.name: logstash.local
path.config: /etc/logstash/conf.d/*.conf
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.username: logstash_system
xpack.monitoring.elasticsearch.password: '<logstash_system_password>'
xpack.monitoring.elasticsearch.hosts: [ 'https://node1.elastic.test.com:9200' ]
xpack.monitoring.elasticsearch.ssl.certificate_authority: /etc/logstash/config/certs/ca.crt

[6-4] Crear y configurar conf.d/example.conf

Usa la contraseña definida en el paso 5-2 en la salida de Elasticsearch.

[root@node1 logstash]# vi conf.d/example.conf 
input {
  beats {
    port => 5044
    ssl => true
    ssl_key => '/etc/logstash/config/certs/logstash.pkcs8.key'
    ssl_certificate => '/etc/logstash/config/certs/logstash.crt'
  }
}
output {
  elasticsearch {
    hosts => ["https://node1.elastic.test.com:9200","https://node2.elastic.test.com:9200"]
    cacert => '/etc/logstash/config/certs/ca.crt'
    user => 'logstash_writer'
    password => <logstash_writer_password>
  }
}

[6-5] Iniciar Logstash con la configuración de ejemplo y comprobar el log de Logstash

Deberíamos ver los mensajes de log siguientes:

[INFO ][logstash.pipeline        ] Pipeline started successfully {:pipeline_id=>".monitoring-logstash", :thread=>"#<Thread:0x640c14d2@/usr/share/logstash/logstash-core/lib/logstash/pipeline.rb:246 run

Y en la pestaña Monitoring (Monitoreo) de Kibana, se mostrará Logstash (información del nodo, configuraciones de pipeline, información del SO, información de JVM, estadísticas de procesamiento y estadísticas de tiempo de ejecución de pipeline):

Pestaña Monitoring (Monitoreo) de Kibana con la visualización de Logstash

Paso 7. Ejecutar Filebeat y configurar TLS en node1

[7-1] Crear una carpeta config y copiar certificados

[root@node1 filebeat]# mkdir config
[root@node1 filebeat]# mkdir config/certs
[root@node1 filebeat]# cp ~/tmp/cert_blog/certs/ca/ca.crt config/certs
[root@node1 filebeat]# ll config/certs/
total 4
-rw-r--r--. 1 root root 1834 Apr 20 00:18 ca.crt

[7-2] Crear un nuevo filebeat.yml

[root@node1 filebeat]# pwd
/etc/filebeat
[root@node1 filebeat]# mv filebeat.yml filebeat.yml.old

[7-3] Editar tu archivo de configuración filebeat.yml nuevo

filebeat.inputs:
- type: log
  paths:
    - /etc/filebeat/logstash-tutorial-dataset
output.logstash:
  hosts: ["logstash.local:5044"]
  ssl.certificate_authorities:
    - /etc/filebeat/config/certs/ca.crt

Paso 8. Usar Filebeat para ingestar datos

[8-1] Preparar los datos de log de entrada (logstash-tutorial.log) para Filebeat

Primero, descarga los datos de log de entrada.

[root@node1 filebeat]# pwd
/etc/filebeat
[root@node1 filebeat]# mkdir logstash-tutorial-dataset
[root@node1 filebeat]# cp /root/logstash-tutorial.log logstash-tutorial-dataset/.
[root@node1 filebeat]# ll logstash-tutorial-dataset/
total 24
-rwxr-x---. 1 root root 24464 Apr 20 00:29 logstash-tutorial.log

[8-2] Iniciar Filebeat

[root@node1 filebeat]# systemctl start filebeat
[root@node1 filebeat]# systemctl enable filebeat
Created symlink from /etc/systemd/system/multi-user.target.wants/filebeat.service to /usr/lib/systemd/system/filebeat.service.

[8-3] Comprobar el log

Deberíamos ver los mensajes de log siguientes:

INFO    log/harvester.go:216    Harvester started for file: /etc/filebeat/logstash-tutorial-dataset/logstash-tutorial.log

[8-4] Crear patrón de índice

A continuación, crea un patrón de índice que coincida con los datos que se están ingestando. Esto permitirá visualizar los datos en Kibana, como con Graph o Discover.

Crea un patrón de índice en Kibana.

Después, selecciona el nombre de campo Time Filter (Filtro de tiempo). En nuestro ejemplo, es @timestamp:

Especifica un nombre de campo Time Filter (Filtro de tiempo).

Eso es todo. Encriptaste la comunicación entre las distintas partes del Elastic Stack y ahora ingestas datos de log de forma segura y protegida.

Algunos comentarios finales...

Si encuentras algún problema durante la configuración de seguridad, te recomendamos consultar primero la guía de solución de problemas de seguridad de nuestra documentación. Puede ser útil para muchos problemas comunes. Si después de consultarla sigues teniendo dudas, visita nuestros foros de Elastic para obtener ayuda adicional. O si deseas hablar directamente con el equipo de Soporte de Elastic, inicia una suscripción a Elastic hoy mismo y accede de forma directa a un equipo de expertos. ¡Mantente seguro!