Configuração de SSL, TLS e HTTPS para proteger o Elasticsearch, o Kibana, o Beats e o Logstash

Está executando o Elastic Stack 6.7.x / 7.0.x ou versões anteriores? Então confira o blog "How to set up TLS..." (Como configurar o TLS...) para obter ajuda ao proteger as comunicações em suas versões. Os recursos de segurança gratuitos tratados nesta postagem de blog exigem o Elastic Stack 6.8 / 7.1 ou versões posteriores.

A Elastic lançou alguns recursos de segurança gratuitamente como parte da distribuição padrão (licença Basic) a partir do Elastic Stack 6.8 e 7.1. Essa nova oferta de recursos inclui a capacidade de criptografar o tráfego de rede usando SSL, criar e gerenciar usuários, definir funções que protegem o acesso de nível de índice e de cluster e proteger totalmente o Kibana. Nosso post do blog de introdução que apareceu pouco depois do lançamento explica como usar a comunicação TLS entre o Elasticsearch e o Kibana. O blog a seguir expande essa orientação para tratar de outros componentes do Elastic Stack, incluindo o Logstash e o Beats. Ele trata da habilitação do TLS entre componentes, além da criptografia de comunicações de clientes HTTP.

Observe que, apesar de a habilitação do TLS na camada de HTTP não ser obrigatória, ela é altamente recomendável para segurança total para proteger os dados, principalmente para proteger informações de nome de usuário/senha contra ataques de eavesdropping, resultando em um cluster comprometido. Se quiser saber mais sobre criptografia TLS, autenticação, scripts restritos ou isolamento, confira o blog Tips to secure Elasticsearch clusters for free with encryption, users, and more (Dicas para proteger gratuitamente os clusters do Elasticsearch com criptografia, usuários e mais).

Como observação adicional, os recursos de segurança sendo habilitados a seguir são fornecidos como padrão com o Elasticsearch Service no Elastic Cloud. Se estiver operando no Elasticsearch Service, você poderá avançar diretamente para a etapa 5.

Etapas para proteger o Elastic Stack

  1. Preparativos
  2. Crie certificados SSL e habilite o TLS para o Elasticsearch em node1
  3. Habilite o TLS para o Kibana em node1
  4. Habilite o TLS para o Elasticsearch em node2
  5. Prepare os usuários do Logstash em node1
  6. Habilite o TLS para o Logstash em node1
  7. Execute o Filebeat e configure o TLS em node1
  8. Use o Filebeat para fazer ingestão dos dados

Diagrama do Elastic Stack

Etapa 1. Preparativos

Baixe os seguintes componentes do Elastic Stack 7.1 ou versões posteriores:

[1-1] Configure o arquivo /etc/hosts

Para este exemplo, nosso node1 tem um navegador instalado, por isso kibana.local permitirá o acesso à página da Web do Kibana.

# /etc/hosts file for [node1] (precisamos de kibana.local e 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
# /etc/hosts file for [node2] (não precisamos de kibana.local e logstash.local aqui)
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2

Etapa 2. Crie certificados SSL e habilite o TLS para o Elasticsearch em node1

[2-1] Defina as variáveis do ambiente (adapte o caminho dessas variáveis dependendo de onde e como foi feito o download do Elasticsearch)

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

[2-2] Crie a pasta tmp

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

[2-3] Crie o arquivo instance yaml

[root@node1 cert_blog]# vi ~/tmp/cert_blog/instance.yml
# adicione as informações de instância ao arquivo 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] Gere os certificados de CA e de servidor (depois que o Elasticsearch estiver instalado)

[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] Descompacte os certificados

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

[2-6] Instalação de TLS do Elasticsearch

[2-6-1] Copie o arquivo cert para a pasta 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] Configure elasticsearch.yml

[root@node1 elasticsearch]# vi elasticsearch.yml 
## adicione o seguinte conteúdo
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] Comece e verifique o log de cluster

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

[2-6-4] Defina a senha de usuário integrada

[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] Acesse a API _cat/nodes por meio de 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
Quando geramos nossos certificados SSL na etapa 2-4, fornecemos a opção --keep-ca-key, o que significa que o arquivo certs.zip contém um arquivo ca/ca.key junto com o arquivo ca/ca.crt. Caso decida adicionar mais nós ao seu cluster do Elasticsearch, você deverá gerar certificados de nós adicionais e, para isso, precisará desses dois arquivos “ca” e da senha usada para gerá-los. Guarde uma cópia desses arquivos ca e da senha usada para gerá-los em um local seguro.

Etapa 3. Habilite o TLS para o Kibana em node1

[3-1] Defina as variáveis de ambiente

Adapte esses caminhos de variáveis dependendo de onde e como foi feito o download do Kibana:

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

[3-2] Crie a pasta config e config/certs e copie certs (depois que o Kibana estiver instalado)

Copie os arquivos de certificação criados anteriormente na etapa 2-4 e cole em kibana/config/certs.

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

[3-3] Configure kibana.yml

Lembre-se de usar a senha gerada para o usuário integrado acima. Você precisa substituir pela senha que foi definida na etapa 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] Comece o Kibana e teste o login do Kibana

Acesse https://kibana.local:5601/ em um navegador. Faça login usando o usuário elastic e a senha que foi definida na etapa 2-6-4. Para este exemplo, nosso node1 tem um navegador instalado, por isso kibana.local permitirá o acesso ao Kibana.

Faça login no Kibana

Autoridades confiáveis junto ao público têm padrões e práticas de auditoria muito rígidos para garantir que um certificado não seja criado sem validar a propriedade adequada da identidade. Para a finalidade desta postagem de blog, criaremos um certificado autoassinado para o Kibana (significando que o certificado gerado foi assinado usando a própria chave privada). Como os clientes não confiam nos certificados Kibana autoassinados, você verá uma mensagem semelhante a estanos logs do Kibana, até que a confiança adequada seja estabelecida usando os certificados gerados por uma CA empresarial ou pública (a seguir está o link para o problema no repositório do Kibana). Esse problema não afeta sua capacidade de trabalhar no 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

Etapa 4. Habilite o TLS para o Elasticsearch em node2

[4-1] Defina as variáveis de ambiente

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

[4-2] Configure o TLS em node2

Você pode usar o comando scp para copiar certificados do node1 para o node2. Ambos os nós exigem o certificado e a chave para proteger a conexão. Em um ambiente de Produção, é recomendável usar uma chave devidamente assinada para cada nó. Para fins de demonstração, estamos usando um certificado CA gerado automaticamente e um certificado de nome de host multi-DNS assinado pelo nosso CA gerado.

[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] Configure o 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] Inicie e verifique o log de cluster

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

[4-5] Acesse a API _cat/nodes por meio de 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

Etapa 5. Prepare os usuários do Logstash em node1

[5-1] Crie logstash_write_role

Você pode criar a função de várias maneiras.

Pode criá-la usando a UI Roles do Kibana: 

Crie logstash_write_role

Ou criá-lo usando a API na guia Kibana Dev Tools:

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
    }
}

E você obterá a resposta:

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

Os usuários que têm essa função atribuída não poderão excluir nenhum documento. Essa função restringe os usuários a criar índices somente se eles começam com logstash ou indexam documentos nesses índices.

Observação para usuários do ILM: Para que logstash_writer_role funcione com o ILM (gestão de ciclo de vida do índice), habilitado por padrão na versão 7.3 e superiores, os seguintes privilégios devem ser incluídos:


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

[5-2] Crie o usuário logstash_writer (altere a senha para o usuário logstash_writer)

Você pode criar o usuário de várias maneiras.

Pode criá-lo usando a UI Users do Kibana:

Criação do usuário logstash_writer

Ou criá-lo usando a API na guia Kibana Dev Tools:

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

E você obterá a resposta:

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

Etapa 6. Habilite o TLS para o Logstash em node1

[6-1] Crie a pasta e copie os certificados

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

[6-2] Converta logstash.key no formato PKCS#8 para o plugin de entrada do Beats

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

[6-3] Configure logstash.yml

Lembre-se de usar a senha autogerada para o usuário logstash_system. Use a senha definida na etapa 2-6-4.

[root@node1 logstash]# vi logstash.yml

Edite:

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] Crie e configure conf.d/example.conf

Na saída do Elasticsearch, use a senha definida na etapa 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] Comece o Logstash com a configuração de exemplo e verifique o log do Logstash

Você deve ver as seguintes mensagens de log:

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

E na guia Monitoring do Kibana, o Logstash será exibido (informações de nó, configurações de pipeline, informações de sistema operacional, informações de JVM, estatísticas de processo e estatísticas de tempo de execução de pipeline):

Guia Monitoring do Kibana com o Logstash exibido

Etapa 7. Execute o Filebeat e configure o TLS em node1

[7-1] Crie uma pasta de configuração e copie os 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] Crie um novo filebeat.yml

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

[7-3] Edite o novo arquivo de configuração 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

Etapa 8. Use o Filebeat para fazer ingestão dos dados

[8-1] Prepare os dados de log de entrada (logstash-tutorial.log) para o Filebeat

Primeiro, faça download dos dados 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] Inicie o 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] Verifique o log

Você deve ver as seguintes mensagens de log:

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

[8-4] Crie o padrão de indexação

Crie um padrão de índice que corresponde aos dados que estão sendo ingeridos. Isso permitirá a visualização dos dados no Kibana, por exemplo, com o Graph ou o Discover.

Crie um padrão de índice no Kibana.

Selecione o nome de campo Time Filter (Filtro de tempo). Em nosso exemplo, é @timestamp:

Especifique um nome de campo Time Filter.

É isso! Você criptografou a comunicação entre diferentes partes do Elastic Stack e a maneira como está fazendo a ingestão segura dos dados de log.

E alguns comentários finais...

Em caso de problemas ao configurar a segurança, a primeira referência de ajuda que recomendamos é o guia de resolução de problemas de segurança em nossa documentação. Ele pode ajudar em relação a muitos problemas comuns. Se ainda tiver dúvidas depois disso, você deverá conferir nossos fóruns da Elastic para obter mais ajuda. Ou se quiser falar diretamente com a equipe de suporte da Elastic, comece uma assinatura da Elastic hoje mesmo e tenha acesso direto a uma equipe de especialistas. Fique seguro!