暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用Search Guard加固Elasticsearch(配置、认证、角色、权限)

运维那点事 2018-12-24
1952

一、介绍

最近新上的 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 预定义了一个适用于大多数用例的操作组列表。

通用

NameDescription
UNLIMITED授予完全访问权限,可用于索引级别和集群级别,等同于“*”。

索引级别

NameDescription
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授予所有监视器和索引管理权限

集群级别

NameDescription
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 附带以下演示用户:

UsernamePasswordDescription
adminadmin完全访问群集和所有索引权限,但无法访问Search Guard配置。需要使用管理员证书。
kibanaserverkibanaserver内部Kibana服务器用户,用于在kibana.yml中配置elasticsearch.username和elasticsearch.password。拥有.kibana索引的所有权限。
kibanarokibanaro常规Kibana用户,具有对.kibana索引和所有索引和所有权限的READ访问权限。
logstashlogstashLogstash和Beats用户对所有logstash和beats索引具有CRUD和CREATE_INDEX权限。
readallreadall

具有对所有索引的读取权限。

snapshotrestoresnapshotrestore具有执行快照和还原操作的权限。

演示角色

Search Guard 附带以下演示角色:

Role nameDescription
sg_all_access所有集群权限和所有索引的全部索引权限
sg_readall读取所有索引的权限,但没有写入权限
sg_readonly_and_monitor读取和监控所有索引的权限,但没有写入权限
sg_kibana_server内部Kibana服务器用户的角色,请参阅 Kibana setup 章节以获取说明
sg_kibana_user为常规Kibana用户设置的最低权限。除了此角色之外,你还需要为用户应该能够在Kibana中访问的索引授予READ权限
sg_logstashlogstash和beats用户的角色,授予对所有logstash和beats索引的完全访问权限
sg_manage_snapshots授予快照,还原和存储库操作的完全权限
sg_own_index授予以经过身份验证的用户的用户名命名的索引的完全权限
sg_xp_monitoringX-Pack监控的角色,除了sg_kibana_user角色之外,希望使用X-Pack Monitoring的用户还需要此角色
sg_xp_alertingX-Pack警报的角色,除了sg_kibana角色之外,希望使用X-Pack警报的用户还需要此角色
sg_xp_machine_learningX-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:
    - devuser

sg_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:
    '*':
      '*':
        - DEVUSER

sg_roles_mapping

sg_devuser:
  users:
    - 'devuser'

都配置完成后,使用 sgadmin.sh 工具把数据加载进 Elasticsearch 即可。可以自行多试试各种权限的组合,根据自己的需求定制即可。

文章转载自运维那点事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论