一、介绍
最近新上的 Elasticsearch 项目需要一些安全认证,使用到 Search Guard 这么一款安全插件,网上也有一些零零散散的资料,官方文档也很全,我把一些重要的社区版功能测试了一下(最新版),形成了一个有点长的文档,如果你也刚好有这方面的需求可能会为你节省一些调研和学习时间。
-----------------正文开始-----------------
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文件。存储库位于:
Search Guard SSL 6.x
要执行的脚本是 ./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:
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脚本生成的证书,则以下是相关文件:
example-pki-scripts/etc/root-ca.conf example-pki-scripts/etc/signing-ca.conf
使用证书链生成示例证书。它由根CA,签名CA和实际证书组成。上述两个文件定义了根CA和签名CA的配置,尤其是 Distinguished Name(DN)。你可以在以下部分中更改DN:
[ 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,请修改以下文件:
# 生成节点证书 gen_node_cert.sh # 生成客户端证书, 此脚本生成的证书也可用作管理员证书 gen_client_node_cert.sh
你可以通过修改相应文件中的以下部分来更改生成的证书的DN,主机名和IP:
-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。
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 安装目录并输入:
bin/elasticsearch-plugin install -b com.floragunn:search-guard-6:<version>
比如:
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 安装目录并输入:
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 目录下):
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 证书,所以我的配置如下:
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 文件:
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的完全访问权限:
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 命令增加执行权限:
chmod +x plugins/search-guard-6/tools/sgadmin.sh
使用 sgadmin 的示例:
./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 生成的证书,请执行以下操作:
./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,您需要向该工具提供管理员证书。
./sgadmin.sh -cd ../sgconfig/ -icl -nhnv \ -cacert ../../../config/chain-ca.pem -cert ../../../config/kirk.crtfull.pem -key ../../../config/kirk.key.pem
如果你使用 demo installation script 生成的证书,请执行以下操作:
./sgadmin.sh -cd ../sgconfig/ -icl -nhnv \ -cacert ../../../config/root-ca.pem -cert ../../../config/kirk.pem -key ../../../config/kirk-key.pem
正常情况下得到以下输出信息:
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 端点,如:
curl 'http://localhost:9200/_searchguard/health?pretty'
它返回一个JSON代码段,如:
{
message: null,
mode: "strict",
status: "UP"
}说明 Search Guard 已经正常运行了。
接下来可以使用默认的 admin:admin 进行登录认证,其属于默认管理账户。
curl 'http://admin:admin@localhost:9200/_searchguard/authinfo?pretty'
正常情况下会返回如下认证信息:
{
"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 官方也有一些说明。
三、内部数据库
Search Guard 附带内部用户数据库,如果你没有任何外部身份验证系统(如 LDAP 或 Active Directory),则可以使用此用户数据库。用户信息及其散列密码和角色存储在群集内部的 Search Guard 索引中。
内部用户在 sg_internal_users.yml
文件中配置,你可以找到模板在<ES installation directory>/plugins/search-guard-6/sgconfig/sg_internal_users.yml
。
语法:
<username>:
hash: <hashed password>
roles:
- <rolename>
- <rolename>示例:
admin:
hash: $2a$12$xZOcnwYPYQ3zIadnlQIJ0eNhX1ngwMkTN.oMwkKxoGvDVPn4/6XtO
roles:
- readall
- writeall
analyst:
hash: $2a$12$ae4ycwzwvLtZxwZ82RmiEunBbIPiAmGZduBAjKN0TXdwQFtCwARz2
roles:
- readall请注意,用户名不能包含点。如果你需要带点的用户名,请使用username属性:
<username>: username: username.with.dots hash: ...
由于在配置 sg 时 sg_internal_users.yml 文件需要存在且不为能空,所以如果你不希望有内部用户则写入 {}
到文件中即可。
生成散列密码
你可以使用 Search Guard 附带的 hash.sh 脚本来生成它们:
plugins/search-guard-6/tools/hasher.sh -p mycleartextpassword
这里注意一下,可能是官方写错了名字,没有名称叫 hasher.sh 的脚本,只有名称叫 hash.sh 的脚本。当然,不知道后面新版本是否会改为 hasher.sh名称。
配置
要使用内部用户数据库,请将 authentication_backend 设置为 internal 。例如,如果要使用 HTTP 基本身份验证和内部用户数据库,则配置如下所示:
basic_internal_auth_domain:
enabled: true
order: 1
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal授权
你还可以使用内部用户数据库进行授权,指分配后端角色。当你的主要身份验证方法不提供任何角色信息时,这非常有用。
例如,你可以使用 LDAP 或 JWT 进行身份验证,使用内部用户数据库进行授权/分配角色。
Search Guard 将使用 autenticated 用户的名称在内部用户数据库中查找相应的条目。如果找到,配置角色将被指定为该用户的后备角色。
如果仅使用内部用户数据库进行授权,则无需设置散列密码。这些条目仅用于分配后端角色。
配置:
authz:
internal_authorization:
enabled: true
authorization_backend:
type: internal四、操作组
操作组只是具有说明名称的权限集合,操作组在文件sg_action_groups.yml
中定义,可以在 sg_roles.yml
中引用。另外,操作组也可以嵌套。
文件结构非常简单:
<action group name>:
- '<permission or action groups>'
- '<permission or action group>'
- ...操作组名称不得包含点,使用操作组是为角色分配权限的首选方式。
预定义操作组
Search Guard 预定义了一个适用于大多数用例的操作组列表。
通用
| Name | Description |
|---|---|
| UNLIMITED | 授予完全访问权限,可用于索引级别和集群级别,等同于“*”。 |
索引级别
| Name | Description |
|---|---|
| INDICES_ALL | 授予索引的所有权限。等同于 indices:* |
| GET | 授予仅使用get和mget操作的权限 |
| READ | 授予读取权限,例如get,mget或获取字段映射以及搜索权限 |
| WRITE | 授予对文档的写权限 |
| DELETE | 授予对文档的删除权限 |
| CRUD | 组合READ,WRITE和DELETE操作组 |
| SEARCH | 授予搜索文档的权限,包括SUGGEST。 |
| SUGGEST | 授予使用建议API的权限,已经包含在READ操作组中。 |
| CREATE_INDEX | 授予创建索引和映射的权限 |
| INDICES_MONITOR | 授予执行有关索引监控的所有操作的权限,例如恢复,段信息,索引统计和状态 |
| MANAGE_ALIASES | 授予管理别名的权限 |
| MANAGE | 授予所有监视器和索引管理权限 |
集群级别
| Name | Description |
|---|---|
| CLUSTER_ALL | 授予所有群集权限。等同于 cluster:* |
| CLUSTER_MONITOR | 授予所有群集监控权限。等同于 cluster:monitor/* |
| CLUSTER_COMPOSITE_OPS_RO | 授予执行多个请求(如mget,msearch或mtv)的只读权限,以及查询别名的权限 |
| CLUSTER_COMPOSITE_OPS | 等同于CLUSTER\ _COMPOSITE\_OPS\_RO,但也授予批量写入权限和所有别名权限 |
| MANAGE_SNAPSHOTS | 授予管理快照和存储库的完全权限 |
多个和批量请求
要执行多个和批量请求,相应的用户需要具有:
群集级别的多个和/或批量权限。
索引级别的相应权限。
例如,如果用户执行包含 index1 删除请求和 index2 更新请求的批量请求,则需要三个权限:
群集级别的批量权限
删除 index1 的权限
写入 index2 的权限
自定义操作组
你可以在 sg_action_groups.yml 文件中定义自己的操作组,你可以使用任何你想要的名称,你还可以从另一个操作组中引用操作组:
SEARCH: - "indices:data/read/search*" - "indices:data/read/msearch*" - SUGGEST SUGGEST: - "indices:data/read/suggest*"
在这种情况下,操作组 SEARCH 包括(通配符)search* 和 msearch* 权限,以及操作组 SUGGEST 定义的所有权限。
然后,你可以通过名称在文件 sg_roles.yml 中引用这些操作组:
sg_readall:
indices:
'*':
'*':
- SEARCH五、演示用户和角色
Search Guard 附带了一个演示配置,其中包含各种用例的用户和角色。你可以将这些用户和角色用作你自己的权限模式。
演示用户
Search Guard 附带以下演示用户:
| Username | Password | Description |
|---|---|---|
| admin | admin | 完全访问群集和所有索引权限,但无法访问Search Guard配置。需要使用管理员证书。 |
| kibanaserver | kibanaserver | 内部Kibana服务器用户,用于在kibana.yml中配置elasticsearch.username和elasticsearch.password。拥有.kibana索引的所有权限。 |
| kibanaro | kibanaro | 常规Kibana用户,具有对.kibana索引和所有索引和所有权限的READ访问权限。 |
| logstash | logstash | Logstash和Beats用户对所有logstash和beats索引具有CRUD和CREATE_INDEX权限。 |
| readall | readall | 具有对所有索引的读取权限。 |
| snapshotrestore | snapshotrestore | 具有执行快照和还原操作的权限。 |
演示角色
Search Guard 附带以下演示角色:
| Role name | Description |
|---|---|
| sg_all_access | 所有集群权限和所有索引的全部索引权限 |
| sg_readall | 读取所有索引的权限,但没有写入权限 |
| sg_readonly_and_monitor | 读取和监控所有索引的权限,但没有写入权限 |
| sg_kibana_server | 内部Kibana服务器用户的角色,请参阅 Kibana setup 章节以获取说明 |
| sg_kibana_user | 为常规Kibana用户设置的最低权限。除了此角色之外,你还需要为用户应该能够在Kibana中访问的索引授予READ权限 |
| sg_logstash | logstash和beats用户的角色,授予对所有logstash和beats索引的完全访问权限 |
| sg_manage_snapshots | 授予快照,还原和存储库操作的完全权限 |
| sg_own_index | 授予以经过身份验证的用户的用户名命名的索引的完全权限 |
| sg_xp_monitoring | X-Pack监控的角色,除了sg_kibana_user角色之外,希望使用X-Pack Monitoring的用户还需要此角色 |
| sg_xp_alerting | X-Pack警报的角色,除了sg_kibana角色之外,希望使用X-Pack警报的用户还需要此角色 |
| sg_xp_machine_learning | X-Pack机器学习的角色,除了sg_kibana角色之外,希望使用X-Pack机器学习的用户还需要此角色 |
注意:默认情况下,所有用户都映射到角色 sg_public 和 sg_own_index。你可以通过从 sg_roles_mapping.yml 中删除以下行来删除此映射:
sg_public:
users:
- '*'
sg_own_index:
users:
- '*'默认映射到 sg_own_index 角色意味着,此用户只需要在 sg_internal_users 中定义以下用户即可。然后此用户就可以创建一个以自己名称命名的索引,并且对这个索引有所有操作权限;但无法创建其他索引且也没有权限操作。
其 sg_own_index 对应的具体角色如下( sg_roles.yml ):
# Allows each user to access own named index
sg_own_index:
cluster:
- CLUSTER_COMPOSITE_OPS
indices:
'${user_name}':
'*':
- INDICES_ALL六、定义角色和权限
Search Guard 角色及其关联权限在文件 sg_roles.yml
中定义。你可以根据需要定义任意数量的角色。定义角色并将权限与其关联的语法如下:
<sg_role_name>:
cluster:
- '<action group or single permission>'
- ...
indices:
'<indexname or alias>':
'<document type>':
- '<action group or single permission>'
- ...
'<document type>':
- '<action group or single permission>'
- ...
_dls_: '<Document level security query>'
_fls_:
- '<field level security fiels>'
- ...
tenants:
<tenantname>: <RW|RO>
<tenantname>: <RW|RO>有关key _dls_
和 _fls_
用于配置文档级和字段级安全性。有关详细信息,请参阅 Document- and Field-level security。
有关key tenants
用于配置Kibana多租户。有关详细信息,请参阅 Kibana multi-tenancy。
文档类型(Type)在 Elasticsearch 6 中已弃用,将使用 Elasticsearch 7 删除。Search Guard 仍支持文档类型以实现向后兼容性。此支持将在 Search Guard 7 中删除,要定义所有文档类型的权限,请使用星号('*')作为文档类型。
集群级别权限
群集条目用于定义群集级别的权限。群集级权限用于允许/禁止影响整个群集的操作,例如查询群集运行状况或节点统计信息。
它们还用于 allow/disallow 影响多个索引的操作,例如 mget,msearch 或 bulk 请求。
示例:
sg_finance:
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
...索引级别权限
索引条目用于 allow/disallow 影响单个索引的操作,你可以单独为索引中的每种文档类型定义权限。
动态索引名称:通配符和正则表达式
索引名称支持(过滤)索引别名,索引名称和文档类型条目都支持通配符和正则表达式。
星号(*)将匹配任何字符序列(或空序列)
*my*index将匹配my_first_index以及myindex,但不匹配myindex1。
问号(?)将匹配任何单个字符(但不是空字符)
?kibana将匹配.kibana但不匹配kibana。
正则表达式必须包含在 /:'/<java regex>/' 中
'/\S*/'将匹配任何非空白字符。
注意:索引名称不能包含点。相反,使用?通配符,如在kibana中。
示例:
sg_kibana:
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
'?kibana':
'*':
- INDICES_ALL动态索引名称:用户名替换
对于<indexname or alias>,也允许占位符 ${user.name} ,支持包含用户名的索引或别名。在评估权限期间,占位符将替换为此请求的经过身份验证的用户的用户名。
sg_own_index:
cluster:
...
indices:
'${user_name}':
'*':
- INDICES_ALL动态索引名称:用户属性
任何身份验证和授权后端都可以添加其他用户属性,然后你可以将这些属性用于变量替换。
使用操作组分配权限
Search Guard 具有对权限进行分组并为其指定名称的功能,这些组称为操作组,是为角色分配权限的首选方式。Search Guard 附带一些预定义的操作组,这些操作组将涵盖大多数用例。
示例:
myrole:
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
'index1':
'*':
- SEARCH
'index2':
'*':
- CRUD使用单一权限
如果需要应用更细粒度的权限模式,Search Guard 还支持为角色分配单个权限。
单个权限以cluster:
or indices:
开头,后跟 REST 样式的路径,进一步定义权限授予访问权限的确切操作。
例如,此权限将授予对索引执行搜索的权限:
indices:data/read/search
此权限授予写入索引的权限:
indices:data/write/index
在群集级别,此权限授予显示群集运行状况的权限:
cluster:monitor/health
单个权限也支持通配符,以下权限授予索引上的所有管理操作:
indices:admin/*
七、映射用户到角色
根据你的配置,你可以使用以下数据将请求分配给一个或多个 Search Guard 角色:
username
经过身份验证的用户名称。
backend roles
授权后端(如LDAP,JWT或内部用户数据库)获取的角色。
hostname/IP
请求来自的主机名或IP。
Common name
随请求一起发送的客户端证书的DN。
后端角色(backend roles)和Search Guard角色
后端角色是 Search Guard 在身份验证和授权过程中检索的角色。然后,这些角色将映射到 Search Guard 用于定义给定用户或主机拥有的权限的角色。权限本身可以在 sg_action_groups
中定义,Search Guard 角色在 sg_roles
中定义,而 sg_roles_mapping
定义了特定用户和特定角色之间的关联。
后端角色(backend roles)可以来自:
在 sg_config.yml 的 authz 部分中配置的 LDAP 服务器
在 sg_internal_users.yml 文件中为特定用户定义的角色
如果你正在使用 JWT 身份验证,则为 JSON Web Token
HTTP headers,如果你正在使用代理身份验证
映射
后端用户、角色和主机映射到 Search Guard 角色,在sg_roles_mapping.yml
文件中定义。
语法:
<Search Guard role name>:
users:
- <username>
- ...
backendroles:
- <rolename>
- ...
hosts:
- <hostname>
- ...Search Guard 角色名称不得包含点。
示例:
sg_read_write:
users:
- janedoe
- johndoe
backendroles:
- management
- operations
- 'cn=ldaprole,ou=groups,dc=example,dc=com'
hosts:
- "*.devops.company.com"可以将请求分配给一个或多个 Search Guard 角色。如果请求映射到多个角色,则会合并这些角色的权限。
分配多个角色时的权限处理
用户可以根据需要拥有任意数量的角色,并为该用户分配所有角色的所有权限。但是,如果用户具有为同一索引定义不同权限的多个角色,则 Search Guard 将仅使用在第一个角色中找到的权限。
如果要组合该索引的所有权限,请在 sg_config.yml 中启用此功能,如:
searchguard.dynamic.multi_rolespan_enabled: true
这将成为 Search Guard 7 的默认行为。小于此版本的默认值为 false,以便向后兼容。
八、角色映射模式
默认情况下,Search Guard 通过将用户名,后端角色 and/or 主机名映射到一个或多个 Search Guard 角色,将每个传入请求映射到 Search Guard 角色。这是在角色映射配置中配置的。
在使用 LDAP 等外部身份验证系统时,这提供了极大的灵活性,LDAP 具有自己的角色管理:例如,你可以将存储在 LDAP 中的多个后端角色映射到一个 Search Guard 角色。这同样适用于来自 JWT 或内部用户数据库的后端角色。
通过指定角色映射模式,你可以配置 Search Guard 映射后端角色的方式。这可以通过设置在 elasticsearch.yml 中配置:
searchguard.roles_mapping_resolution: <mode>
Mode: MAPPING_ONLY
这是默认值,表示所有后端角色都通过角色映射进行映射,如上所述。如果 sg_roles_mapping.yml 文件中没有特定后端角色的条目,则它不会映射到任何 Search Guard 角色。
Mode: BACKENDROLES_ONLY
后端角色直接映射到 Search Guard 角色,有效地完全跳过角色映射。如果使用此设置,则可以直接在 sg_roles.yml 文件中使用后端角色的名称,但不会进行其他映射。
例如,如果你的 LDAP 返回角色 ldap_finance,你可以直接在 sg_roles.yml 中定义权限,如:
ldap_finance:
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
...Mode: BOTH
在此模式下,角色通过 sg_roles_mapping.yml 映射,如MAPPING_ONLY模式,但后端角色也会添加到最终角色集中。这基本上是MAPPING_ONLY和BACKENDROLES_ONLY的组合。
假设你已经定义了一个映射:
sg_finance:
backendroles:
- ldap_finance如果你的 LDAP 返回角色 ldap_finance,则该用户将拥有两个 Search Guard 角色:
ldap_finance:来自LDAP的角色
sg_finance:来自LDAP的映射角色
九、权限配置实践
Search Guard 对于用户权限配置这块还是有点绕的,得真的理解各个文件之间的关系才能真的用好。我也是大概的过了一遍,简单理解。就使用本地数据库而言,大概工作原理如下图:

一个简单的需求就是对一个用户给予索引基本操作权限,并要求用户能够看索引的 settings、mapping 信息,但不包括能新增或删除索引。比较符合线上使用实践。下面分别配置一下各个文件。
sg_internal_users
#password is: devuser
devuser:
hash: $2y$12$Ry7rszDbaSLSGGpERxpGzue5HjjXt85dsZ/6vd32JwKb..xSt5ziS
roles:
- devusersg_action_groups
DEVUSER:
readonly: true
permissions:
- READ
- WRITE
- DELETE
- SEARCH
- INDEX
- GET
- indices:monitor/stats*
- indices:admin/get*
- indices:admin/mappings/get*
- indices:monitor/settings/get*sg_roles
sg_devuser:
cluster:
- CLUSTER_MONITOR
- CLUSTER_COMPOSITE_OPS
indices:
'*':
'*':
- DEVUSERsg_roles_mapping
sg_devuser:
users:
- 'devuser'都配置完成后,使用 sgadmin.sh 工具把数据加载进 Elasticsearch 即可。可以自行多试试各种权限的组合,根据自己的需求定制即可。




