一、介绍
Elasticsearch本身没有用户及权限认证体系。虽然官方提供了自己的权限管理系统 – Shield, 但是它——收费! 所以在这里给大家介绍一款实用的开源Elasticsearch权限管理系统——Search Guard。
Shield 现在已经被 X-pack 集成,另外 X-pack 还集成了 Watcher,Marvel,Graph 和 reporting。X-pack 就是一个大合集,便于安装,不用为版本兼容性犯愁,可以灵活 disable/enable 其中的各个组件。他还多干了一件事儿,可以监控 Logstash。如今 X-Pack 已经作为 Elastic 公司单独的产品线。
在 Elasticsearch 6.3.2 版本中,已经集成了 X-Pack ,虽然 ES 团队已经对 X-Pack 开源,但是在该版本中如果需要使用到安全加密功能,依然还是需要付费购买License,
官方对于Search Guard的简单说明:Search Guard可用于通过使用不同的行业标准身份验证技术来保护你的Elasticsearch集群,例如Kerberos,LDAP/Active Directory,JSON Web Token,TLS证书和代理身份验证/SSO。概括一下就是你能用到的身份验证模式它都支持,并且还支持细粒度权限控制。对于Search Guard的功能及工作机制,官方这个图画的其实很简单明了。
先来看看Search Guard都支持哪些功能及特性,Search Guard也分社区版和企业版,但这里只简单说一下社区版所支持功能,具体社区版及企业版对比参考官方文档:
1. Search Guard支持Transport Layer(Node-to-node)和REST Layer(HTTP/HTTPS)的SSL/TLS加密传输,并且Transport Layer和REST Layer都可以单独配置是否开启SSL/TLS加密。
2. Search Guard提供了一套完整的“用户-角色-权限”控制系统。免费版权限可以控制到indice/type、host级别。
3. 如果需要Document level security(DLS)和Field level security(FLS)级别的权限控制,或者Audit logging审计功能,或者需要支持如LDAP、Kerberos等第三方用户认证系统的话,那就乖乖购买Enterprise License吧(每个集群一个License,无所谓集群规模)。
补充一点,Search Guard可以实现和Logstash、Kibana的完美结合(本文是以Elasticsearch 6.4为基础),对于使用ELK的用户大可不必担心,修改很容易的。
二、安装
先决条件
确保对JVM的支持
- 只支持 OpenJDK 7/8 或者 Oracle JVM 7/8
- 不支持 IBM VM 或者其他 JVM供应商
生成所有必需的TLS证书
确保你所有的节点都有TLS证书和至少一个管理证书,如果你已经拥有PKI基础结构,则通常通过向PKI发出证书签名请求来获取所需的证书即可。如果不是这种情况,那么你可以使用以下方式来生成证书(选择一种生产安全证书生成方式即可):
- Use the Search Guard demo installation script (not safe for production)
- Download the Search Guard demo certificates (not safe for production)
- Use the Online TLS generator service (not safe for production)
- Use the Offline TLS Tool (safe for production)
- Use and customize the example PKI scripts (safe for production)
- Create a CSR and send it to your existing PKI infrastructure, if any (safe for production)
- Using tools like OpenSSL and/or keytool (safe for production)
对于你想生产的典型安装方式:
- 每个节点一个TLS证书
- 一个管理证书
当然也可以在每个节点上使用相同的证书,但由于你无法使用Search Guard的主机名验证和DNS查找功能来检查TLS证书的有效性,因此安全性较低。
我这里选择 example PKI scripts 方式来生成证书【此步骤可选】。建议你先略过这里,直接使用 Search Guard demo certificates 方式来启动集群,下载就可以使用,证书都已经在里面了。
我这里也说一下 example PKI scripts 方式,生产安全可用的。首先将 Search Guard SSL 源代码下载到你的计算机上,你可以克隆Git库,也可以将其下载为zip文件。存储库位于:
要执行的脚本是 ./example.sh,位于 example-pki-scripts 文件夹中。你可能需要在执行文件之前 chmod a+x 该文件。
如果执行成功,你将在 example-pki-scripts 文件夹中找到生成的文件和文件夹。如果由于其他原因需要重新执行脚本,请首先在同一目录中执行 ./clean.sh。这将自动删除所有生成的文件。
该脚本以 PEM,P12 and JKS 格式生成证书,你可以使用其中一个来运行 Search Guard。推荐的格式是 PEM。
生成以下主要证书:
Node certificates:
- node-0-signed.pem / node-0.key.pem
- node-1-signed.pem / node-1.key.pem
- node-2-signed.pem / node-2.key.pem
Admin certificate:
- kirk.crtfull.pem / kirk.key.pem
Client certificate:
- spock.crtfull.pem / spock.key.pem
要将 kirk 证书配置为管理员证书,请将以下条目添加到 elasticsearch.yml:
1 2 |
searchguard.authcz.admin_dn: - CN=kirk,OU=client,O=client,L=Test,C=DE |
另外,该脚本还为 Kibana,logstash 和 Beats 生成证书。这些可用于保护所述工具和Elasticsearch之间的连接,这是可选的,但更安全。
所有私钥和密钥库文件的密码都是 changeit。可在 example.sh 脚本中修改。
用于签署证书的根 CA 和签名 CA 可以在 example-pki-scripts/ca 文件夹中找到。
自定义证书
如果需要自定义示例PKI脚本生成的证书,则以下是相关文件:
1 2 |
example-pki-scripts/etc/root-ca.conf example-pki-scripts/etc/signing-ca.conf |
使用证书链生成示例证书。它由根CA,签名CA和实际证书组成。上述两个文件定义了根CA和签名CA的配置,尤其是 Distinguished Name(DN)。你可以在以下部分中更改DN:
1 2 3 4 5 6 |
[ ca_dn ] 0.domainComponent = "com" 1.domainComponent = "example" organizationName = "Example Com Inc." organizationalUnitName = "Example Com Inc. Root CA" commonName = "Example Com Inc. Root CA" |
要自定义生成的节点,管理员和客户端证书的DN,请修改以下文件:
1 2 3 4 5 |
# 生成节点证书 gen_node_cert.sh # 生成客户端证书, 此脚本生成的证书也可用作管理员证书 gen_client_node_cert.sh |
你可以通过修改相应文件中的以下部分来更改生成的证书的DN,主机名和IP:
1 2 |
-dname "CN=$NODE_NAME.example.com, OU=SSL, O=Test, L=Test, C=DE" \ -ext san=dns:$NODE_NAME.example.com,dns:localhost,ip:127.0.0.1,oid:1.2.3.4.5.5 |
对于 gen_node_cert.sh 脚本,请确保保留 oid:1.2.3.4.5.5 部分!此OID值用于标识群集中的节点证书。
首次在群集上安装 Search Guard 后,需要重新启动整个群集。TLS 加密在 Elasticsearch 的传输层(transport layer)上是必需的,因此所有节点必须安装 Search Guard 才能相互通信。如果你已安装 Search Guard 并想要升级,请按照升级说明进行操作。
生产 Elasticsearch 群集上的第一次安装过程如下:
1. 禁用分片分配
此步骤是可选的,但推荐用于具有大量数据的大型群集。此步骤可确保在重新启动群集时不会移动分片,从而导致大量I/O。也可以看看https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html。
1 2 3 4 5 6 7 8 |
curl -Ss -XPUT 'https://localhost:9200/_cluster/settings?pretty' \ -H 'Content-Type: application/json' -d' { "persistent": { "cluster.routing.allocation.enable": "none" } } ' |
2. 停止所有节点
这一步没什么特别的,就是关闭所有 ES 节点即可。
3. 所有节点安装 Search Guard 插件
可以使用 elasticsearch-plugin 命令像安装其他 Elasticsearch 插件一样安装 Search Guard。
切换到 Elasticsearch 安装目录并输入:
1 |
bin/elasticsearch-plugin install -b com.floragunn:search-guard-6:<version> |
比如:
1 |
bin/elasticsearch-plugin install -b com.floragunn:search-guard-6: |
将上面示例中的版本号替换为与你的 Elasticsearch 安装相匹配的确切版本号。为 Elasticsearch 6.3.0 构建的插件不能在 Elasticsearch 6.2.4 上运行,反之亦然。可以在 Search Guard Version Matrix page 上找到所有可用 Search Guard 版本的概述。
安装完成后,你会在 Elasticsearch 安装的插件目录中看到名为 search-guard-6 的文件夹。
也支持离线安装,首先下载与你的 Elasticsearch 版本匹配的 Search Guard 版本,zip文件。切换到 Elasticsearch 安装目录并输入:
1 |
bin/elasticsearch-plugin install -b file:///path/to/search-guard-6-<version>.zip |
4. 添加 TLS configure 到 elasticsearch.yml 文件
最低限度的 Search Guard 配置包括传输层(transport layer)上的 TLS 设置和至少一个用于初始化 Search Guard 索引的管理证书。
这是在 elasticsearch.yml 中配置,指定证书的路径必须位于 Elasticsearch config 目录下,使用相对路径指定,这是必须的(也就是要把相关证书复制到 config 目录下):
1 2 3 4 5 6 7 8 |
searchguard.ssl.transport.pemcert_filepath: <path_to_node_certificate> searchguard.ssl.transport.pemkey_filepath: <path_to_node_certificate_key> searchguard.ssl.transport.pemkey_password: <key_password (optional)> searchguard.ssl.transport.pemtrustedcas_filepath: <path_to_root_ca> searchguard.ssl.transport.enforce_hostname_verification: <true | false> searchguard.authcz.admin_dn: - CN=kirk,OU=client,O=client,L=test, C=de |
searchguard.ssl.transport.pem* 定义了相对于 Elasticsearch config 目录的节点证书的路径。
你可以在 GitHub 上找到包含所有选项的示例配置模板。
我这里使用的是 example PKI scripts 证书,所以我的配置如下:
1 2 3 4 5 |
xpack.security.enabled: false searchguard.ssl.transport.pemcert_filepath: node-0-signed.pem searchguard.ssl.transport.pemkey_filepath: node-0.key.pem searchguard.ssl.transport.pemtrustedcas_filepath: chain-ca.pem searchguard.ssl.transport.enforce_hostname_verification: false |
searchguard.authcz.admin_dn 条目配置可以与 sgadmin 或 REST管理API 一起使用的管理员证书。管理员证书是具有提升的执行管理任务权限的常规客户端证书。你需要管理员证书才能通过 sgadmin 命令行工具更改 Search Guard 配置,或者使用REST管理API。你需要声明证书的完整DN,并且可以配置多个管理证书。
如果你还想在 REST 层上使用 TLS(HTTPS),请将以下行添加到 elasticsearch.yml 文件:
1 2 3 4 5 |
searchguard.ssl.http.enabled: true searchguard.ssl.http.pemcert_filepath: <path_to_http_certificate> searchguard.ssl.http.pemkey_filepath: <path_to_http_certificate_key> searchguard.ssl.http.pemkey_password: <key_password (optional)> searchguard.ssl.http.pemtrustedcas_filepath: <path_to_http_root_ca> |
你可以在传输层(transport layer)和 REST 层上使用相同的证书。对于生产系统,我们建议使用单独的证书。
可选:启用REST管理API
要使用REST管理API,请配置应该有权访问API的 Search Guard 角色。以下条目授予对角色 sg_all_access 的API的完全访问权限:
1 |
searchguard.restapi.roles_enabled: ["sg_all_access"] |
如果你想进一步限制对某些API的访问,请参考 REST management API documentation chapter ,REST管理API是Enterprise的功能。
另外,你可能还需要关闭 Xpack 的安全认证功能,避免两者冲突 xpack.security.enabled: false 。
如果你是测试,使用了 Search Guard demo certificates 证书,那么需要在 elasticsearch.yml 文件添加 searchguard.allow_unsafe_democertificates: true 来确保服务正常运行。
5. 重新启动 Elasticsearch 并检查节点是否正常
观察 ES 启动日志,要保证没有错误及其他问题。
6. 使用 sgadmin 重新启用分片分配
在群集再次启动后,重新启用分片分配,以便可以在下一步中创建 Search Guard 配置索引。由于 Search Guard 现在处于活动状态,但尚未初始化,因此你需要将管理证书与 sgadmin 或 curl 结合使用,需要给 sgadmin 命令增加执行权限:
1 |
chmod +x plugins/search-guard-6/tools/sgadmin.sh |
使用 sgadmin 的示例:
1 2 |
./sgadmin.sh --enable-shard-allocation \ -icl -nhnv -cert ../../../config/kirk.crtfull.pem -key ../../../config/kirk.key.pem -cacert ../../../config/chain-ca.pem |
参数说明:
默认情况下,sgadmin将验证节点证书中的主机名是否与节点的实际主机名匹配,如果不是这种情况,例如你正在使用演示证书,通过添加 -nhnv 开关来禁用主机名验证。
默认情况下,sgadmin使用elasticsearch作为群集名称,如果你的群集名称不同,就需要使用 -icl 开关来忽略集群名称。或者使用 -cn 开关来指定集群的名称。
连接有什么问题,多多参考官方故障指南。
如果你使用 demo installation script 生成的证书,请执行以下操作:
1 2 |
./sgadmin.sh --enable-shard-allocation \ -cert ../../../config/kirk.pem -key ../../../config/kirk-key.pem -cacert ../../../config/root-ca.pem |
7. 通过使用 sgadmin 更新 Search Guard 配置来配置身份验证/授权,用户,角色和权限
初始化Search Guard。有关用户,角色,权限和身份验证方法的所有设置都存储在 Elasticsearch 上的 Search Guard 索引中。这允许配置热加载,并且无需在任何节点上放置配置文件。默认情况下,出于安全原因,不会自动创建此索引。
通过使用 sgadmin 命令行工具和 searchguard.authcz.admin_dn 参数配置的管理证书来初始化 Search Guard。如果 Search Guard 索引已初始化,你还可以使用 Kibana 配置 GUI 来更改用户,角色和权限。但是,你需要至少运行一次 sgadmin 来初始化索引并配置你要使用的身份验证和授权方法。
使用带有PEM证书的sgadmin
为了使用sgadmin将配置更改推送到Search Guard,您需要向该工具提供管理员证书。
1 2 |
./sgadmin.sh -cd ../sgconfig/ -icl -nhnv \ -cacert ../../../config/chain-ca.pem -cert ../../../config/kirk.crtfull.pem -key ../../../config/kirk.key.pem |
如果你使用 demo installation script 生成的证书,请执行以下操作:
1 2 |
./sgadmin.sh -cd ../sgconfig/ -icl -nhnv \ -cacert ../../../config/root-ca.pem -cert ../../../config/kirk.pem -key ../../../config/kirk-key.pem |
正常情况下得到以下输出信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Search Guard Admin v6 Will connect to localhost:9300 ... done Elasticsearch Version: 6.4.2 Search Guard Version: 6.4.2-23.2 Connected as CN=kirk,OU=client,O=client,L=test,C=de Contacting elasticsearch cluster 'elasticsearch' and wait for YELLOW clusterstate ... Clustername: cluster01 Clusterstate: GREEN Number of nodes: 3 Number of data nodes: 3 searchguard index does not exists, attempt to create it ... done (0-all replicas) Populate config from /opt/elasticsearch-6.4.2/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 |
-cd选项指定可以找到要加载到集群的 Search Guard 配置文件的位置。
验证 Search Guard 是否正常运行:
要检查 Search Guard 是否已安装并启动并运行,请访问 healthcheck 端点,如:
1 |
curl 'http://localhost:9200/_searchguard/health?pretty' |
它返回一个JSON代码段,如:
1 2 3 4 5 |
{ message: null, mode: "strict", status: "UP" } |
说明 Search Guard 已经正常运行了。
接下来可以使用默认的 admin:admin 进行登录认证,其属于默认管理账户。
1 |
curl 'http://admin:admin@localhost:9200/_searchguard/authinfo?pretty' |
正常情况下会返回如下认证信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{ "user" : "User [name=admin, roles=[admin], requestedTenant=null]", "user_name" : "admin", "user_requested_tenant" : null, "remote_address" : "[::1]:35782", "backend_roles" : [ "admin" ], "custom_attribute_names" : [ "attr.internal.attribute1", "attr.internal.attribute2", "attr.internal.attribute3" ], "sg_roles" : [ "sg_all_access", "sg_own_index" ], "sg_tenants" : { "admin_tenant" : true, "admin" : true }, "principal" : null, "peer_certificates" : "0", "sso_logout_url" : null } |
至此,关于 Search Guard 认证基本已经完成了。接下来就是关于账号权限的创建与管理,可以在 Kibana 直接操作。
如果你使用 Cerebro 连接 Elastisearch 就需要输入用户名和密码了,但是如果你也对 REST API 也开启了 HTTPS 保护,那么就需要对 Cerebro 做一些特殊的设置了,Search Guard 官方也有一些说明。