概述
目前,数据安全越来越得到了大家的重视,而 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 模块:
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
然后重启 ElasicSearch 服务。
Step2: 创建默认的用户和分组:
./bin/elasticsearch-setup-passwords interactive
# 交互式为每个用户设置对应的密码
Step3: 修改Kibana 配置文件,设置对应的ElasticSearch 的用户名和密码
elasticsearch.username: "kibana_system"
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 证书。
./bin/elasticsearch-certutil ca
执行完成之后,可以得到一个 elastic-stack-ca.p12 文件,这就是我们的 CA 证书,接下来,我们需要为这个 CA 证书为各个节点签发证书。
Step2: 生成节点证书
./bin/elasticsearch-certutil cert --ca \
--dns ${节点机器名} \
--ip ${节点IP} \
--out ./elastic-certificates.p12 \
--ca ./elastic-stack-ca.p12
Ps: 在生成节点证书时,针对不同的节点,需要设置对应正确的机器名称和机器IP。
执行完成后,我们就可以得到由 CA 证书签发的节点可用的证书了,elastic-certificates.p12 文件。
Step3: 将节点证书放入 ElasticSearch 服务的指定目录下。
mkdir config/certs
cp ./elastic-certificates.p12 config/certs/
Step4: 修改 ElasticSearch 的配置文件,增加证书相关的配置:
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
完成相关的配置后,重启 ElasticSearch 服务即可。
其中,verification_mode 就是我们在上述中讲解的认证级别。
集群与外部系统通信安全
理论说明
目前,我们已经完成了 ElasticSearch 的身份认证、鉴权以及集群内部通信的 HTTPS 协议通信加密。
其实,除了集群内部之外,集群与外部系统的通信理论上也应该调整为 HTTPS 协议,从而避免通信数据被抓包或劫持导致的数据泄露。
接下来,我们将讲解如何将 ElasticSearch 升级为 HTTPS 协议。
实战篇 - ElasticSearch 的 HTTPS 改造
Step1: 升级 ElasticSearch 为HTTPS 协议。
修改 ElasticSearch 的配置,增加如下配置:
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12
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 格式:
openssl pkcs12 -in ./elastic-certificates.p12 -cacerts -nokeys -out elastic-ca.pem
此时,我们就可以得到一个 elastic-ca.pem 的证书文件了。
下面,我们将该文件放到 kibana 的 certs 目录下:
cd kibana
mkdir config/certs
cp elastic-ca.pem config/certs/
下面,我们来修改Kibana的配置文件:
elasticsearch.hosts: ["https://127.0.0.1:9200"]
elasticsearch.ssl.certificateAuthorities: [ "/home/work/kibana-7.14.0-linux-x86_64/config/certs/elastic-ca.pem" ]
elasticsearch.ssl.verificationMode: certificate
然后重启 kibana 即可。
这时再访问一下 Kibana 吧,服务是不是正常了!