Configurer SSL, TLS et HTTPS pour sécuriser Elasticsearch, Kibana, Beats et Logstash

Si vous exécutez la Suite Elastic 6.7.x, 7.0.x ou une version antérieure, consultez l'article de blog intitulé "How to set up TLS..." (Comment configurer TLS...). Vous y découvrirez comment sécuriser les communications pour votre version. Les fonctionnalités de sécurité gratuites abordées dans le présent article nécessitent l'utilisation de la Suite Elastic 6.8, 7.1 ou d'une version ultérieure.

Depuis le lancement des versions 6.8 et 7.1 de la Suite Elastic, vous avez gratuitement accès à certaines fonctionnalités de sécurité, qui sont désormais intégrées dans la distribution par défaut (licence Basic). Avec cette nouvelle offre, vous pouvez désormais chiffrer le trafic réseau via SSL, ajouter et gérer des utilisateurs, définir des rôles qui protègent l'accès au niveau des index et des clusters, mais aussi assurer la sécurité totale de Kibana. Dans l'article de blog Prise en main de la sécurité Elasticsearch que nous avions publié peu de temps après le lancement, nous vous expliquions comment utiliser les communications TLS entre Elasticsearch et Kibana. Dans l'article ci-dessous, nous allons nous pencher sur d'autres composants de la Suite Elastic, comme Beats ou Logstash. Nous allons voir comment activer TLS entre les composants et comment chiffrer les communications client HTTP.

Remarque : si l'activation de TLS sur la couche HTTP n'est pas obligatoire, elle est néanmoins vivement recommandée pour assurer une sécurité de bout en bout et protéger les données, notamment pour éviter l'interception des noms d'utilisateur et des mots de passe, et donc la compromission du cluster. Pour en savoir plus sur le chiffrement TLS, l'authentification, les scripts limités ou l'isolation, consultez l'article de blog intitulé Chiffrement, sécurisation des données utilisateur et plus encore : nos conseils pour sécuriser gratuitement vos clusters Elasticsearch.

Autre remarque : les fonctionnalités de sécurité que nous allons configurer ci-dessous sont activées par défaut dans Elasticsearch Service sur Elastic Cloud. Si vous utilisez Elasticsearch Service, vous pouvez donc passer directement à l'étape 5.

Étapes à suivre pour sécuriser la Suite Elastic

  1. Préparation
  2. Créer des certificats SSL et activer TLS pour Elasticsearch sur "node1" (nœud1)
  3. Activer TLS pour Kibana sur "node1"
  4. Activer TLS pour Elasticsearch sur "node2" (nœud2)
  5. Préparer les utilisateurs Logstash sur "node1"
  6. Activer TLS pour Logstash sur "node1"
  7. Exécuter Filebeat et configurer TLS sur "node1"
  8. Utiliser Filebeat pour ingérer les données

Diagramme de la Suite Elastic

Étape 1. Préparation

Téléchargez les composants suivants de la Suite Elastic 7.1 ou d'une version plus récente :

[1-1] Configurer le fichier /etc/hosts

Dans cet exemple, notre "node1" (nœud1) dispose d'un navigateur, afin que kibana.local autorise l'accès à la page web de Kibana.

#fichier /etc/hosts pour le [node1] (nous avons besoin de kibana.local et de 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
#fichier /etc/hosts pour le [node2] (ici, nous n'avons pas besoin de kibana.local et logstash.local)
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2

Étape 2. Créer des certificats SSL et activer TLS pour Elasticsearch sur "node1" (nœud1)

[2-1] Définir les variables d'environnement (adapter le chemin de ces variables en fonction du mode de téléchargement d'Elasticsearch et de son emplacement)

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

[2-2] Créer un dossier tmp

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

[2-3] Créer un fichier d'instance yaml

[root@node1 cert_blog]# vi ~/tmp/cert_blog/instance.yml
# ajoutez les informations relatives à l'instance au fichier 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] Générer des certificats d'autorité de certification (CA) et de serveur (une fois Elasticsearch installé)

[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] Décompresser les certificats

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

[2-6] Configurer le TLS Elasticsearch

[2-6-1] Copier le fichier "cert" vers le dossier "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] Configurer elasticsearch.yml

[root@node1 elasticsearch]# vi elasticsearch.yml 
## ajoutez le contenu suivant
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] Démarrer et vérifier le log du cluster

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

[2-6-4] Définir un mot de passe intégré

[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] Accéder à l'API _cat/nodes via 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
Lorsque nous avons généré nos certificats SSL lors des étapes 2 à 4, nous avons fourni l'option --keep-ca-key, ce qui signifie que le dossier certs.zip contient un fichier ca/ca.key ainsi qu'un fichier ca/ca.crt. Si vous décidez d'ajouter plus de nœuds à votre cluster Elasticsearch, vous devrez générer d'autres certifications de nœuds. C'est à ce moment que les deux fichiers "ca" vous seront utiles, ainsi que le mot de passe que vous avez utilisé pour les générer. Veuillez conserver une copie de ces fichiers "ca" ainsi que le mot de passe utilisé pour les générer dans un endroit sécurisé.

Étape 3. Activer TLS pour Kibana sur "node1"

[3-1] Définir les variables d'environnement

Adaptez le chemin de ces variables en fonction du mode de téléchargement de Kibana et de son emplacement :

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

[3-2] Créer un dossier "config" et "config/certs" et copier "certs" (une fois Kibana installé)

Copiez les fichiers de certificat créés à l'étape 2-4 et collez-les dans kibana/config/certs.

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

[3-3] Configurer kibana.yml

Pensez à utiliser le mot de passe que vous avez généré plus haut pour l'utilisateur intégré. Remplacez <kibana_password> par le mot de passe défini à l'étape 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] Démarrer Kibana et tenter de se connecter

Accédez à https://kibana.local:5601/ depuis un navigateur. Connectez-vous à l'aide du nom d'utilisateur elastic et du mot de passe défini à l'étape 2-6-4. Dans cet exemple, notre "node1" (nœud1) dispose d'un navigateur, afin que kibana.local autorise l'accès à Kibana.

Connexion à Kibana

Les autorités de certification approuvées publiquement appliquent des normes et des pratiques d'audit très strictes, afin de garantir que seules les identités correctement confirmées puissent obtenir un certificat. À des fins d'illustration, nous allons créer un certificat auto-signé pour Kibana (ce qui signifie que le certificat généré est signé via sa propre clé privée). Les clients ne faisant pas confiance aux certificats Kibana auto-signés, un message similaire à celui-ci s'affiche dans vos logs Kibana jusqu'à ce que l'utilisation de certificats générés par une autorité de certification publique ou d'entreprise permette d'établir la confiance (ce lien vous permet d'accéder au problème dans le référentiel Kibana). Le problème ne vous empêche pas de travailler dans 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

Étape 4. Activer TLS pour Elasticsearch sur "node2" (nœud2)

[4-1] Définir les variables d'environnement

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

[4-2] Configurer TLS sur "node2"

Vous pouvez utiliser la commande "scp" pour copier des certificats de "node1" vers "node2". Pour sécuriser la connexion, les deux nœuds nécessitent une clé et un certificat. Dans un environnement de production, il est recommandé d'utiliser une clé correctement signée pour chaque nœud. À des fins de démonstration, nous utilisons ici un certificat d'autorité de certification généré automatiquement et un certificat de nom d'hôte multi-DNS signé par l'autorité de certification que nous avons générée.

[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] Configurer 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] Démarrer et vérifier le log du cluster

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

[4-5] Accéder à l'API _cat/nodes via 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

Étape 5. Préparer les utilisateurs Logstash sur "node1"

[5-1] Créer un rôle logstash_write_role

Il existe différentes façons de créer le rôle.

Vous pouvez le créer via l'interface utilisateur "Roles" de Kibana : 

Création d'un rôle logstash_write_role

Mais vous pouvez aussi le créer via l'API disponible dans l'onglet "Dev Tools" 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
    }
}

Vous obtenez alors la réponse suivante :

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

Les utilisateurs associés à ce rôle ne pourront supprimer aucun document. Ce rôle limite les autorisations des utilisateurs à la création d'index commençant par logstash et à l'indexation de documents dans ces index.

Remarque pour les utilisateurs d’ILM : Pour que logstash_writer_role fonctionne avec la gestion du cycle de vie (ILM), activée par défaut à partir de la version 7.3, les privilèges suivants doivent être inclus :


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

[5-2] Créer un utilisateur logstash_writer (penser à modifier le mot de passe de l'utilisateur logstash_writer)

Il existe différentes façons de créer l'utilisateur.

Vous pouvez le créer via l'interface utilisateur "Users" de Kibana :

Création de l'utilisateur logstash_writer

Mais vous pouvez aussi le créer via l'API disponible dans l'onglet "Dev Tools" 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
}

Vous obtenez alors la réponse suivante :

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

Étape 6. Activer TLS pour Logstash sur "node1"

[6-1] Créer un dossier et copier les certificats

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

[6-2] Convertir logstash.key au format PKCS#8 pour le plug-in d'entrée Beats

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

[6-3] Configurer logstash.yml

Pensez à utiliser le mot de passe généré automatiquement pour l'utilisateur logstash_system. Utilisez le mot de passe défini à l'étape 2-6-4.

[root@node1 logstash]# vi logstash.yml

Puis modifiez :

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] Créer et configurer conf.d/example.conf

Sur la sortie Elasticsearch, utilisez le mot de passe défini à l'étape 5-2.

[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] Démarrer Logstash avec l'exemple de configuration et vérifier le log Logstash

Les messages de log suivants doivent s'afficher :

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

Dans l'onglet "Monitoring" de Kibana, Logstash doit également s'afficher (informations sur le nœud, les paramètres du pipeline, le système d'exploitation, la machine virtuelle Java (JVM), les statistiques de traitement et les statistiques d'exécution du pipeline) :

Onglet "Monitoring" de Kibana affichant Logstash

Étape 7. Exécuter Filebeat et configurer TLS sur "node1"

[7-1] Créer un dossier "config" et copier les certificats

[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] Créer un nouveau fichier filebeat.yml

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

[7-3] Modifier le nouveau fichier de configuration filebeat.yml

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

Étape 8. Utiliser Filebeat pour ingérer les données

[8-1] Préparer les données du log d'entrée (logstash-tutorial.log) pour Filebeat

Commencez par télécharger les données du log d'entrée.

[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] Démarrer 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] Vérifier le log

Les messages de log suivants doivent s'afficher :

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

[8-4] Créer un modèle d'indexation

Ensuite, créez un modèle d'indexation correspondant aux données en cours d'ingestion. Cela permet la visualisation des données dans Kibana, par exemple via les onglets Graph ou Discover.

Création d'un modèle d'indexation dans Kibana.

Sélectionnez ensuite le nom du champ "Time Filter" (filtre temporel). Dans notre exemple, il s'agit de @timestamp :

Spécifier un nom de champ "Time Filter".

Et voilà ! Vous venez de chiffrer la communication entre les différents composants de la Suite Elastic et vous ingérez maintenant des données de log en toute sécurité.

Pour terminer

Si vous rencontrez des problèmes lors de la configuration de la sécurité, commencez par jeter un œil au guide de résolution des problèmes de sécurité. Il peut vous aider à résoudre bon nombre de problèmes courants. Si vous avez toujours des questions après cela, n'hésitez pas à demander de l'aide sur les forums Elastic. Et si vous préférez contacter directement l'équipe de support technique Elastic, souscrivez un abonnement Elastic : il vous donnera directement accès à une équipe d'experts. En attendant un prochain article, faites attention à vous (et à votre cluster) !