关于ES9200漏洞添加授权验证方法实践

关于ES9200漏洞添加授权验证方法实践

Elasticsearch往往存有公司大量的数据,如果安全不过关,那么就会有严重的数据安全隐患。 Elasticsearch 的安全认证方式有不少,如http-basic,search guard,shield等,本文讲的是使用Xpack进行安全认证。

1、关于http-basic也实验过,使用的是elasticSearch-http-basic提供了针对ES HTTP连接的IP白名单、密码权限和信任代理功能。可以安装elasticsearch-http-basic包,但是在Github上目前发布的是已经是7年前的版本了。而且对应es的版本也只是支持到es6.x,所以排除了http-basic这个插件包。

2、在本项目中涉及到的ES版本是7.8以及8.2。部署上线后会经由扫描系统Elasticsearch 安全漏洞(CVE-2020-7019)

image-20221115191050553

所以想使用X-Pack进行安全认证。

XPack

X-Pack是Elastic Stack扩展功能,提供安全性,警报,监视,报告,机器学习和许多其他功能。 ES7.0+之后,默认情况下,当安装Elasticsearch时,会安装X-Pack,无需单独再安装。

自6.8以及7.1+版本之后,基础级安全永久免费。

2、相关安全配置介绍

2.1、xpack.security.enabled

默认为true,启用节点上ES的XPACK安全功能,相当于总开关

2.2、xpack.security.http.ssl

这个是用来开启https的,以及对应的设置,整体配置项如下:

1
2
3
4
5
6
7
8
xpack.security.http.ssl:
enabled: false 【开启还是关闭】
verification_mode: certificate【如下】
【full:它验证所提供的证书是否由受信任的权威机构(CA)签名,并验证服务器的主机名(或IP地址)是否与证书中识别的名称匹配。】
【certificate:它验证所提供的证书是否由受信任的机构(CA)签名,但不执行任何主机名验证。】
【none:它不执行服务器证书的验证。】
truststore.path: certs/elastic-certificates.p12 【信任存储库文件的存放位置】
keystore.path: certs/elastic-certificates.p12【密钥存储库文件的存放位置】

2.3、xpack.security.transport.ssl

这个是传输层的认证设置,整体配置项如下:

1
2
3
4
5
6
7
8
xpack.security.transport.ssl:
enabled: true【开启还是关闭】
verification_mode: certificate【如下】
【full:它验证所提供的证书是否由受信任的权威机构(CA)签名,并验证服务器的主机名(或IP地址)是否与证书中识别的名称匹配。】
【certificate:它验证所提供的证书是否由受信任的机构(CA)签名,但不执行任何主机名验证。】
【none:它不执行服务器证书的验证。】
keystore.path: certs/elastic-certificates.p12【信任存储库文件的存放位置】
truststore.path: certs/elastic-certificates.p12【密钥存储库文件的存放位置】

3、ES集群认证配置

命令操作都是在ES安装根目录下执行的(这个好像不用管)

3.1、创建证书

3.1.1、创建一个证书颁发机构

提示命名文件:直接回车,默认文件名elastic-stack-ca.p12文件 提示输入密码:可以直接回车,也可以输入密码进行设置(如果这里设置密码的话,下面在给keystore和truststore设置的时候要输入密码,较为繁琐)

1
./bin/elasticsearch-certutil ca

生成如下文件:

3.1.2、为节点生成证书和私钥

提示命名文件,直接回车,默认文件名elastic-certificates.p12文件 提示输入密码:可以直接回车,也可以输入密码进行设置

1
./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

这里使用3.1.1创建的elastic-stack-ca.p12文件

3.1.3、config目录下创建certs目录
1
mkdir config/certs 
3.1.4、将文件可拷贝到certs目录下
1
mv elastic-certificates.p12 config/certs/

3.2、给keystore和truststore设置密码

keystore可以看成一个放key的库,key就是公钥,私钥,数字签名等组成的一个信息

truststore是放信任证书的一个store

truststore和keystore的性质是一样的,都是存在key的一个仓库,区别在于,truststore存放的是只包含公钥的数字证书,代表了可以信任的证书,而keystore是包含私钥的。

如果在创建证书的过程中加了密码,需要输入这个密码。每个节点都需要。执行如下:

1
./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
1
./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
1
./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
1
./bin/elasticsearch-keystore add xpack.security.http.ssl.truststore.secure_password

这样就会在config目录下生成keystore文件了

3.3、修改配置文件并重启

在config/elasticsearch.yml文件中设置并重启:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xpack.security.enabled: true


xpack.security.http.ssl:
enabled: false
verification_mode: certificate
truststore.path: certs/elastic-certificates.p12
keystore.path: certs/elastic-certificates.p12

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

3.4 创建用户密码

集群中的节点都按照上面的方式完成配置并启动后,就可以设置账号密码了,有4种方式:

a、自动创建密码

1
./bin/elasticsearch-setup-passwords auto

b、手动输入密码

1
./bin/elasticsearch-setup-passwords interactive

c、重置用户密码(随机密码)

1
./bin/elasticsearch-reset-password -u elastic

d、重置用户密码(指定密码)

1
./bin/elasticsearch-reset-password -u elastic -i <password>

这里我们设置的密码是scDEfDfTT=9k7aaA=H_m,也就是user:elastic的密码。

4、认证验证场景

这里说明一下: xpack.security.http.ssl的enable为true 就会是https,为false就是http,我这里是关掉了

4.1 浏览器访问验证、

在web页面浏览的话就是:

4.2 curl认证

当你执行curl去访问es api的时候也会提示需要进行认证。

但是加上账户密码认证授权就可以访问了:

1
curl --user elastic:scDEfDfTT=9k7aaA=H_m localhost:9200

4.3 kibana认证

kibana中配置ES中配置的kibana账号密码即可连接ES认证。

修改kibana的配置文件config/kibana.yml在配置文件中添加下面内容

1
2
3
4
elasticsearch.username: "kibana"
elasticsearch.password: "XXX"
elasticsearch.hosts: ["http://1.1.1.1:9200","http://2.2.2.2:9200","http://3.3.3.3:9200"]
server.port: 5601

重启Kibana

这里补充一个之前在介绍kibana没有记录的内容。

kibana 使用ps -ef|grep kibana是查不到进程的,因为其实运行在node里面。但是我们也不能关闭所有node里面的软件,所以我们需要查询kibana监听端口5601的进程。

使用下面命令关闭kibana

1
2
3
4
5
6
[esadmin@****** elasticsearch-7.2.0-a]$ netstat -tunlp|grep 5601
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:5601 0.0.0.0:* LISTEN 16177/bin/../node/b

[root@****** elasticsearch-7.2.0-a]# kill -9 16177

然后重启Kibana

1
nohup ./kibana &

5、另外在启动es的时候提示这样一个错误:

max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]。

解决办法如下:

1
sudo vi /etc/security/limits.conf

下面这行代码就添加到这个配置文件的末尾就好

1
2
*                soft    nofile          65536
* hard nofile 65536

然后我们再看看有没有设置好

就把当前账号退出,可以切换root就可以

在初次进入用zwyuser账户登陆的时候并不能加载该配置,但是su root后,再su zwyuser后就会加载该配置,原因并未具体深究,查阅到一篇相关的文章https://blog.csdn.net/zzddada/article/details/121701005。

6、bulk操作elasticsearch8报错解决:The bulk request must be terminated by a newline []

bulk批量操作的时候,bulk请求的时候,必须以换行符()结束,请求体是一种叫NDJSON的结构。

可以解决的办法是:

将批量操作的每一条数据先转成字符串,并在后面加上 *** 换行符,将最后所有的拼接成一个大字符串

如果想使用json文件的话,要在文件名字前面添加@符号。即 @xxx.json

curl --user elastic:scDEfDfTT=9k7aaA=H_m -XGET -H "Content-Type: application/json" '192.168.200.8:9200/policy_laoshan/_search' -d '{"query":{"bool":{"should":[{"term":{"content":{"value":"城乡"}}}]}},"from":0,"size":20},"highlight":{"pre_tags": "<span style='color:red'>","post_tags": ""}'

建筑

1
2
3
 curl --user elastic:scDEfDfTT=9k7aaA=H_m -XPOST -H "Content-Type: application/json;charset=utf-8" 'loc 
alhost:9200/policy_laoshan/_search' -d '{"query": {"match": {"content": "企业服务业"}},"highlight":{"fields":{"content":{}},"pr
e_tags":"<span style='color:red'>","post_tags":"</span>"},"from":0,"size":30}'

之前在query的时候传递的是term值,term是不具备分词功能的,这里改成了match,具备分词功能。