AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1109187
Accepted
miken32
miken32
Asked: 2022-08-27 09:13:50 +0800 CST2022-08-27 09:13:50 +0800 CST 2022-08-27 09:13:50 +0800 CST

OpenLDAP ACL 不合作

  • 772

我的服务器上有一个简单的 ACL,运行良好。我决定设置 SSSD 以通过 LDAP 验证用户登录,因此我需要授予对 SSSD 绑定帐户的更多访问权限。在此过程中,我以某种方式阻止了第一个 ACL 之外的所有访问;尽管breakACL {0} 末尾有语句,但不是根级别用户的每次搜索都会返回错误 32(找不到对象。)

数据库的结构大致如下:

organization: dc=r1,dc=internal
    organizationalUnit: ou=users,dc=r1,dc=internal
        inetOrgPerson: uid=mike,ou=users,dc=r1,dc=internal
    organizationalUnit: ou=groups,dc=r1,dc=internal
        groupOfUniqueNames: cn=root,ou=groups,dc=r1,dc=internal
        posixGroup: cn=mike,ou=groups,dc=r1,dc=internal
    organizationalUnit: ou=system,dc=r1,dc=internal
        inetOrgPerson: uid=sssd,ou=system,dc=r1,dc=internal

这是我的 ACL:

version: 1

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcAccess
# admin users can write anything in this subtree
# also the root SASL user (eg ldapmodify -QY EXTERNAL -H ldapi:/// ...)
# nobody else has access, but continue searching for matches below
olcAccess: {0}to dn.subtree="dc=r1,dc=internal"
  by anonymous break
  by group/groupOfUniqueNames/uniqueMember="cn=root,ou=groups,dc=r1,dc=internal" write
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
  by * break
# sssd user can read all user/group attributes
# other users keep looking
olcAccess: {1}to dn.onelevel="ou=users,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
olcAccess: {2}to dn.onelevel="ou=groups,dc=r1,dc=internal"
  by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
  by * break
# you can update your own password
# anonymous users can authenticate against it
# nobody else sees it
olcAccess: {3}to dn.subtree="dc=r1,dc=internal"
  attrs=userPassword
    by self write
    by anonymous auth
    by * none
# anonymous users can read select user/group attributes
olcAccess: {4}to dn.onelevel="ou=users,dc=r1,dc=internal"
  attrs=entry,cn,uid,sn,givenName,mail,telephoneNumber,mobile,memberOf
    by anonymous read
    by * break
olcAccess: {5}to dn.onelevel="ou=groups,dc=r1,dc=internal"
  attrs=entry,cn,description,uniqueMember,memberUid
    by anonymous read
    by * break
# all users can update their own records
# and see all other users' attributes
# everyone (including anonymous) can search
olcAccess: {6}to dn.onelevel="ou=users,dc=r1,dc=internal"
  by self write
  by users read
  by * search

这是带有额外 ACL 日志记录的日志提取:

Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: search access to "ou=users,dc=r1,dc=internal" "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [1] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] attr entry
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: access to entry "ou=users,dc=r1,dc=internal", attr "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: to all values by "uid=sssd,ou=system,dc=r1,dc=internal", (=0)
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: anonymous
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: cn=admin,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_group_pat: cn=root,ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => mdb_entry_get: found entry: "cn=root,ou=groups,dc=r1,dc=internal"
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: *
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] applying +0 (break)
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] mask: =0
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [2] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [3] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [4] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [4] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [5] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [6] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [7] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_get: done.
Aug 26 13:04:10 lemongrab slapd[3991]: => slap_access_allowed: no more rules
Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: no more rules

日志条目证实了我的怀疑,即在第一条规则之后没有做任何事情。例如,为什么它会从规则 1 跳到规则 4?根据我的理解,接下来应该考虑规则 2。

我已经尝试了 ACL 中的onelevel和范围,效果相同。children如果我将 ACL 更改为olcAccess: {1}to dn.subtree="dc=r1,dc=internal"它似乎可以工作,但除了用户和组之外还有其他 OU 我不想授予访问权限。我是否误解了范围的工作原理?

openldap
  • 1 1 个回答
  • 45 Views

1 个回答

  • Voted
  1. Best Answer
    larsks
    2022-08-27T18:18:22+08:002022-08-27T18:18:22+08:00

    更新我想通了!主要问题是文档很微妙。这是 dnstyle 限定符的描述slapd.access(5):

    <dnstyle>是可选的;但是,建议指定它以避免歧义。Base(的同义词baseObject)、默认值或exact(的别名base)表示DN等于的条目<dnpattern>;one(的同义词onelevel)表示紧接在下面的所有条目<dnpattern>,sub(的同义词subtree)表示在子树中的所有条目 <dnpattern>,children表示在下面(从属于)的所有条目<dnpattern>。

    关键点是仅dn.one授予对紧随其后的条目的访问权限。如果你写(就像你一样):<dnpattern>

    olcAccess: {1}to dn.onelevel="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    olcAccess: {2}to dn.onelevel="ou=groups,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    

    这将失败,因为dn.onelevel="ou=users,dc=r1,dc=internal" 不授予sssd用户访问 dn ou=users,dc=r1,dc=internal本身的权限。如果您在发出请求时查看 ACL 日志,您会看到如下内容:

    => access_allowed: search access to "ou=users,dc=r1,dc=internal" "entry" requested
    

    您没有授予此访问权限的规则,因此它失败了。我们需要添加授予对 ou 本身的访问权限的 ACL。这意味着替换这样的东西:

    olcAccess: to dn.onelevel="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    

    有了这个:

    # grant access to ou=users
    olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    # grant access to entries immediately below ou=users
    olcAccess: to dn.onelevel="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    

    (如果您不想读取 ou 本身的属性,可以在第一个 ACL 中替换read为。)searchsssd

    这是我在测试环境中设置的完整 ACL 集:

    dn: olcDatabase=mdb,cn=config
    objectClass: olcDatabaseConfig
    objectClass: olcMdbConfig
    olcDatabase: mdb
    olcSuffix: dc=r1,dc=internal
    olcDbDirectory: /var/lib/openldap/r1.internal
    # root has access to everything always
    olcAccess: to *
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
      by * break
    # root and members of cn=root group can access everything
    olcAccess: to dn.subtree="dc=r1,dc=internal"
      by anonymous break
      by group/groupOfUniqueNames/uniqueMember="cn=root,ou=groups,dc=r1,dc=internal" write
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
      by * break
    # sssd user can read all users
    olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    # sssd user can read all groups
    olcAccess: to dn.base="ou=groups,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    olcAccess: to dn.one="ou=groups,dc=r1,dc=internal"
      by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
      by * break
    # self can modify password, anon can authenticate
    olcAccess: to dn.subtree="dc=r1,dc=internal"
      attrs=userPassword
        by self write
        by anonymous auth
        by * none
    # anonymous can read selected user attributes
    olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
        by anonymous search
        by * break
    olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
      attrs=entry,cn,uid,sn
        by anonymous read
        by * break
    # anonymous can read selected group attributes
    olcAccess: to dn.base="ou=groups,dc=r1,dc=internal"
        by anonymous search
        by * break
    olcAccess: to dn.subtree="ou=groups,dc=r1,dc=internal"
      attrs=entry,cn,uniqueMember,objectClass
        by anonymous read
        by * break
    # self can modify own entry, authenticated users can
    # read all entries
    olcAccess: to dn.base="ou=users,dc=r1,dc=internal"
      by * search
    olcAccess: to dn.one="ou=users,dc=r1,dc=internal"
      by self write
      by users read
      by * search
    

    这行得通!使用这样的目录结构:

    dn: ou=users,dc=r1,dc=internal
      dn: cn=user1,ou=users,dc=r1,dc=internal
      dn: cn=user2,ou=users,dc=r1,dc=internal
      dn: ou=nested,ou=users,dc=r1,dc=internal
        dn: cn=user3,ou=nested,ou=users,dc=r1,dc=internal
    

    然后运行:

    ldapsearch -LLL -H ldap://localhost:3890 -x \
      -D uid=sssd,ou=system,dc=r1,dc=internal -w secret \
      -b ou=users,dc=r1,dc=internal dn
    

    产生:

    dn: ou=users,dc=r1,dc=internal
    
    dn: cn=user1,ou=users,dc=r1,dc=internal
    
    dn: cn=user2,ou=users,dc=r1,dc=internal
    
    dn: ou=nested,ou=users,dc=r1,dc=internal
    

    ...这正是我们想要的:sssd只能看到一个级别,并且看不到ou=nested. 如果我们以 组成员的身份执行相同的搜索root,我们现在可以看到:user3ou=nested

    dn: ou=users,dc=r1,dc=internal
    
    dn: cn=user1,ou=users,dc=r1,dc=internal
    
    dn: cn=user2,ou=users,dc=r1,dc=internal
    
    dn: ou=nested,ou=users,dc=r1,dc=internal
    
    dn: cn=user3,ou=nested,ou=users,dc=r1,dc=internal
    
    • 1

相关问题

  • OpenLDAP 无效凭证

  • 从 OpenLDAP 检索操作属性

  • 为 Mac 网络使用 Linux 和 Open LDAP

  • 使用LDAP服务器身份验证的Linux中单个用户的多个登录名

  • 将 OpenLDAP 实现为目录而不是控制网络访问的指南?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve