写点什么

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:161370
用户头像

发布了 1855 篇内容, 共 121.9 次阅读, 收获喜欢 78 次。

关注

评论

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

基于 MinIO 对象存储保障 Rancher 数据

Rancher

Kubernetes k8s rancher

Rust 入门指南(rustup, cargo)

王泰

rust

兆骑科创创新创业大赛人才引进平台,双创赛事高层次人才引进

兆骑科创凤阁

TDengine 助力西门子轻量级数字化解决方案

TDengine

数据库 tdengine 时序数据库

10次面试9次被刷?吃透这500道大厂Java高频面试题后,怒斩offer

程序员啊叶

Java 编程 程序员 架构 java面试

【微服务测试教程】使用Python测试gRPC接口案例

和牛

测试

一文读懂如何部署具有外部数据库的高可用 K3s

Rancher

Kubernetes k8s rancher

面试官:ThreadLocal使用场景有哪些?内存泄露问题如何避免?

程序员啊叶

Java 编程 程序员 架构 java面试

兆骑科创创业大赛平台,活动路演,投融资对接

兆骑科创凤阁

58子站安居,经纪人营销管理平台登录接口加密逆向

梦想橡皮擦

Python 爬虫 7月月更

35道MySQL面试必问题图解,这样也太好理解了吧

程序员啊叶

Java 编程 程序员 架构 java面试

活动速递| Apache Doris 性能优化实战系列直播课程初公开,诚邀您来参加!

SelectDB

数据库 性能优化 数据仓库 OLAP Doris

Rust 入门指南(crate 管理)

王泰

rust

IT远程运维是什么意思?远程运维软件哪个好?

行云管家

IT运维 远程运维 IT远程运维

一些企业数据平台建设的思考

Bright

数据平台 大数据平台

看了就会的 Rainbond 入门教程

北京好雨科技有限公司

Kubernetes 云原生

这50道Java面试题看完,想不进大厂都难

王小凡

Java 程序员 面试 面试题 大厂面试

有奖活动分享:使用WordPress搭建一个专属自己的博客后最高可领取iPhone13

云端explorer

Wordpress 博客部署

详解.NET的求复杂类型集合的差集、交集、并集

了不起的程序猿

java 14 java程序员 java编程

语音社交系统——完善有声系统产业链

开源直播系统源码

开源源码 语音直播系统源码 语音直播系统 语音直播系统连麦

不懂就问,快速成为容器服务进阶玩家!

阿里巴巴云原生

阿里云 容器 云原生 训练营

围绕新市民金融聚焦差异化产品设计、智能技术提效及素养教育

易观分析

新市民金融 差异化产品设计 素养教育

什么是SpringMVC?工作流程是什么?九大组件有哪些?

程序员啊叶

Java 编程 程序员 架构 java面试

NFTScan 与 NFTPlay 在 NFT 数据领域达成战略合作

NFT Research

区块链 大数据 NFT 合作 Web3.0

数牍 X Rust,那些不得不说的事

Jessica@数牍

联邦学习 隐私计算 数牍科技 rust开发者大会 分布式计算框架

管理区解耦架构见过吗?能帮客户搞定大难题的

华为云开发者联盟

云计算 后端 华为云

详解Kafka分区副本分配的Bug

石臻臻的杂货铺

7月月更 签约计划第三季

A tour of gRPC:05 - gRPC server straming 服务端流

BUG侦探

gRPC RPC protocolBuffer

融云实时社区解决方案

融云 RongCloud

分布式 hdfs-over-ftp 工具实现方案

移动云大数据

ApacheCon Asia 2022 启动!7场阿里云大数据+AI议题分享等你围观

阿里云大数据AI技术

人工智能 大数据

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