为 SSH 和 Samba 身份验证设置可组合 POSIX 组的最简单方法是什么?

为 SSH 和 Samba 身份验证设置可组合 POSIX 组的最简单方法是什么?

背景

我正在整合我认为相当普通的基础设施,但是遇到了太多问题,我不禁想知道是否有更简单的方法。


我需要能够执行以下操作:

  • 通过委派身份验证和基于组的权限,安全地将文件从 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 -> nslcdcoreutils -> libnss-ldapd -> nscd -> nslcd,因此getent passwdid [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 似乎接受了它。这样做还让我成功安装,这很好。memberUidposixAccountgroupOfNamesposixAccountobjectClassmemberof

autogroup但是,只有一半有效。虽然它会将用户添加到动态组(使用 可见groups [user]),但当用户从基组中删除时,它不会将其删除。 groupOfNames还要求其members字段始终至少有一个用户,这对于使用 来说有问题autogroup。您必须使用初始 进行设置,但一旦锁定属性member,就无法删除虚拟成员。autogroupmember


配置

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

问题

从最具体到最不具体:

  1. 为什么autogroup可以将用户添加到动态组,但不能将其删除?
  2. 有没有更简单的方法来实现这个用例?
  3. 我是否使用的工具不对?如果使用不同的 LDAP 实现、一些简单的客户端配置或完全非 LDAP 的配置,此用例是否会变得容易得多?

答案1

事实证明,最好的方法是让 LDAP 客户端承担繁重的工作:

我将组设置为在结构上由groupOfNamesRFC2307bis-posixGroup附加组成。由于我的环境不RFC2307bis-posixGroup直接支持,我整理了一个 LDIF,让 OpenLDAP 删除其现有的 定义posixGroup并将其替换为辅助副本:

请勿按原样修改您的配置! 如果您选择采用这条路线,请找到您的服务器配置,并将其与更改为的posixGroup等效配置进行交换。STRUCTURALAUXILIARY

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现在将列出每个组以及直接在组中引用的所有用户的扁平列表,或在引用的组内递归引用。

相关内容