背景
我将我认为是相当普通的基础设施块放在一起,但遇到了很多问题,我不禁想知道是否有更简单的方法。
我需要能够执行以下操作:
- 使用委派身份验证和基于组的权限将文件从 Linux 服务器安全地共享给 OSX、Linux 和 Windows 计算机上的数百名用户。
- 允许基于组的 SSH 访问数十个 Linux 服务器,具有委派的身份验证和基于组的权限。
- 能够创建由其他组和用户组成的组,最好是任意深度。
- 能够允许基本任务的自助服务(密码更改和恢复,个人信息的有限编辑等)
- 能够以最少的配置迁移现有服务器(运行各种 Linux 风格) - 因此尽可能坚持“标准”配置,尤其是客户端。
我希望能够选择执行以下操作:
- 除基于密码的身份验证外,还支持公钥身份验证
对我来说,上述所有听起来都像是 LDAP + Samba 是唯一可行的方法,尤其是因为之前的实现使用了 FreeIPA/Samba。团队决定使用 OpenLDAP 和 LDAP Account Manager 来提供身份验证和目录服务,但实施过程却是一场噩梦。
OpenLDAP 设置
我的目录树具有以下结构:
- dc=example,dc=com
- ou=groups
- cn=groupA
- ...
- ou=policies
- cn=passwordDefault
- ...
- ou=services
- cn=service1
- ...
- ou=users (
- uid=user1
- ...
用户有以下类别:
- inetOrgPerson(结构)
- posixAccount
- 影子账户
- sambaSamAccount
- ppolicyUser
- 密码自复位
- ldapPublicKey
- 一般信息
用户工作得很好。大多数 Linux 机器都使用sshd -> libpam-ldap -> libnss-ldapd -> nscd -> nslcd
and coreutils -> libnss-ldapd -> nscd -> nslcd
,因此getent passwd
根本id [username]
不需要任何特殊配置即可工作。
服务有以下类:
- applicationProcess(结构)
- 简单安全对象
服务只是内部服务(如 Gitlab)的简单 DN/pw 实体,可以直接联系 LDAP,这样我们就可以关闭匿名绑定而不切断它们。他们也工作得很好。(注意 - 一些服务实际上需要作为 POSIX 帐户存在,因此为简单起见将它们配置为用户)
策略是诸如密码策略之类的实体,它们不在此问题的范围内。
组一直是真正的问题,因此我将在下一节中详细讨论它们。
团体的问题
无论我做什么,我似乎都无法创建可组合的 POSIX 兼容组。在这种情况下,我使用“可组合”来表示以下内容。假设配置了这些组 - GroupA(User1、User2、User3)、GroupB(User4、User5)和 GroupC(User1、User5)。可组合组将允许创建动态 GroupD (GroupA, GroupC),有效成员资格为 (User1, User2, User3, User5)。 理想情况下,GroupD 也可以定义为 (GroupA, GroupC, User6)。此外,理想情况下,您可以继续嵌套多于一层的组。
OpenLDAP 和 LAM 有一些工具似乎适用于这类事情,但我不断遇到模式问题、设计问题、实现问题或三者的某种组合。
dynlist - 这个 OpenLDAP 覆盖允许您基于 LDAP 过滤器即时填充属性列表。您甚至可以拥有由用户和其他组组成的混合组!不幸的是,覆盖仅在直接查看它所附加的实体时触发。这意味着
getent group [group]
(直接查看一个或多个组)有效,但groups [user]
(搜索用户在组中的存在)无效。nss
这使得如果不将您自己的映射层或其他 LDAP 使用者写入,就不可能基于动态组进行 SSH 。此外,可能出于类似原因,您无法从其他 dynlist 组创建 dynlist 组。memberof - 此 OpenLDAP 覆盖将自动更新
memberOf
用户的属性,以对应用户在组中的添加和删除。然而,它似乎需要使用基于 RFC2307 的类以外的组类posixGroup
,因为它memberof
需要基于 DN 的成员资格,而不是基于 uid 的成员资格。它实际上也无助于管理组本身。自动组 - 此OpenLDAP覆盖将自动从可配置属性中添加或删除用户 DN,对应于用户在可配置 LDAP 过滤器结果中的存在或不存在。这个覆盖似乎需要
memberof
安装,因为autogroup
除非我包含olcAGmemberOfAd
配置属性,否则安装会失败。它似乎也需要基于 DN 的成员资格,所以memberof
它需要一个基于 RFC2307 以外的类posixGroup
我最初尝试使用 class 实现静态组posixGroup (structural)
,并使用附加labeledURIObject
类来附加dynlist
过滤器的动态组。这基本上奏效了,但我遇到了dynlist
上面列出的缺点。
然后我尝试改用autogroup
覆盖,但遇到了似乎需要基于 DN 的成员资格的问题。在这一点上,我觉得我必须尝试摆脱posixGroup
结构类,因为似乎没有任何东西支持它。LAM似乎更喜欢使用 和 的组合groupOfNames
,因为它包含一个功能,当两个属性都存在于同一个对象上时RFC2307bis-posixGroup
,它可以自动member
将属性与属性同步。memberUid
所以我修改了posixAccount
OpenLDAP 附带的模式,使其成为辅助而不是结构,并使用groupOfNames
(结构)和修改的posixAccount
类创建组。破解 OpenLDAP 的objectClass
使用 RFC2307bis-esque 类来欺骗它的模式感觉就像 Not The Right Thing To Do™,但 OpenLDAP/LAM 似乎接受了它。这样做也使我能够memberof
成功安装,这很好。
autogroup
,但是,只有一半有效。虽然它会将用户添加到动态组(使用 可见groups [user]
),但在将用户从基本组中删除时不会将其删除。 groupOfNames
还要求其members
字段始终至少有一个用户在其中,这对于与autogroup
. 您必须使用初始设置它,但是一旦锁定属性member
就无法删除虚拟成员。autogroup
member
配置
cn=模块{0},cn=配置
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_mdb
olcModuleLoad: {1}ppolicy
olcModuleLoad: {2}autogroup
olcModuleLoad: {3}memberof
olcOverlay={1}memberof,olcDatabase={1}mdb,cn=config
dn: olcOverlay={1}memberof
objectClass: top
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcMemberOf
olcOverlay: {1}memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
olcOverlay{2}autogroup,olcDatabase={1}mdb,cn=config
olcOverlay: {2}autogroup
structuralObjectClass: olcAutomaticGroups
olcAGattrSet: {0}labeledURIObject labeledURI member
olcAGmemberOfAd: memberOf
问题
最具体到最少:
- 为什么
autogroup
能够将用户添加到动态组,但不能删除它们? - 有没有更简单的方法来实现这个用例?
- 我是否使用了错误的工具来完成这项工作?使用不同的 LDAP 实现、一些简单的客户端配置或完全非 LDAP 的东西,这个用例会更容易吗?
事实证明,这里最好的方法是让 LDAP 客户端完成繁重的工作:
我将组设置为在结构上
groupOfNames
由RFC2307bis-posixGroup
附加组成。由于我的环境不RFC2307bis-posixGroup
直接支持,我将一个 LDIF 放在一起,以使 OpenLDAP 删除其现有定义posixGroup
并用一个辅助副本替换它:不要按原样修改您的配置! 如果您选择走这条路,请找到您服务器的
posixGroup
配置,并将其与STRUCTURAL
更改为AUXILIARY
.然后服务器可以假装支持 RFC2307bis-posixGroup 规范。从那里,我能够添加 memberOf 并完成 OpenLDAP 配置。
关键是现代版本的 NSLCD 和 SSSD 都包含允许递归组搜索的标志。显然,此功能称为“嵌套”分组,这在 LDAP 目录结构的上下文中有点令人困惑,它还允许组相互嵌套。这些功能与 LDAP 结构无关,但是,它们是关于能够遵循对
groupOfNames
其他groupOfNames
.nslcd : nss_nested_groups是|否
sssd:ldap_group_nesting_level(整数)
有一些注意事项 - Red Hat 更喜欢您使用 SSSD,因此 Red Hat 存储库中的 nslcd 版本不足以支持该功能。但是这种方法应该适合大多数用例。最终,使用 sssd 或 nslcd 在所有服务器上重新配置标志比尝试让 OpenLDAP 自行进行“嵌套”分组要容易得多。
我现在可以在 LDAP 树中引用其他组中的组,
getent group
现在将列出每个组以及在组中直接引用或在引用组中递归引用的所有用户的扁平列表。