目录
6. 配置ElasticSearch 的search-guard插件
6.6 将Search Guard语言配置在ElasticSearch中
众所周知,ElasticSearch设计之初就定位在纯私网环境而不做权限和安全控制呢。ElasticSearch如果设置不当,则存在较为严重的安全风险!有两种访问ElasticSearch的方式:使用默认端口为9300的TCP模式和使用默认端口为9200的HTTP模式。然而在同ElasticSearch服务器进行通信的过程中,通信流量是明文形式的,没有加密;更为严重的是,如果不做任何防护措施地将ElasticSearch暴露在公网上,那么对它的访问将没有任何安全认证,任何连接到服务器端口上的人,都可以调用相关API对服务器上的数据进行任意的增删改查。
安全策略网络层除却“内鬼”的因素,攻击基本都是通过外部网络,所以这里是保障ElasticSearch安全的第一道屏障。相信大家都有自己的网络安全策略,硬件防火墙也好,软件防火墙也罢,按照自己的需求做好设置和维护即可。
所以要避免黑客入侵的最有力的手段,也是最后一层屏障,那就是用户及权限认证。ElasticSearch本身没有用户及权限认证体系,虽然官方提供了自己的权限管理系统—— Shield, 但是它——收费!本篇文章就是介绍如何使用Search Guard对ElasticSearch集权做权限认证。
1. 背景
ElasticSearch集群在暴露了一个节点的IP和端口就可以对整个集群进行各种操作,删索引、改数据等。在重要的项目应用中,需要防范这一点。
目前常见的安全防范方式有:
- X-Pack ElasticSearch Security,收费License
- Search Guard,免费开源
2. 软件介绍
2.1 ElasticSearch
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
ElasticSearch使用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
2.2 Search Guard
Search Guard是ElasticSearch的安全插件,它支持ES客户端认证、后端系统授权,并增加审计日志,提供文档/字段级别的安全保障。
Search Guard中,所有的基础安全特性都是免费的,但如果想在商业项目中使用一些企业级安全特性,需要付费得到Search Guard的官方授权。
- 基础特性:
- 节点-节点间的加密(SSL/TSL)
- 安全的REST访问(HTTPS)
- 灵活的REST访问控制(User/Role; aliases&indices&types)
- HTTP基础认证
- HTTP代理认证
- HTTP SSL/CLIENT-CERT认证
- XFF支持
- 内部认证/授权
- 匿名登录/未经验证的访问
- 用户模仿
- 企业级特性:
3. 架构规划
- 操作系统:CentOS 6.8
- ElasticSearch 6.5.4
- Search Guard 25.1
- 主机地址:*.*.*.1(node-1)、*.*.*.2(node-2)、*.*.*.3(node-3)
4. 软件下载地址
- Elasticsearch:https://www.elastic.co/downloads
- Search Guard:https://github.com/floragunncom/search-guard/tree/es-6.5.4
5. 搭建ElasticSearch集群
5.1 上传软件包并解压缩
使用FTP工具上传elasticsearch-6.5.4.zip至~目录。使用以下命令解压缩:
[node-1@localhost ~]$ tar -zxvf elasticsearch-6.5.4.zip |
5.2 同步时间
三个节点都需要执行:
[node-1@localhost ~]$ ntpdate time.windows.com |
5.3 开放ElasticSearch端口
三个节点都需要执行:
(1)检查防火墙是否打开:
firewall-cmd –state |
如果防火墙是关闭的,跳过该步骤。
(2)开放Elasticsearch必要的端口:
开放9200端口:
firewall-cmd --zone=public --permanent --add-port=9200/tcp |
开放9300端口
firewall-cmd --zone=public --permanent --add-port=9300/tcp |
(3)重启防火墙:
firewall-cmd –reload |
5.4 修改系统参数
(1)修改/etc/sysctl.conf文件:
vim /etc/sysctl.conf编辑文件,加入以下内容:
# 开启对于TCP时间戳的支持,若该项设置为0,则下面一项设置不起作用 net.ipv4.tcp_timestamps = 1 # 表示开启TCP连接中TIME-WAIT sockets的快速回收 net.ipv4.tcp_tw_recycle = 1 # 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭 net.ipv4.tcp_syncookies = 1 # 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 net.ipv4.tcp_tw_reuse = 1 # 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间 net.ipv4.tcp_fin_timeout = 30 vm.max_map_count=655360 |
然后执行 /sbin/sysctl -p 让参数生效。
(2)修改/etc/security/limits.conf文件
/etc/security/limits.conf 文件修改内容如下: * hard nofile 65536 * soft nofile 65536 |
5.5 创建ElasticSearch用户
es 规定 root 用户不能启动 es,所以需要创建一个用户来启动 es:
# 创建用户名为 es 的用户 useradd es # 设置 es 用户的密码 passwd es #pass:123456 # 将 ~/elasticsearch-6.5.4 的拥有者设置为 es chown -R es:es ~/elasticsearch-6.5.4 |
5.6 修改ElasticSearch参数
三个节点都需要执行:
5.6.1 node-1节点
vim ~/elasticsearch-6.5.4/config/elasticsearch.yml
cluster.name: YOUR_CLUSTER_NAME node.name: node-1 network.host: *.*.*.1 #默认访问端口 #http.port: 9200 #集群主机互相访问地址 discovery.zen.ping.unicast.hosts: ["*.*.*.2", "*.*.*.3"] #防止脑裂 discovery.zen.minimum_master_nodes: 2 #锁定物理内存 #bootstrap.memory_lock: true #以下head插件用(可选) http.cors.enabled: true http.cors.allow-origin: "*" indices.fielddata.cache.size: 20% |
5.6.2node-2节点
vim ~/elasticsearch-6.5.4/config/elasticsearch.yml
cluster.name: YOUR_CLUSTER_NAME node.name: node-2 network.host: *.*.*.2 #默认访问端口 #http.port: 9200 #集群主机互相访问地址 discovery.zen.ping.unicast.hosts: ["*.*.*.1", "*.*.*.3"] #防止脑裂 discovery.zen.minimum_master_nodes: 2 #锁定物理内存 #bootstrap.memory_lock: true #以下head插件用(可选) http.cors.enabled: true http.cors.allow-origin: "*" indices.fielddata.cache.size: 20% |
5.6.3node-3节点
vim ~/elasticsearch-6.5.4/config/elasticsearch.yml
cluster.name: YOUR_CLUSTER_NAME node.name: node-3 network.host: *.*.*.3 #默认访问端口 #http.port: 9200 #集群主机互相访问地址 discovery.zen.ping.unicast.hosts: ["*.*.*.1", "*.*.*.2"] #防止脑裂 discovery.zen.minimum_master_nodes: 2 #锁定物理内存 #bootstrap.memory_lock: true #以下head插件用(可选) http.cors.enabled: true http.cors.allow-origin: "*" indices.fielddata.cache.size: 20% |
5.7启动ElasticSearch
三个节点都需要执行:
(1)切换到 es 用户,启动 es。因为非root用户所以不需要切换用户。
su es |
(2)前台启动:
进入到~/elasticsearch-6.5.4目录,执行:
./bin/elasticsearch |
(3)后台启动:
进入到~/elasticsearch-6.5.4目录,执行:
./bin/elasticsearch -d |
(4)关闭后台启动:
ps -ef | grep elasticsearch kill -9 [进程号] |
5.8验证集群是否搭建成功
浏览器打开http://*.*.*.1:9200/_cat/nodes,如下图所示,表示成功:
6. 配置ElasticSearch 的search-guard插件
6.1 上传插件包
使用FTP工具上传search-guard-6-6.5.4-25.1.zip至~目录。
6.2安装Search Guard
三个节点都需要执行:
[node-1@localhost ~]$ cd ~/elasticsearc-6.5.4 [node-1@localhost elasticsearc-6.5.4]$ ./bin/elasticsearch-plugin install -b file:///yourPath/search-guard-6-6.5.4-25.1.zip |
命令执行后,显示如下图说明插件安装成功:
6.3在线生成Search Guard证书
Search Guard需要证书才可以,生成证书有两种方式,一个是人工手动生成,这个复杂麻烦,另一种就是观望那个提供的在线生成,这里使用了后面一种在线生成。官网在线生成证书连接:https://search-guard.com/tls-certificate-genertor/。
Email用来接收密钥,Organization Name随意填写,HostName填写ElasticSearch集群中每个节点的Node Name,这是一一对应的,这里我们有三个节点,Node Name为node-1、node-2、node-3。
6.4创建证书目录
三个节点都需要执行:
在~/elasticsearch-6.5.4/config目录下创建key目录:
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/config/ [node-1@localhost config]$ mkdir key |
6.5上传证书文件
三个节点都需要执行:
将邮箱中收到的密钥文件上传至服务器的~/elasticsearch-6.5.4/config/key目录下再解压,删除证书的压缩文件。
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/config/key/ [node-1@localhost key]$ tar -zxvf search-guard-certificates-8fc55817-572a-4ae2-8c5d-920ea7bffc77.tar.gz [node-1@localhost key]$ rm -rf search-guard-certificates-8fc55817-572a-4ae2-8c5d-920ea7bffc77.tar.gz |
6.6将Search Guard语言配置在ElasticSearch中
三个节点都需要执行:
修改elasticsearch.yml增加下面的内容:
[node-1@localhost ~]$ vim elasticsearch-6.5.4/config/elasticsearch.yml searchguard.ssl.transport.pemcert_filepath: key/search-guard-certificates/node-certificates/CN=node-1.crtfull.pem searchguard.ssl.transport.pemkey_filepath: key/search-guard-certificates/node-certificates/CN=node-1.key.pem searchguard.ssl.transport.pemkey_password: 43fee506c0417aadc16f searchguard.ssl.transport.pemtrustedcas_filepath: key/search-guard-certificates/chain-ca.pem searchguard.ssl.transport.enforce_hostname_verification: false searchguard.ssl.http.enabled: false searchguard.ssl.http.pemcert_filepath: key/search-guard-certificates/node-certificates/CN=node-1.crtfull.pem searchguard.ssl.http.pemkey_filepath: key/search-guard-certificates/node-certificates/CN=node-1.key.pem searchguard.ssl.http.pemkey_password: 43fee506c0417aadc16f searchguard.ssl.http.pemtrustedcas_filepath: key/search-guard-certificates/chain-ca.pem searchguard.authcz.admin_dn: - CN=sgadmin searchguard.audit.type: internal_elasticsearch searchguard.enable_snapshot_restore_privilege: true searchguard.check_snapshot_restore_write_privileges: true searchguard.restapi.roles_enabled: ["sg_all_access"] cluster.routing.allocation.disk.threshold_enabled: false node.max_local_storage_nodes: 3 xpack.security.enabled: false |
注意:
上面pemkey_password属性可以在下载的密钥包中README.txt文件中查看到,pemkey_password和各个节点是对应的。
启动ElasticSearch,如果没有报错,就继续往下走,如果报错,则仔细检查每一步。
6.7设置权限因子
在其中任意一个节点执行,本次以node-1节点为例:
将sgadmin客户端证书密钥复制到插件目录下,并执行./sgadmin.sh命令:
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/config/key/search-guard-certificates/ [node-1@localhost search-guard-certificates]$ cp root-ca.pem client-certificates/CN=sgadmin.key.pem client-certificates/CN=sgadmin.crtfull.pem ../../../plugins/search-guard-6/tools/ [node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/plugins/search-guard-6/tools/ [node-1@localhost tools]$ chmod 744 sgadmin.sh [node-1@localhost tools]$ ./sgadmin.sh -cacert root-ca.pem -cert CN=sgadmin.crtfull.pem -key CN=sgadmin.key.pem -keypass dd31f987ec32f906e37d -nhnv -icl -cd ../sgconfig/ -nhnv -icl -cd ../sgconfig/ -h *.*.*.1 |
执行之后界面显示如下,则启动成功:
6.8验证
浏览器打开http://*.*.*.1:9200,提示输入用户名,密码,则安装成功。如下图所示:
默认的Search Guard用户名为admin,密码为admin。
至此,ElasticSearch集群集成Search Guard插件配置完成。
7. Search Guard的相关配置
7.1 修改管理用密码
安装完ElasticSearch之后会有一个默认的用户admin密码也为admin,该用户无法删除无法编辑修改密码,用于生产时安全性较差,需要修改默认密码或者删除该admin用户。
以下步骤只需要在三台节点中的任意节点中执行,本次以node-1节点为例。
7.1.1使用工具生产加密密码
执行以下命令,即可生成加密的密码:
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/plugins/search-guard-6/tools/ [node-1@localhost tools]$ chmod 744 hash.sh [node-1@localhost tools]$ ./hash.sh -p ***** |
执行之后显示如下:
最下面一行就是生成的加密密码,明文密码为***的加密密码为$2y$12$Vnp7cWPFeCo/Os8GQRKWduAAcZd88ZH13Ahh3zKlk5Xg1iQpvJPMe。
7.1.2修改配置文件
复制生成的加密密码,修改~/elasticsearch-6.5.4/plugins/search-guard-6/sgconfig/sg_internal_users.yml文件。
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/plugins/search-guard-6/sgconfig/ [node-1@localhost sgconfig]$ vim sg_internal_users.yml #password is: admin admin: # 修改readonly为false readonly: false # 替换hash hash: $2y$12$Vnp7cWPFeCo/Os8GQRKWduAAcZd88ZH13Ahh3zKlk5Xg1iQpvJPMe roles: - admin attributes: #no dots allowed in attribute names attribute1: value1 attribute2: value2 attribute3: value3 |
7.1.3设置生效
执行以下命令,使设置的密码生效:
[node-1@localhost ~]$ cd ~/elasticsearch-6.5.4/plugins/search-guard-6/tools/ [node-1@localhost tools]$ ./sgadmin.sh -cacert root-ca.pem -cert CN=sgadmin.crtfull.pem -key CN=sgadmin.key.pem -keypass dd31f987ec32f906e37d -nhnv -icl -cd ../sgconfig/ -nhnv -icl -cd ../sgconfig/ -h *.*.*.1 |
执行命令之后,显示如下,说明密码修改成功:
[node-1@localhost tools]$ ./sgadmin.sh -cacert root-ca.pem -cert CN=sgadmin.crtfull.pem -key CN=sgadmin.key.pem -keypass dd31f987ec32f906e37d -nhnv -icl -cd ../sgconfig/ -nhnv -icl -cd ../sgconfig/ -h *.*.*.1 -p 9300 Search Guard Admin v6 Will connect to localhost:9300 ... done Elasticsearch Version: 6.5.4 Search Guard Version: 6.5.4-25.1 Connected as CN=sgadmin Contacting elasticsearch cluster 'elasticsearch' and wait for YELLOW clusterstate ... Clustername: CollectorDBCluster Clusterstate: YELLOW Number of nodes: 3 Number of data nodes: 3 searchguard index already exists, so we do not need to create one. Populate config from ../elasticsearch-6.5.4/plugins/search-guard-6/sgconfig Will update 'sg/config' with ../sgconfig/sg_config.yml SUCC: Configuration for 'config' created or updated Will update 'sg/roles' with ../sgconfig/sg_roles.yml SUCC: Configuration for 'roles' created or updated Will update 'sg/rolesmapping' with ../sgconfig/sg_roles_mapping.yml SUCC: Configuration for 'rolesmapping' created or updated Will update 'sg/internalusers' with ../sgconfig/sg_internal_users.yml SUCC: Configuration for 'internalusers' created or updated Will update 'sg/actiongroups' with ../sgconfig/sg_action_groups.yml SUCC: Configuration for 'actiongroups' created or updated Done with success |