概述

目前,数据安全越来越得到了大家的重视,而 ElasticSearch 也在集群安全方面做了很多的工作,在本文中,我们将会主要围绕 ElasticSearch 的集群安全展开进行讲解,帮助你保护你的集群安全。

ElasticSearch 对集群安全的保护主要体现在三个方面:

  • 身份认证和鉴权
  • 集群内部通信安全
  • 集群与外部系统通信安全

下面,我们来依次展开进行说明。

身份认证和鉴权

理论说明

在 ElasticSearch 的默认安装中,其实没有提供任何的认证和鉴权功能,这也就导致了将集群暴露在了一个非常危险的处境之中。
那么,我们应该怎么开启身份认真和鉴权呢?可以采用的方案很多,此处,我们最建议的是 X-Pack 中的 Secure 模块
X-Pack 中 Secure 模块支持了 RBAC 的用户鉴权方式。
具体来看一下什么是 RBAC: Role Based Access Control,即基于角色的访问控制。展开解释一下,就是可以定义多个不同的角色,并且为每个角色分配一组不同的权限,同时,并将真实的用户添加到对应的角色中,这时,这些登录用户就具备了这些角色拥有的权限。

在 ElasticSearch 中,对权限的控制是非常精细的,既支持集群粒度的权限、也支持索引粒度的权限控制等。

同时,为了方便用户使用,ElasticSearch 中也内置了一组角色和用户,如下表所示:

用户 角色及功能描述
elastic 超级管理员用户
kibana_system 用于Kibana与ElasticSearch交互
logstash_system 用于Logstash向ES中写入数据
beats_system 用于各种Beat向ES中写入数据
apm_system 用于APM监控向ES中写入数据
remote_monitoring_user 用于MetricBeat收集和向ES中写入数据

实战篇-开启X-Pack认证与鉴权

了解了 X-Pack 中认证和鉴权的基本理论,下面,我们就来具体实战一下吧。

Step1: 修改 ElasticSearch 的配置文件,启用 X-Pack Secure 模块:

  1. xpack.security.enabled: true
  2. xpack.security.transport.ssl.enabled: true

然后重启 ElasicSearch 服务。

Step2: 创建默认的用户和分组:

  1. ./bin/elasticsearch-setup-passwords interactive
  2. # 交互式为每个用户设置对应的密码

Step3: 修改Kibana 配置文件,设置对应的ElasticSearch 的用户名和密码

  1. elasticsearch.username: "kibana_system"
  2. elasticsearch.password: "kibana_system"

然后重启Kibana,这样就可以了,服务已经正常了。

集群内部通信验证

理论说明

现在,我们已经解决了外部用户访问 ElasticSearch 时需要进行的身份验证和鉴权的功能了。
接下来,我们需要解决的是解决集群内部通信的验证。
可能你会想,为什么集群内部的通信还需要验证呢?
想一个这样的场景,如果一个黑客想要查询你的ES中的数据,那么他自己部署了一个ES实例并加入了你的集群中作为一个节点,这样,他部署的节点中的数据对他而言,其实就是完全可见的了,这是一个非常大的安全风险,而集群内部的通信认证想要解决的其实就是这个问题。

那么,集群内部应该怎么进行通信认证呢?此时就不再是用户名和密码的认证了,而是另一个常见的认证方式:TLS证书认证

对于 TLS 证书认证而言,支持三种不同的认证级别:

  • No Verification: 任何节点均可以加入,仅限于开发环境使用;
  • Certificate: 节点需要使用相同CA签发的证书;
  • Full Verification: 节点需要使用相同CA签发的证书且同时需要验证Hostname或IP地址。

实战篇 - 集群内部通信开启TLS认证

下面,我们开始给我们的集群内部通信添加TLS证书认证吧。
Step1: 生成 CA 证书
ElasticSearch 提供了一个现成的工具,可以快速生成一个 CA 证书。

  1. ./bin/elasticsearch-certutil ca

执行完成之后,可以得到一个 elastic-stack-ca.p12 文件,这就是我们的 CA 证书,接下来,我们需要为这个 CA 证书为各个节点签发证书。

Step2: 生成节点证书

  1. ./bin/elasticsearch-certutil cert --ca \
  2. --dns ${节点机器名} \
  3. --ip ${节点IP} \
  4. --out ./elastic-certificates.p12 \
  5. --ca ./elastic-stack-ca.p12

Ps: 在生成节点证书时,针对不同的节点,需要设置对应正确的机器名称和机器IP。
执行完成后,我们就可以得到由 CA 证书签发的节点可用的证书了,elastic-certificates.p12 文件。

Step3: 将节点证书放入 ElasticSearch 服务的指定目录下。

  1. mkdir config/certs
  2. cp ./elastic-certificates.p12 config/certs/

Step4: 修改 ElasticSearch 的配置文件,增加证书相关的配置:

  1. xpack.security.transport.ssl.enabled: true
  2. xpack.security.transport.ssl.verification_mode: certificate
  3. xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
  4. xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12

完成相关的配置后,重启 ElasticSearch 服务即可。
其中,verification_mode 就是我们在上述中讲解的认证级别。

集群与外部系统通信安全

理论说明

目前,我们已经完成了 ElasticSearch 的身份认证、鉴权以及集群内部通信的 HTTPS 协议通信加密。
其实,除了集群内部之外,集群与外部系统的通信理论上也应该调整为 HTTPS 协议,从而避免通信数据被抓包或劫持导致的数据泄露。

接下来,我们将讲解如何将 ElasticSearch 升级为 HTTPS 协议。

实战篇 - ElasticSearch 的 HTTPS 改造

Step1: 升级 ElasticSearch 为HTTPS 协议。
修改 ElasticSearch 的配置,增加如下配置:

  1. xpack.security.http.ssl.enabled: true
  2. xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12
  3. xpack.security.http.ssl.truststore.path: certs/elastic-certificates.p12

与集群内部通信协议类似,我们使用了同一个节点证书,将HTTP数据包进行了SSL加密。
重启服务之后就可以生效了。

此时,使用浏览器访问一下,你就可以看到 ElasticSearch 的确已经升级为了通过 HTTPS 协议进行访问了。
但是,如果你访问 Kibana 服务的话,你会发现一个 Kibana 服务已经无法正常查询数据了,这是为什么呢?因为 Kibana 还是按照 http 协议访问 ElasticSearch,导致服务已经无法正常访问了。

Step2: 修改 Kibana 通过 HTTPS 协议访问 ElasticSearch
此时,需要注意的一点是,Kibana 对证书的格式仅支持 pem 类型的格式,因此,我们首先需要将 elastic-certificates.p12 的格式转化为 pem 格式:

  1. openssl pkcs12 -in ./elastic-certificates.p12 -cacerts -nokeys -out elastic-ca.pem

此时,我们就可以得到一个 elastic-ca.pem 的证书文件了。
下面,我们将该文件放到 kibana 的 certs 目录下:

  1. cd kibana
  2. mkdir config/certs
  3. cp elastic-ca.pem config/certs/

下面,我们来修改Kibana的配置文件:

  1. elasticsearch.hosts: ["https://127.0.0.1:9200"]
  2. elasticsearch.ssl.certificateAuthorities: [ "/home/work/kibana-7.14.0-linux-x86_64/config/certs/elastic-ca.pem" ]
  3. elasticsearch.ssl.verificationMode: certificate

然后重启 kibana 即可。
这时再访问一下 Kibana 吧,服务是不是正常了!