背景
我正在整合我认为相当普通的基础设施,但是遇到了太多问题,我不禁想知道是否有更简单的方法。
我需要能够执行以下操作:
- 通过委派身份验证和基于组的权限,安全地将文件从 Linux 服务器共享给 OSX、Linux 和 Windows 计算机上的数百名用户。
- 允许基于组的 SSH 访问数十台 Linux 服务器,并具有委派身份验证和基于组的权限。
- 能够创建由其他组和用户组成的组,最好是任意深度。
- 能够允许自助完成基本任务(更改和恢复密码、有限地编辑自己的信息等)
- 能够以最少的配置迁移现有服务器(运行各种版本的 Linux)-因此尽可能坚持“标准”配置,尤其是客户端。
我希望能够选择执行以下操作:
- 除了基于密码的身份验证外,还支持公钥身份验证
在我看来,以上所有方案似乎都是 LDAP + Samba 唯一可行的方案,尤其是因为之前的实现使用了 FreeIPA/Samba。团队决定使用 OpenLDAP 和 LDAP 帐户管理器来提供身份验证和目录服务,但实现过程却是一场噩梦。
OpenLDAP 设置
我的目录树具有以下结构:
- dc=example,dc=com
- ou=groups
- cn=groupA
- ...
- ou=policies
- cn=passwordDefault
- ...
- ou=services
- cn=service1
- ...
- ou=users (
- uid=user1
- ...
用户有以下课程:
- inetOrgPerson (结构)
- posix帐户
- 影子账户
- sambaSam帐户
- 政策用户
- 密码自我重置
- ldap公钥
- 一般信息
用户使用效果很好。大多数 Linux 机器都在使用sshd -> libpam-ldap -> libnss-ldapd -> nscd -> nslcd
和coreutils -> libnss-ldapd -> nscd -> nslcd
,因此getent passwd
和id [username]
无需任何特殊配置即可运行。
服务有以下课程:
- 应用过程(结构)
- 简单安全对象
服务只是 Gitlab 等内部服务的简单 DN/pw 实体,可以直接联系 LDAP,这样我们就可以关闭匿名绑定而不切断它们。它们也运行良好。(注意 - 一些服务实际上需要作为 POSIX 帐户存在,因此为了简单起见,将它们配置为用户)
政策是诸如密码策略之类的实体,它们超出了本问题的范围。
群组才是真正的问题,因此我将在下一节详细讨论它们。
团体的问题
无论我做什么,似乎都无法创建符合 POSIX 标准的可组合组。在此上下文中,我使用“可组合”来表示以下含义。假设配置了这些组 - GroupA(用户 1、用户 2、用户 3)、GroupB(用户 4、用户 5)和 GroupC(用户 1、用户 5)。可组合组将允许创建动态 GroupD(GroupA、GroupC),其有效成员资格为(用户 1、用户 2、用户 3、用户 5)。 理想情况下,GroupD 也可以定义为 (GroupA, GroupC, User6)。另外,理想情况下您可以继续嵌套多层组。
OpenLDAP 和 LAM 有一些工具似乎是用于此类目的,但我一直遇到模式问题、设计问题、实施问题或三者的某种组合。
动态列表- 此 OpenLDAP 覆盖允许您根据 LDAP 过滤器动态填充属性列表。您甚至可以拥有由用户和其他组组成的混合组!不幸的是,覆盖仅在直接查看其附加到的实体时才会触发。这意味着
getent group [group]
(直接查看一个或多个组)有效,但groups [user]
(搜索组中用户的存在)无效。这使得无法基于动态组进行 SSH,而无需将您自己的映射层写入nss
或其他 LDAP 消费者。此外,可能出于类似的原因,您无法从其他 dynlist 组创建 dynlist 组。成员- 此 OpenLDAP 覆盖将自动更新
memberOf
用户的属性,以对应用户添加到组和从组中删除。posixGroup
但是,它似乎需要使用除基于 RFC2307 的类之外的组类,因为它memberof
需要基于 DN 的成员资格,而不是基于 uid 的成员资格。它实际上也无助于管理组本身。自动分组- 此 OpenLDAP 覆盖将自动从可配置属性中添加或删除用户 DN,与用户在可配置 LDAP 过滤器结果中的存在或不存在相对应。此覆盖似乎需要安装
memberof
,因为autogroup
除非我包含配置属性,否则安装会失败olcAGmemberOfAd
。它似乎还需要基于 DN 的成员资格,因此memberof
它需要一个基于 RFC2307 以外的类posixGroup
我最初尝试使用类来实现静态组posixGroup (structural)
,并使用附加类来实现动态组labeledURIObject
以附加dynlist
过滤器。这基本上是可行的,但我遇到了dynlist
上面概述的缺点。
然后我尝试使用autogroup
覆盖,但遇到了一个问题,它似乎需要基于 DN 的成员资格。此时,我觉得我必须尝试摆脱posixGroup
结构类,因为似乎没有任何东西可以支持它。 LAM似乎更喜欢groupOfNames
使用和的组合RFC2307bis-posixGroup
,因为它包含一个功能,当属性和属性同时存在于同一对象上时,可以自动同步member
属性和属性。因此,我修改了OpenLDAP 附带的架构,使其成为辅助架构而不是结构架构,并使用(结构) 和 修改的类创建了组。破解 OpenLDAP 的架构,用 RFC2307bis-esque 类来欺骗它,感觉不是正确的做法™,但 OpenLDAP/LAM 似乎接受了它。这样做还让我成功安装,这很好。memberUid
posixAccount
groupOfNames
posixAccount
objectClass
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}自动组,olcDatabase={1}mdb,cn=config
olcOverlay: {2}autogroup
structuralObjectClass: olcAutomaticGroups
olcAGattrSet: {0}labeledURIObject labeledURI member
olcAGmemberOfAd: memberOf
问题
从最具体到最不具体:
- 为什么
autogroup
可以将用户添加到动态组,但不能将其删除? - 有没有更简单的方法来实现这个用例?
- 我是否使用的工具不对?如果使用不同的 LDAP 实现、一些简单的客户端配置或完全非 LDAP 的配置,此用例是否会变得容易得多?
答案1
事实证明,最好的方法是让 LDAP 客户端承担繁重的工作:
我将组设置为在结构上由groupOfNames
和RFC2307bis-posixGroup
附加组成。由于我的环境不RFC2307bis-posixGroup
直接支持,我整理了一个 LDIF,让 OpenLDAP 删除其现有的 定义posixGroup
并将其替换为辅助副本:
请勿按原样修改您的配置! 如果您选择采用这条路线,请找到您的服务器配置,并将其与更改为的posixGroup
等效配置进行交换。STRUCTURAL
AUXILIARY
dn: cn={2}nis,cn=schema,cn=config
changetype: modify
delete: olcObjectClasses
olcObjectClasses: {2}( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top STRUCTURAL MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description ) )
-
add: olcObjectClasses
olcObjectClasses: {2}( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top AUXILIARY MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description ) )
然后服务器就可以假装支持 RFC2307bis-posixGroup 规范。从那里,我能够添加 memberOf 并完成 OpenLDAP 配置。
关键在于,NSLCD 和 SSSD 的现代版本都包含允许递归组搜索的标志。显然,此功能称为“嵌套”分组,这在 LDAP 目录结构的上下文中有点令人困惑,因为 LDAP 目录结构还允许组相互嵌套。然而,这些功能与 LDAP 结构无关,而是与能够跟踪groupOfNames
其他 内部的引用有关groupOfNames
。
韓國:nss_nested_groups是|否
如果设置了此选项,则群组的成员属性可能指向另一个群组。嵌套群组的成员也会在更高级别的群组中返回,并且在查找特定用户的群组时会返回父群组。默认不会对嵌套群组执行额外搜索。
ssd 的:ldap_group_nesting_level(整数)
如果 ldap_schema 设置为支持嵌套组的架构格式(例如 RFC2307bis),则此选项控制 SSSD 将遵循多少层嵌套。此选项对 RFC2307 架构没有影响。默认值:2
有一些注意事项 - Red Hat 更希望您使用 SSSD,因此 Red Hat 存储库中的 nslcd 版本不够新,无法支持该功能。但这种方法应该适合大多数用例。最终,在所有使用 sssd 或 nslcd 的服务器上重新配置标志很多比尝试让 OpenLDAP 自行进行“嵌套”分组更容易。
我现在可以引用 LDAP 树中其他组中的组,并且 getent group
现在将列出每个组以及直接在组中引用的所有用户的扁平列表,或在引用的组内递归引用。