【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

Open Distro for Elasticsearch 的 LDAP 集成

  • 2019-10-01
  • 本文字数:7287 字

    阅读完需:约 24 分钟

Open Distro for Elasticsearch 的 LDAP 集成

Open Distro for Elasticsearch 的安全插件自带即开即用的身份验证和访问控制功能。在前几篇文章中,我们展示了如何在 Open Distro for Elasticsearch 中更改管理员密码以及如何将自己的 SSL 证书添加到 Open Distro for Elasticsearch。


使用安全插件的关键步骤之一是确定身份验证后端。该插件包含一个内部用户数据库,但是许多人员更喜欢使用现有的身份验证后端(例如 LDAP 服务器)或者两者的某种组合。在本文中,我们将讨论如何将安全插件与 LDAP 或 Active Directory 集成,并配置后端用户角色与 Elasticsearch 安全角色之间的映射,以提供粒度访问控制。


身份验证和授权模块的主配置文件为 plugins/opendistro_security/securityconfig/config.yml。该文件定义安全插件如何检索用户凭证,如何验证这些凭证以及如何从后端系统获取其他用户角色。有关此配置文件结构的详细信息,请参阅 Open Distro for Elasticsearch 文档。

在 LDAP/AD 中创建用户并分配到组

我使用 Active Directory 作为 LDAP 服务器。使用“Active Directory 用户和计算机”管理工具,我创建了三个用户(esuser1、esuser2 和 esuser3)以及两个组(ESAdmins 和 ES-Read-Grp)。我已使 esuser1 成为 ESAdmins 组的成员,esuser2 成为 ES-Read-Grp 组的成员,而 esuser3 不属于任何组。



针对 Open Distro for Elasticsearch 的 Microsoft Active Directory 用户配置

对安全插件配置应用更改

安全插件将其配置(包括用户、角色和权限)存储在 Elasticsearch 集群 (.opendistro_security) 的索引中。将这些设置存储在索引中,可以在更改设置后无需重新启动集群,也不需要将配置文件放在任何节点上。


但是,更改 plugins/opendistro_security/securityconfig 中的任何配置文件后,必须运行 plugins/opendistro_security/tools/securityadmin.sh,将这些新设置加载到索引。此脚本通过管理员 TLS 证书(采用 .pem、.jks、.p12 或 .pfx 格式)针对集群自我识别。


如果 .opendistro_security 索引已初始化,您也可以使用 Kibana 更改用户、角色和权限。但是,您需要至少运行一次 securityadmin.sh 来初始化索引并配置身份验证和授权方法。


有关如何使用 securityadmin.sh 的更多详细信息,请参阅 Open Distro for Elasticsearch 文档。

在安全插件中配置 LDAP 详细信息

LDAP 可用于身份验证和授权,因此可以在配置的 authc 和 authz 部分中使用。authc 部分用于配置身份验证,这意味着可用于检查用户是否输入了正确的凭证。authz 用于授权,定义如何检索和映射经过身份验证的用户的角色。


对于新设置,可以使用 plugins/opendistro_security/securityconfig/config.yml 更新 LDAP 配置详细信息。在既有的设置中,确保从正在运行的集群 (securityadmin.sh -r…) 检索当前安全插件配置并使用这些文件避免丢失任何更改。

身份验证

将以下行添加到 config.yml 文件的 authc 部分以启用 LDAP 身份验证:


  ...     authc:      ldap:        http_enabled: true        transport_enabled: false        order: 1        http_authenticator:          type: "basic"          challenge: false        authentication_backend:          type: "ldap"          config:   ...
复制代码


在 config 部分,我们将配置 LDAP 连接设置:主机名和端口 (hosts:)、BindDN (bind_dn:) 和密码 (password)。以下是此部分的副本 – 将 “<< password >>” 替换为绑定用户的实际纯文本密码。


          config:            enable_ssl: false            enable_start_tls: false            enable_ssl_client_auth: false            verify_hostnames: true            hosts:                - "ad.example.com:389"            bind_dn: "cn=esuser1,OU=Users,OU=AD,dc=ad,dc=example,dc=com"            password: "<< password >>"            userbase: "OU=Users,OU=AD,dc=ad,dc=example,dc=com"            usersearch: "(sAMAccountName={0})"            username_attribute: "cn"
复制代码


身份验证的运作方式为:对 LDAP 树的用户子树发出包含用户名的 LDAP 查询。


安全插件首先接受已配置的 LDAP 查询,并将占位符 {0} 替换为用户凭证中的用户名。


usersearch: "(sAMAccountName={0})"
复制代码


然后对用户子树发出此查询。目前,将搜索配置的 userbase 下面的整个子树:


userbase: "OU=Users,OU=AD,dc=ad,dc=example,dc=com"
复制代码


如果查询成功,安全插件将从 LDAP 条目检索用户名。您可以指定安全插件应该使用 LDAP 条目中的哪个属性作为用户名:


username_attribute: "cn"
复制代码


如果此项未设置或为 null,则使用 LDAP 条目的可分辨名称 (DN)。我已设置为“CN”。

授权

将以下行添加到 config.yml 文件的 authz 部分以启用 LDAP 授权:


...    authz:      roles_from_myldap:        http_enabled: true        transport_enabled: false        authorization_backend:          type: "ldap"          config:...
复制代码


授权是从 LDAP 服务器检索经过身份验证的用户的后端角色的过程。此服务器通常是用于身份验证的同一服务器,但也可以使用不同的服务器。惟一的要求是所需的用户确实存在于 LDAP 服务器上。由于安全插件始终检查用户是否存在于 LDAP 服务器上,因此您需要在 authz 部分配置 userbase、usersearch 和 username_attribute。授权的运作方式与身份验证类似。安全插件对 LDAP 树的角色子树发出包含用户名的 LDAP 查询。以下是此部分的副本:


        config:            enable_ssl: false            enable_start_tls: false            enable_ssl_client_auth: false            verify_hostnames: true            hosts:            - "ad.example.com:389"            bind_dn: "cn=esuser1,OU=Users,OU=AD,dc=ad,dc=example,dc=com"            password: "Test1234"            userbase: "OU=Users,OU=AD,dc=ad,dc=example,dc=com"            usersearch: "(uid={0})"            rolebase: "OU=Groups,OU=AD,dc=ad,dc=example,dc=com"            rolesearch: "(member={0})"            userrolename: "memberOf"            rolename: "cn"
复制代码


安全插件首先接受用于获取角色的 LDAP 查询(“rolesearch”),并替换在查询中发现的任何变量。例如,对于标准的 Active Directory 安装,您将使用以下角色搜索。此处的 {0} 将替换为用户的 DN:


rolesearch: '(member={0})'
复制代码


然后,安全插件对配置的角色子树发出替换的查询。将搜索 rolebase 下面的整个子树。


rolebase: 'ou=groups,dc=example,dc=com'
复制代码


获取所有角色之后,安全插件将从角色条目的可配置属性中提取最终的角色名称:


rolename: 'cn'
复制代码


如果未设置此项,将使用角色条目的 DN。

更新安全插件配置

现在,运行 securityadmin.sh 以更新安全插件配置,如下所示:


$ /usr/share/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh \    -cacert /etc/elasticsearch/root-ca.pem \-cert /etc/elasticsearch/kirk.pem \ -key /etc/elasticsearch/kirk-key.pem \-h <Cluster-IP-or-FQDN> \-f <Path-to-config>/config.yml -t config
复制代码


这里,我指定了根 CA 证书 (-cacert)、管理员证书 (-cert) 和管理员私有密钥 (-key) 文件的路径。管理员证书的 DN 需要在 elasticsearch.yml 中的 opendistro_security.authcz.admin_dn 下配置。我通过明确指定配置文件位置,限制为仅对此配置文件进行此更新。

创建 Elasticsearch 安全角色

Open Distro for Elasticsearch 的安全插件内置默认操作组。我们将创建新角色,并使用这些默认操作组分配集群级和索引级权限。有关创建组合默认操作组和单一权限的新自定义操作组以及如何将文档和字段级安全性添加到角色定义中的详细信息,请参阅文档。

Kibana

使用 Kibana 作为“管理员”用户,我创建了两个自定义角色,一个具有完全的读/写权限,另一个仅具有只读权限。


选择“Security”并单击 Roles:



Open Distro for Elasticsearch 安全插件的 Kibana 主面板


单击 + 按钮,添加新角色:


显示 Open Distro for Elasticsearch 的安全插件角色管理页面


输入新的角色名称:



用于为 Open Distro for Elasticsearch 中的新后端角色设置角色名称的 Kibana 面板


选择 Cluster Permissions,然后在“Action Groups”和/或“Single Permissions”下添加值:



在 Open Distro for Elasticsearch 安全插件中添加新后端角色的权限


选择 Index Permissions,然后添加索引模式(支持通配符)或选择一个索引。


对于每个索引模式,在“Action Groups”和/或“Single Permissions”下添加值。


完成后,单击 Save Role Definition。


为 Open Distro for Elasticsearch 中的新后端角色设置索引权限

将 LDAP 后端角色映射到 Elasticsearch 安全角色

可以将 Elasticsearch 角色映射到用户名、后端角色和/或主机。后端角色确定为身份验证和授权过程的一部分,可以来自内部用户配置、LDAP 或 JSON Web Token。我们将角色映射到 LDAP 组名。


在 Kibana 中,选择 Security 并单击 Role Mappings:


Open Distro for Elasticsearch 安全插件的主 Kibana 面板,显示了角色映射按钮的位置


单击 + 按钮,添加新角色映射:



Open Distro for Elasticsearch 安全插件中的管理角色映射面板


从 Role 下拉列表中选择新角色(仅未映射的角色可供选择)。


添加相应的后端角色。(我使用 LDAP 组名的 CN,因为我已在安全配置中配置了 rolename: ‘cn’。如果没有此配置,则需要在此处指定完整的 DN。)


单击 Submit,保存映射:



Open Distro for Elasticsearch 中用于创建新角色映射的对话框

使用 CLI 创建角色和映射

我们将使用命令行界面 (CLI) 创建只读角色和映射。


在新的设置中,您也可使用 plugins/opendistro_security/securityconfig/ 中的默认安全配置文件从命令行创建角色和角色映射。在既有的设置中,从正在运行的集群 (securityadmin.sh -r…) 检索当前安全插件配置,并使用这些输出文件以确保更新当前配置。


$ /usr/share/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh \    -cacert /etc/elasticsearch/root-ca.pem \-cert /etc/elasticsearch/kirk.pem \ -key /etc/elasticsearch/kirk-key.pem \-h <Cluster-IP-or-FQDN> \-r
复制代码


这将在本地文件夹中创建五个带有日期戳的文件 – config、roles、roles_mapping、internal_users、action_groups


将 roles 文件复制到 roles.yml 并将 roles_mapping 文件复制到 roles_mapping.yml


将以下所示的配置附加到 roles.yml 文件。这将创建一个名为 CustomReadOnly 的新角色且具有读权限


CustomReadOnly:  cluster:  - "CLUSTER_COMPOSITE_OPS_RO"  indices:    '*':      '*':      - "READ"
复制代码


将以下所示的配置附加到 roles_mapping.yml。这会将角色 CustomReadOnly 映射到 LDAP 组 ES-Read-Grp。


CustomReadOnly:  backendroles:  - "ES-Read-Grp" hosts: [] users: []
复制代码


现在,运行 securityadmin.sh 以更新安全插件配置,且一次推送一个更新,如下所示:


第一个命令行推送角色。


$ /usr/share/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh \    -cacert /etc/elasticsearch/root-ca.pem \-cert /etc/elasticsearch/kirk.pem \ -key /etc/elasticsearch/kirk-key.pem \-h <Cluster-IP-or-FQDN> \-f ./roles.yml -t roles
复制代码


此命令行推送角色映射。


$ /usr/share/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh \    -cacert /etc/elasticsearch/root-ca.pem \-cert /etc/elasticsearch/kirk.pem \ -key /etc/elasticsearch/kirk-key.pem \-h <Cluster-IP-or-FQDN> \-f ./roles_mapping.yml -t rolesmapping
复制代码

测试以不同的用户身份登录

以读写用户 esuser1 身份登录


用户 esuser1 属于 ESAdmins LDAP 组并映射到安全角色 ESAdminRole。作为该角色的一部分,允许此用户执行读写操作。


创建索引(正如所料成功):


$ curl -XPUT -k "https://odfe-node1:9200/my-index" -u esuser1Enter host password for user 'esuser1':{    "acknowledged":true,    "shards_acknowledged":true,    "index":"my-index" }
复制代码


添加文档(正如所料成功):


$ curl -XPOST -k "https://odfe-node1:9200/my-index/doc1/?pretty=true" -H 'Content-Type: application/json' -d'        {          "text":"Hello World!"        }' -u esuser1Enter host password for user 'esuser1':{  "_index" : "my-index",  "_type" : "doc1",  "_id" : "GPxOLGoB9R98haWaBOPk",  "_version" : 1,  "result" : "created",  "_shards" : {    "total" : 2,    "successful" : 2,    "failed" : 0  },  "_seq_no" : 0,  "_primary_term" : 1}
复制代码


运行搜索查询(正如所料成功):


$ curl -XPOST -k "https://odfe-node1:9200/_search?pretty=true"  -H 'Content-Type: application/json' -d' {  "query":{    "query_string":{        "query":"hello"        }    }}' -u esuser1Enter host password for user 'esuser1':{  "took" : 99,  "timed_out" : false,  "_shards" : {    "total" : 90,    "successful" : 90,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : 1,    "max_score" : 0.2876821,    "hits" : [      {        "_index" : "my-index",        "_type" : "doc1",        "_id" : "GPxOLGoB9R98haWaBOPk",        "_score" : 0.2876821,        "_source" : {          "text" : "Hello World!"        }      }    ]  }}
复制代码

以只读用户 esuser2 身份登录

用户 esuser2 属于 ES-Read-Grp LDAP 组并映射到安全角色 CustomReadOnly。作为该角色的一部分,允许此用户执行只读操作。


创建索引(正如所料失败。esuser2 不是允许写入的组的成员):


$ curl -XPUT -k "https://odfe-node1:9200/my-index" -u esuser2Enter host password for user 'esuser2':{  "error" : {    "root_cause" : [      {        "type" : "security_exception",        "reason" : "no permissions for [indices:data/write/index] and User [name=esuser2, roles=[Domain Users, Users, AWS Delegated Add Workstations To Domain Users], requestedTenant=null]"      }    ],    "type" : "security_exception",    "reason" : "no permissions for [indices:data/write/index] and User [name=esuser2, roles=[Domain Users, Users, AWS Delegated Add Workstations To Domain Users], requestedTenant=null]"  },  "status" : 403}
复制代码


运行搜索查询(正如所料成功):


$ curl -XPOST -k "https://odfe-node1:9200/_search?pretty=true"  -H 'Content-Type: application/json' -d' {  "query":{    "query_string":{        "query":"hello"        }    }}' -u esuser2Enter host password for user 'esuser2':{  "took" : 101,  "timed_out" : false,  "_shards" : {    "total" : 90,    "successful" : 90,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : 1,    "max_score" : 0.2876821,    "hits" : [      {        "_index" : "my-index",        "_type" : "doc1",        "_id" : "GPxOLGoB9R98haWaBOPk",        "_score" : 0.2876821,        "_source" : {          "text" : "Hello World!"        }      }    ]  }}
复制代码

以用户 esuser3(不属于任何组)身份登录

用户 esuser3 不属于任何 LDAP 组,也没有映射到任何安全角色。因此,不允许此用户执行任何操作。


添加文档(正如所料失败。esuser3 不是任何组的成员):


$ curl -XPOST -k "https://odfe-node1:9200/my-index/doc1/?pretty=true" -H 'Content-Type: application/json' -d'        {          "text":"Hello World!"        }' -u esuser3Enter host password for user 'esuser3':  "error" : {    "root_cause" : [      {        "type" : "security_exception",        "reason" : "no permissions for [indices:data/write/index] and User [name=esuser3, roles=[], requestedTenant=null]"      }    ],    "type" : "security_exception",    "reason" : "no permissions for [indices:data/write/index] and User [name=esuser3, roles=[], requestedTenant=null]"  },  "status" : 403}
复制代码


添加搜索查询(正如所料失败。esuser3 不是任何组的成员):


$ curl -XPOST -k "https://odfe-node1:9200/_search?pretty=true"  -H 'Content-Type: application/json' -d' {  "query":{    "query_string":{        "query":"hello"        }    }}' -u esuser3Enter host password for user 'esuser3':{  "error" : {    "root_cause" : [      {        "type" : "security_exception",        "reason" : "no permissions for [indices:data/read/search] and User [name=esuser3, roles=[], requestedTenant=null]"      }    ],    "type" : "security_exception",    "reason" : "no permissions for [indices:data/read/search] and User [name=esuser3, roles=[], requestedTenant=null]"  },  "status" : 403}
复制代码

小结

在本文中,我介绍了如何将安全插件与 LDAP 或 Active Directory 服务器集成以进行用户身份验证。我展示了如何配置授权以及后端用户组和 Elasticsearch 安全角色之间的映射,以提供基于粒度角色的访问控制。


有关安全插件的 Active Directory 和 LDAP 集成的其他配置选项,请参阅 Open Distro for Elasticsearch 文档。


有问题或疑问? 希望参与讨论? 您可以在我们的论坛上获得帮助并讨论 Open Distro for Elasticsearch。您可以在这里提出问题。


作者介绍:


Jagadeesh Pusapadi


Jagadeesh Pusapadi 是 AWS 的解决方案架构师,负责与客户就其战略计划进行合作。他通过提供架构指导,帮助客户在 AWS 云上构建创新解决方案,以实现预期的业务成果。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/ldap-integration-for-open-distro-for-elasticsearch/


2019-10-01 18:161113
用户头像

发布了 1837 篇内容, 共 92.9 次阅读, 收获喜欢 73 次。

关注

评论

发布
暂无评论
发现更多内容

【Vite】配置HTTPS&自签名证书

小鑫同学

8月月更

flex 布局(弹性布局 / 弹性盒子)一直没学明白,看完这篇文章我彻底懂了

CRMEB

云签约,云培训,云办公,云指挥… 欧冶工业品,用数字化赋能企业

sofiya

【全干】从零搞定微信SDK授权

小鑫同学

8月月更

带你体验一次类型编程实践

小鑫同学

8月月更

介绍16个让你的代码变漂亮的属性

小鑫同学

8月月更

SAP 电商云 Spartacus UI 里的 ASM 模块启用的前置条件

Jerry Wang

angular SAP SAP UI5 Spartacus 8月月更

时尚品牌玛丝菲尔,选择华为云会议的3个理由

sofiya

计算机网络(四、网络层)

计算机网络 8月月更

强烈推荐一款超好用的开源电商系统!!!

CRMEB

惊艳!阿里巴巴最新发布Java系统架构师+开发应用面试突击宝典

Java编程日记

Java 编程 程序员 面试 架构师

数据,不能只讲大道理

水滴

数据中台 数据规范 数据化转型

华为云会议,用高效联接推进工业企业数字化转型

sofiya

C++多态案例(一)-计算器类

CtrlX

c c++ 面向对象 代码 8月月更

小程序|炎炎夏日、清爽一夏、头像大换装

小鑫同学

8月月更

秋招大厂字节上午 10:00 面试,10:09 就出来了 ,问的实在是太...

退休的汤姆

Java、 面经 社招 Java工程师 秋招

打造数字化工作平台,提升内外协同效率

神奇视野

拒绝“填”麻烦,这里有条安全返校小妙招

sofiya

docker下的spark集群,调整参数榨干硬件

程序员欣宸

Java spark 8月月更

抽象工厂模式在项目开发中的应用,这个例子绝了

知识浅谈

工厂模式 8月月更

【消息通知】用公众号模板消息怎么样?

小鑫同学

8月月更

上手体验TailwindCSS

小鑫同学

8月月更

京东8年资深架构师为你解析:Kafka源码解析实战。为你解忧

Java编程日记

Java 编程 程序员 架构师 面经

大数据训练营1期 毕业总结

张大彪

阿里最新468页Spring Boot企业级项目开发实战手册好强啊,Github获星30000+

Java面试那些事儿

Java 编程 程序员 面试 架构师

Go-Excelize API源码阅读(十五)——SetSheetViewOptions

Regan Yue

Go 开源 源码 8月日更 8月月更

让视频会议更简单,华为云会议SmartRooms一站全搞定

sofiya

头脑风暴:最长重复子数组

HelloWorld杰少

“掌上迎新”,这个学校把5400+新生安排的明明白白

sofiya

云原生(二十二) | Kubernetes篇之Ingress案例实战

Lansonli

云原生 8月月更

基于STM32F103设计的智能门锁(支持多种开锁解锁方式)

DS小龙哥

8月月更

Open Distro for Elasticsearch 的 LDAP 集成_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章