前言
公司有一台外网的测试服务器安装了elasticsearch
7.17集群,其中一个容器使用默认的端口9200
,而且还没有设置密码。虽然没什么重要数据,但还是被攻击了。集群全部的索引都被删除了,增加了一个名为read-me
的索引,打开看到里面的内容是:转0.01比特币(BTC)给指定地址,并发邮件通知才能找回数据。虽然我不会花钱给攻击者的,但是elasticsearch
的安全问题还是需要重视的。我使用了以下的策略或方法:
一、不使用默认的端口
1.1 修改默认的端口
9200、9300最好改为其他端口,防止恶意软件按端口扫描到。在elasticsearch.yml中增加配置项:
http.port: 9202
transport.port: 9302
1.2 安装包运行
如果是手动下载wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.4-linux-x86_64.tar.gz 压缩包,并解压后运行的。可以在防火墙中配置内网访问或者白名单来限制访问。
配置白名单命令如下,将
修改成你的白名单地址。可以改为不同的IP地址多次执行:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="/32" accept'
firewall-cmd --reload
1.3 容器内运行
如果是在docker
或podman
容器内运行的话,默认外网总是能访问到elasticsearch的映射端口,firewalld
防火墙配置也不起作用,这比较麻烦。
解决办法是:在运行容器的时候不加映射端口参数-p 9202:9200 -p 9302:9300
,并且用固定IP地址运行,这样外网是访问不到各容器的9200和9300端口的,集群参数就配置内网的固定IP。运行容器时固定IP地址的命令如下:
# 查看桥接网络的默认网关,我查出的结果是:172.17.0.1
docker network inspect bridge|grep Gateway
# 运行时指定IP:172.17.0.101(与网关地址的前面一致)
docker run -d --network bridge --ip 172.17.0.102 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e TZ=Asia/Shanghai --privileged -v /opt/es/test/es2.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /opt/es/test/data:/usr/share/elasticsearch/data --name es2 elasticsearch:7.17.4
# 同样,如果是podman命令如下:
podman network inspect podman|grep gateway
sudo podman run -d --network podman --ip 10.88.0.103 -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e TZ=Asia/Shanghai --privileged -v /opt/es/test3/es3.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /opt/es/test3/data:/usr/share/elasticsearch/data --name es3 elasticsearch:7.17.4
详细用法可以参考这篇文章:https://www.jianshu.com/p/58e207a675e7
用类似172.17.0.102这样的内网IP地址的9200和9300来配置集群和kibana访问。
如果你不想安装kibana,想临时从外网访问容器来测试怎么办?
其实也可以配置一下防火墙,来做端口转发:
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-forward-port=port=9202:proto=tcp:toaddr=172.17.0.102:toport=9200 --permanent
firewall-cmd --reload
试了下开通了之后就可以通过宿主机的9202端口来访问了,但是不能配置白名单,意味着所有人都能访问这个端口了。网上查找了很久,也没有解决方案,所以建议还是用kibana来访问,不要开通9202端口。
二、配置Elastic Search密码和集群证书
因为不同版本的配置会不一样,我主要还是参照官方的文档来做:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-basic-setup.html
2.1 生成证书
以下两个命令,可以输入证书密码,但要自己保存下来。文件名就直接回车用默认的即可。
./elasticsearch-certutil ca
./elasticsearch-certutil cert --ca elastic-stack-ca.p12
可以在任意一个节点生成,生成完成之后把两个.p12文件(elasticsearch的根目录下)复制到所有集群节点config目录下。另外在每一个集群节点都执行下面的语句:
./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
运行时,可能需要输入之前的证书密码。
2.2 修改Elastic Search配置文件
所有集群节点,编辑elasticsearch.yml
加入以下内容:
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.client_authentication: required
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
然后全部重启,如果启动失败,先删除data目录下的数据后再重启。
2.3 设置密码
保证全部节点都正常启动了,然后在任意一个节点下面运行下面的密码设置各个系统默认用户的密码。
./elasticsearch-setup-passwords interactive
注意:elastic
为超级管理员,密码一定要记得。
kibana_system
为kibana
配置文件中用到的账号,权限较低。
其他用户密码可以随便设置,后面可以kibana中修改密码。
2.4 配置Kibana
编辑kibana.yml
文件加入以下配置项:
elasticsearch.username: "kibana_system"
然后再执行下面两条命令:
./kibana-keystore create
./kibana-keystore add elasticsearch.password
注意上面的命令要输入前面设置的kibana_system用户的密码,其实就是将密码加密后保存在文件中。比直接明文写在kibana.yml
中要更安全些。
三、Kibana配置为网站子目录访问
Kibana
默认端口为5601
,多暴露一个端口就多一分危险;配置到网站的子目录中,还能更方便在浏览器地址栏中输入访问。编辑kibana.yml
文件加入以下配置项:
server.basePath: "/kibana"
然后nginx.conf中加入以下配置:
location /kibana {
proxy_pass http://127.0.0.1:5601/;
rewrite ^/kibana/(.*)$ /$1 break;
}
最后,重启Kibana
和Nginx
即可。