背景
主搜几个集群发生过删库,继而引发大规模的数据修复重建,浪费了开发、运维同学的大量时间精力。为了能从访问上对人员的操作进行限制和记录,需要引入对ES集群进行权限校验的机制。
思路
- 开启ES本身的权限校验及相关配置
- 接入Ldap的权限校验体系
- migrate所有应用中的ES链接创建方式
- 通过公用的cerebro和kibana对ES集群进行访问
实施路径
ES集群
- 在配置文件中开启包括集群SSL、安全性认证等在内的配置
- 需要通过统一的认证中心生成证书
- 根据需要设置不同权限的用户组
- 为每个既存应用创建对应的账号密码
- 接入Ldap权限体系,对个人的访问进行验证
- 给ES集群的Master节点添加SLB对所有流量进行监控和记录
应用
- 创建时注册应用专用的账号密码
- 修改原有ES链接代码,添加安全认证部分
- 新应用构建时通过配置中心 + 安全认证的方式进行链接建立
个人
- 从直接使用变成通过Ldap认证的方式进行登入
- 通过统一的客户端对ES集群进行使用
主要milestone
- ES权限部分使用的调研
- 开启和接入方式
- 不同权限组的使用范围
- client连接方式的修改sample
- Ldap的接入
- 既存系统的改造
- 配置的引入
- client的修改
- 服务的迁移和测试
实际操作
- 修改ES配置文件
$ES_HOME/config/elasticsearch.yml
,添加以下配置并重启- xpack.monitoring.collection.enabled=true
- xpack.security.enabled=true
- xpack.security.transport.ssl.enabled=true
- 创建证书(参考)
- 登陆任意一个节点,找到
ES
的bin
目录 - 运行命令
/bin/elasticsearch-certutil ca
- 一路
y
- 生成文件
elastic-stack-ca.p12
- 一路
- 运行命令
./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
- 一路
y
- 生成文件
elastic-certificates.p12
- 把这个文件拷贝到所有节点的
config
目录里
- 一路
- 登陆任意一个节点,找到
- 创建账号密码
- 登陆任意一个节点,找到
ES
的bin
目录 - 运行命令
./bin/elasticsearch-setup-passwords auto
自动生成密码,或者./bin/elasticsearch-setup-passwords interactive
手动填写密码 - 主要记得两个账户的密码,
kibana
和elastic
,一个用来连接和认证 kibana,一个是整个集群的superuser
超级管理员
- 登陆任意一个节点,找到
- 修改ES配置文件
$ES_HOME/config/elasticsearch.yml
,添加以下配置并重启- xpack.security.transport.ssl.keystore.type=PKCS12
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.keystore.path=elastic-certificates.p12
- xpack.security.transport.ssl.truststore.path=elastic-certificates.p12
- xpack.security.transport.ssl.truststore.type=PKCS12
- (可选)修改
Kibana
配置文件$KIBANA_HOME/config/kibana.yml
并重启。主要修改password
字段,改成上面生成的密码- elasticsearch.username: kibana
- elasticsearch.password: changeme
- 通过
elastic
账号密码登陆ES进行后续配置 - 禁用无用的账户
PUT /_security/user/$USER_NAME/_disable
curl -XPUT http://elastic@$elastic_pwd:$ES_URL:9200/_security/user/$USER_NAME/_disable
- 创建需要的账户
- Kibana
POST /_security/user/ccy_test_1 { "password" : "ccy_test_1", "roles" : [ "ccy_test_1" ], "metadata" : { "description":"ccy service account" } }
- 命令行
curl -XPOST 'http://elastic@$ELASTIC_PWD:$ES_URL:9200/_security/user/$SERVICE_USER' \ -H 'Content-Type: application/json' \ -d '{· "password" : "$SERVICE_USER", "roles" : [ "$SERVICE_ROLE" ], "metadata" : { "description":"ccy service account" } }'
- Kibana
- 创建需要的权限
- Kibana
POST /_security/role/ccy_test_1 { "indices": [ { "names": [ "ms_ccy_*" ], "privileges": [ "read", "write", "create", "delete", "create_index", "index" ] } ], "metadata": { "description":"ccy service account role" } }
- 命令行
curl -XPOST 'http://elastic@$ELASTIC_PWD:$ES_URL:9200/_security/role/$SERVICE_ROLE' \ -H 'Content-Type: application/json' \ -d '{ "indices": [ { "names": [ "$INDEX_PATTERN" ], "privileges": [ "read", "write", "create", "delete", "create_index", "index" ] } ], "metadata": { "description":"ccy service account role" } }'
- Kibana
- 给账号指定
服务端升级
- 用服务的appid注册账号密码(运维维护)
JavaClient
构建的时候添加以下代码
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
...
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ES_USER, ES_PWD));
RestClientBuilder builder = RestClient.builder(httpHosts)
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider))
;