Sun Java System Directory Server Enterprise Edition 6.3 管理指南

第 7 章 目录服务器访问控制

对目录访问的控制是创建安全目录不可或缺的一部分。本章介绍访问控制指令 (Access Control Instruction, ACI),这些指令用于确定要为访问目录的用户授予哪些权限。

请在目录部署的规划阶段定义符合总体安全策略的访问控制策略。有关规划访问控制策略的提示,请参见《Sun Java System Directory Server Enterprise Edition 6.3 Deployment Planning Guide》

有关 ACI 的其他信息(包括 ACI 语法和绑定规则),请参见《Sun Java System Directory Server Enterprise Edition 6.3 Reference》

本章包含以下主题:

创建、查看和修改 ACI

可以通过使用目录服务控制中心 (Directory Service Control Center, DSCC) 或命令行创建 ACI。无论选择哪种方法,查看并复制现有 ACI 值通常比从头创建新 ACI 更容易。

可以在 DSCC 中查看和修改 aci 属性值。有关如何通过 DSCC 修改 ACI 的信息,请参见 DSCC 联机帮助。

Procedure创建、修改和删除 ACI

要使用命令行创建 ACI,应首先使用 LDIF 语句在文件中创建 ACI。然后通过使用 ldapmodify 命令将 ACI 添加到您的目录树中。

可使用 DSCC 执行此任务。有关信息,请参见目录服务控制中心界面和 DSCC 联机帮助。

  1. 在 LDIF 文件中创建 ACI。


    dn: dc=example,dc=com
    changetype: modify
    add: aci
    aci: (target)(version 3.0; acl "name";permission bindrules;)

    此示例说明如何添加 ACI。要修改或删除 ACI,请将 add 替换为 replacedelete

    有关常用 ACI 的更多示例,请参见访问控制使用示例

  2. 使用 LDIF 文件进行更改。


    $ ldapmodify -h host -p port -D cn=admin,cn=Administrators,cn=config -w - -f ldif-file
    

Procedure查看 ACI 属性值

ACI 作为条目的一个或多个 aci 属性值进行存储。aci 属性为多值操作属性,可由目录用户读取和修改。因此,ACI 属性自身应受 ACI 保护。管理用户通常具有 aci 属性的完全访问权限。

可使用 DSCC 执行此任务。有关信息,请参见目录服务控制中心界面和 DSCC 联机帮助。

  1. 通过运行以下 ldapsearch 命令查看条目的 ACI 属性值:


    $ ldapsearch -h host -p port -D cn=admin,cn=Administrators,cn=config -w - \
     -b entryDN -s base "(objectclass=*)" aci

    结果为 LDIF 文本,可将其复制到新的 LDIF ACI 定义以进行编辑。由于 ACI 的值是一个长字符串,因此 ldapsearch 操作的输出可能会以多行显示。此外,第一个空格为连续标记。如果不希望 LDIF 输出包含连续标记,请使用 -T 选项。复制和粘贴 LDIF 输出时应考虑输出格式。


    注 –

    要查看 aci 值所授予和拒绝的权限,请参见查看有效权限


Procedure查看根级别的 ACI

创建后缀时,将在顶级或根级别上创建一些默认 ACI。这些 ACI 允许默认管理用户 cn=admin,cn=Administrators,cn=config 具有与目录管理员相同的目录数据访问权限。

可使用 DSCC 执行此任务。有关信息,请参见目录服务控制中心界面和 DSCC 联机帮助。

  1. 查看默认的根级别 ACI。


    $ ldapsearch -h host -p port -D cn=admin,cn=Administrators,cn=config -w - \
     -b "" -s base "(objectclass=*)" aci

访问控制使用示例

本部分中的示例说明了一家虚构的 ISP 公司 Example.com 如何实现其访问控制策略。

此外,您也可以在随安装提供的示例 LDIF 文件 (install_path/ds6/ldif/Example.ldif) 中找到 ACI 示例。

所有示例都说明如何使用 LDIF 文件执行给定任务。下图以图形方式显示了 example.com 目录信息树。

示例目录树的剖析图。图中显示了顶级条目以及直接位于顶级条目下的条目。

Example.com 提供了 Web 托管服务和 Internet 访问。Example.com 的部分 Web 托管服务用于托管客户端公司的目录。Example.com 实际上托管并部分管理两家中型公司(Company333 和 Company999)的目录。此外,Example.com 还提供对大量单个订户的 Internet 访问。

Example.com 希望制定以下访问规则:

授予匿名访问权限

大多数目录都配置为至少允许您匿名访问一个后缀,以进行读取、搜索或比较。如果要运行公司人员目录(如可供员工搜索的电话薄),则可能需要设置这些权限。Example.com 内部即为这种情况,如ACI "Anonymous Example.com"中所示。

作为 ISP,Example.com 还要创建允许所有人访问的公共电话薄,以提供其所有订户的联系信息。相关内容如ACI "Anonymous World"所述。

ACI "Anonymous Example.com"

在 LDIF 中,要为 Example.com 员工授予对整个 Example.com 树的读取、搜索和比较权限,可编写以下语句:


aci: (targetattr !="userPassword")(version 3.0; acl "Anonymous
 example"; allow (read, search, compare)
 userdn= "ldap:///anyone") ;)

本示例假定将 aci 添加到 dc=example,dc=com 条目中。请注意,userPassword 属性被排除在 ACI 范围之外。


注 –

请使用与密码属性保护示例中所用的相同语法来保护保密属性和不应显示的属性,即 (targetattr !="attribute-name ")


ACI "Anonymous World"

在 LDIF 中,要为所有人授予对单个订户子树的读取和搜索访问权限,但不允许访问未列出订户的信息,可编写以下语句:


aci: (targetfilter= "(!(unlistedSubscriber=yes))")
 (targetattr="homePostalAddress || homePhone || mail")
 (version 3.0; acl "Anonymous World"; allow (read, search)
 userdn="ldap:///anyone";)

此示例假定 ACI 已添加到 ou=subscribers,dc=example, dc=com 条目中。此示例还假定每个订户条目都具有 unlistedSubscriber 属性(设置为 yesno)。目标定义将根据此属性的值过滤掉未列出的订户。有关过滤器定义的详细信息,请参阅使用过滤设置目标

授予对个人条目的写入访问权限

许多目录管理者都允许内部用户更改其自身条目中的部分(而非全部)属性。Example.com 的目录管理者允许用户更改自身的密码、家庭电话号码和家庭地址,但不允许更改其他内容。相关内容如ACI "Write Example.com"所述。

Example.com 还有一条策略,即,如果订户建立到目录的 SSL 连接,则允许订户在 Example.com 树中更新自身的个人信息。相关内容如ACI "Write Subscribers"所述。

ACI "Write Example.com"


注 –

通过设置此权限,还可以为用户授予删除属性值的权限。


在 LDIF 中,要为 Example.com 员工授予更新其家庭电话号码和家庭地址的权限,可编写以下语句:


aci: (targetattr="homePhone ||
 homePostalAddress")(version 3.0; acl "Write Example.com";
 allow (write) userdn="ldap:///self" ;)

此示例假定 ACI 已添加到 ou=People,dc=example,dc=com 条目中。

ACI "Write Subscribers"


注 –

通过设置此权限,还可以为用户授予删除属性值的权限。


在 LDIF 中,要为 Example.com 订户授予更新其家庭电话号码的权限,可编写以下语句:


aci: (targetattr="homePhone")
 (version 3.0; acl "Write Subscribers"; allow (write)
 userdn= "ldap://self" and authmethod="ssl";)

此示例假定 aci 已添加到 ou=subscribers,dc=example, dc=com 条目中,并且用户必须使用 SSL 进行绑定。

请注意,Example.com 订户对其家庭地址没有写入访问权限,因为他们可能会删除该属性。家庭地址是 Example.com 寄发帐单时所需的重要业务信息。

授予对特定级别的访问权限

可以通过设置 ACI 的范围来影响目录树中的不同级别,以便对您所允许的访问权限级别进行微调。可将目标 ACI 范围设置为以下任一选项:

base

条目自身

onelevel

条目自身及其下一级的所有条目

subtree

条目自身及其下面的所有条目(不限制深度)

ACI "Read Example.com only"

在 LDIF 中,要为 Example.com 订户授予读取 dc=example,dc=com 条目的权限(以获取公司联系信息),但不允许访问该条目下的任何条目,可编写以下语句:


aci: (targetscope="base") (targetattr="*")(version 3.0;
 acl "Read Example.com only";  allow (read,search,compare)
 userdn="ldap:///cn=*,ou=subscribers,dc=example,dc=com";)

此示例假定 ACI 已添加到 dc=example, dc=com 条目中。

限制对重要角色的访问权限

您可以在目录中使用角色定义,以标识对业务至关重要的功能,如网络和目录管理。

例如,您可以通过标识系统管理员的某个子集来创建超级管理员 (superAdmin) 角色,这些管理员于每周特定日期的特定时间在全球公司站点上可用。或者,您也可以创建急救员 (First Aid) 角色,其中包括特定站点中所有受过急救培训的工作人员。有关创建角色定义的信息,请参见管理角色

当某个角色在重要的公司或业务功能方面可提供任何种类的用户特权时,应考虑限制对该角色的访问权限。例如,在 Example.com 中,员工可以向自身条目中添加除超级管理员 (superAdmin) 角色之外的任何角色,如以下示例所示。

ACI "Roles"

在 LDIF 中,要为 Example.com 员工授予在自身条目中添加除超级管理员 (superAdmin) 之外的任何角色的权限,可编写以下语句:


aci: (targetattr="*") (targattrfilters="add=nsRoleDN:
 (nsRoleDN !="cn=superAdmin, dc=example, dc=com")")
 (version 3.0; acl "Roles"; allow (write)
 userdn= "ldap:///self" ;)

此示例假定 ACI 已添加到 ou=People,dc=example, dc=com 条目中。

为角色授予对整个后缀的完全访问权限

有时,针对某个后缀为特定用户授予与目录管理员相同的权限是非常有用的。在 Example.com 中,Kirsten Vaughan 是目录服务器管理员。她具有超级管理员 (superAdmin) 角色。此角色具有以下优点:


注 –

将 Kirsten Vaughan 添加到 cn=Administrators,cn=config 组还会为她授予与目录管理员相同的权限。


要使用户对整个服务器具有与目录管理员相同的权限,请执行创建具有超级用户权限的管理用户中的过程。

ACI "Full Access"

在 LDIF 中,要为管理员 Kirsten Vaughan 授予与目录管理员相同的权限,请使用以下语句:


aci: (targetattr="*") (version 3.0; acl "Full Access";
 allow (all) groupdn= "ldap:///cn=SuperAdmin,dc=example,dc=com"
 and authmethod="ssl" ;)

此示例假定 ACI 已添加到根条目 ""(无文本)中。

为组授予对后缀的完全访问权限

大多数目录都有用于标识特定公司功能的组。可以为组授予对部分或全部目录的访问权限。通过将访问权限应用于组,可以避免单独为每个成员设置访问权限。可以通过将用户添加到组来为这些用户授予访问权限。

例如,在创建目录服务器实例时,默认情况下将创建一个管理员组 cn=Administrators,cn=config,此组具有目录的完全访问权限。

在 Example.com 中,人力资源组对目录的 ou=People 分支具有完全访问权限,这样他们可以更新员工目录,如ACI "HR"中所示。

ACI "HR"

在 LDIF 中,要为人力资源组授予对目录员工分支的所有权限,请使用以下语句:


aci: (targetattr="*") (version 3.0; acl "HR"; allow (all)
  groupdn= "ldap:///cn=HRgroup,ou=Groups,dc=example,dc=com";)

此示例假定 ACI 已添加到以下条目中:


ou=People,dc=example,dc=com

授予添加和删除组条目的权限

某些组织允许员工在树中创建条目,以提高员工的工作效率,并鼓励员工为公司活力注入一己之力。例如,在 Example.com 中,Social Committee 由网球、游泳、滑雪和角色扮演等各种俱乐部组成。

任何 Example.com 员工都可以创建代表新俱乐部的组条目,如ACI "Create Group"中所示。

任何 Example.com 员工都可以成为其中某个组的成员,如允许用户在组中添加或删除自身中所示。

只有组的所有者才能修改或删除组条目,如ACI "Delete Group"中所示。

ACI "Create Group"

在 LDIF 中,要为 Example.com 员工授予在 ou=Social Committee 分支下创建组条目的权限,可编写以下语句:


aci: (targetattr="*") (targattrfilters="add=objectClass: 
(|(objectClass=groupOfNames)(objectClass=top))") 
(version 3.0; acl "Create Group"; allow (read,search,add) 
userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") 
and dns="*.Example.com";)

此示例假定 ACI 已添加到 ou=Social Committee,dc=example,dc=com 条目中。


注 –

ACI "Delete Group"

在 LDIF 中,要为 Example.com 员工授予相应权限,以修改或删除其所属组(在 ou=Social Committee 分支下)的组条目,可编写以下语句:


aci: (targetattr = "*") (targattrfilters="del=objectClass:
(objectClass=groupOfNames)")
 (version 3.0; acl "Delete Group"; allow (write,delete)
 userattr="owner#GROUPDN";)

此示例假定 aci 已添加到 ou=Social Committee,dc=example,dc=com 条目中。

请注意,使用 DSCC 创建此 ACI 不是有效方式,因为您必须使用手动编辑模式创建目标过滤器,并检查组的所有权。

允许用户在组中添加或删除自身

许多目录都设置了允许用户在组中(如邮件列表)添加或删除自身的 ACI。

在 Example.com 中,员工可以将自身添加到 ou=Social Committee 子树下的任何组条目中,如ACI "Group Members"中所示。

ACI "Group Members"

在 LDIF 中,要为 Example.com 员工授予将自身添加到组的权限,可编写以下语句:


aci: (targettattr="member")(version 3.0; acl "Group Members";
 allow (selfwrite)
 (userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") ;)

此示例假定 ACI 已添加到 ou=Social Committee, dc=example,dc=com 条目中。

为组或角色授予条件访问权限

在许多情况下,当您为组或角色授予对目录的访问特权时,必须确保入侵者无法模拟特权用户使用这些特权。因此,在许多情况下,为组或角色授予重要访问权限的访问控制规则通常与许多条件相关联。

例如,Example.com 为其每个托管公司(Company333 和 Company999)创建了一个目录管理者角色。Example.com 希望这两家公司能够管理各自的数据并实现各自的访问控制规则,同时又能确保数据不受侵犯。

因此,如果满足以下条件,Company333 和 Company999 将对其各自的目录树分支具有完全权限。

这些条件将在每个公司的某个 ACI(ACI "Company333" 和 ACI "Company999")中列出。由于两个 ACI 的内容相同,因此以下示例只使用 "Company333" ACI。

ACI "Company333"

在 LDIF 中,要在满足上述条件的情况下为 Company333 授予对其目录分支的完全访问权限,可编写以下语句:


aci: (targetattr = "*") (version 3.0; acl "Company333"; allow (all)
 (roledn="ldap:///cn=DirectoryAdmin,ou=Company333,
 ou=corporate clients,dc=example,dc=com") and (authmethod="ssl")
 and (dayofweek="Mon,Tues,Wed,Thu") and (timeofday >= "0800" and
 timeofday <= "1800") and (ip="255.255.123.234"); )

此示例假定 ACI 已添加到 ou=Company333,ou=corporate clients,dc=example,dc=com 条目中。

拒绝访问

如果您已经允许对后缀的大部分进行访问,则您可能希望在现有的 ACI 下拒绝对后缀的较小部分进行访问。


注 –

应尽可能避免拒绝访问,因为它可能会导致意外或复杂的访问控制行为。可以结合使用作用域、属性列表、目标过滤器等来限制访问权限。

此外,删除拒绝访问 ACI 不会删除权限,但会扩展其他 ACI 所设置的权限。


当目录服务器评估访问权限时,它将首先读取 deny 权限,然后再读取 allow 权限。

在后面的示例中,Example.com 希望所有订户都能读取自身条目下的帐单信息,如连接时间或帐户余额。Example.com 也明确希望拒绝对该信息的写入访问权限。读取访问权限将在ACI "Billing Info Read"中进行介绍。拒绝访问权限将在ACI "Billing Info Deny"中进行介绍。

ACI "Billing Info Read"

在 LDIF 中,要为订户授予读取自身条目中的帐单信息的权限,可编写以下语句:


aci: (targetattr="connectionTime || accountBalance")
 (version 3.0; acl "Billing Info Read"; allow (search,read)
  userdn="ldap:///self";)

此示例假定已在模式中创建了相关属性,并且 ACI 已添加到 ou=subscribers,dc=example,dc=com 条目中。

ACI "Billing Info Deny"

在 LDIF 中,要拒绝订户修改自身条目中的帐单信息的权限,可编写以下语句:


aci: (targetattr="connectionTime || accountBalance")
 (version 3.0; acl "Billing Info Deny";
 deny (write) userdn="ldap:///self";)

此示例假定已在模式中创建了相关属性,并且 ACI 已添加到 ou=subscribers,dc=example,dc=com 条目中。

代理授权

代理授权方法是一种特殊形式的验证。通过代理授权,可为使用自身标识绑定到目录的用户授予其他用户的权限。

要将目录服务器配置为允许代理请求,必须执行以下操作:


注 –

您可以将代理权限授予除目录管理员之外的任何目录用户。此外,您无法将目录管理员的 DN 用作代理 DN。授予代理权限时应特别小心,因为授予此权限可将任何 DN(目录管理员 DN 除外)指定为代理 DN。如果目录服务器在同一操作中收到多个代理验证控制,则会向客户端应用程序返回错误,并且操作尝试将会失败。


示例代理授权

对于 LDAP 数据,Example.com 希望绑定为 MoneyWizAcctSoftware 的客户端应用程序具有与帐户管理员相同的访问权限。

将应用以下参数:

要使客户端应用程序获取对帐户子树的访问权限(通过使用与帐户管理员相同的访问权限),必须满足以下条件:

正确使用此 ACI 之后,MoneyWizAcctSoftware 客户端应用程序即可绑定到目录,然后发送需要代理 DN 访问权限的 LDAP 命令,如 ldapsearchldapmodify

在此示例中,如果客户端要执行 ldapsearch 命令,则此命令将包括以下控制:


$ ldapsearch -D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \
 -Y "dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com" ...

如果客户端要执行 ldapmodify 命令,则此命令将包括以下控制:


$ ldapmodify -h hostname -p port \
-D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \
-Y"dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com"
dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com
changetype: modify
delete: userpassword
-
add: userpassword
userpassword: admin1

请注意,客户端以自身标识进行绑定,但被授予代理条目的特权。客户端不需要代理条目的密码。

使用过滤设置目标

如果要设置允许访问目录中大量条目的访问控制,则可以使用过滤器设置目标。

在 LDIF 中,要通过过滤器允许人力资源部门的所有用户访问员工条目,可编写以下语句:


aci: (targetattr="*") (targetfilter=(objectClass=employee))
 (version 3.0; acl "HR access to employees";
 allow (all) groupdn= "ldap:///cn=HRgroup,ou=People,dc=example,dc=com";)

此示例假定 ACI 已添加到 ou=People,dc=example,dc=com 条目中。


注 –

由于搜索过滤器不直接指出要管理访问权限的对象的名称,因此在允许或拒绝对象的访问权限时,请勿弄错对象。如果不慎允许或拒绝了错误对象的访问权限,则随着目录变得越来越复杂,风险将会越来越大。此外,使用过滤器时,您可能难以对目录中的访问控制问题进行故障排除。


为包含逗号的 DN 定义权限

需要在 LDIF ACI 语句中对包含逗号的 DN 进行特殊处理。在 ACI 语句的目标和绑定规则部分,必须使用单个反斜杠 (\) 来转义逗号。以下示例对此语法进行了说明:


dn: o=Example.com Bolivia\, S.A. 
objectClass: top 
objectClass: organization 
aci: (target="ldap:///o=Example.com Bolivia\,S.A.") (targetattr="*") 
(version 3.0; acl "aci 2"; allow (all) groupdn = 
"ldap:///cn=Directory Administrators, o=Example.com Bolivia\, S.A.";)

查看有效权限

维护目录中条目的访问策略时,您需要了解所定义的 ACI 对安全性的影响。目录服务器允许您评估现有 ACI,方法是查看 ACI 针对给定条目为给定用户授予的有效权限。

目录服务器会对“获得有效的权限”控制做出响应,可在搜索操作中包含此控制。对此控制的响应是在搜索结果中返回有关条目和属性的有效权限信息。此额外信息包括每个条目及其每个属性的读写权限。可以为用于搜索的绑定 DN 或任意 DN 请求这些权限。此功能允许管理员测试目录用户的权限。

有效权限功能依赖于 LDAP 控制。必须确保用于绑定到远程服务器的代理标识也可以访问这些有效权限属性。

限制对“获得有效的权限”控制的访问权限

查看有效权限的操作是一种目录操作,必需对该操作进行保护和适当地限制。

要限制对有效权限信息的访问权限,请修改 getEffectiveRights 属性的默认 ACI。然后为 getEffectiveRightsInfo 属性创建新的 ACI。

例如,以下 ACI 只允许目录管理者组的成员获得有效权限:


aci: (targetattr != "aci")(version 3.0; acl
 "getEffectiveRights"; allow(all) groupdn =
 "ldap:///cn=Directory Administrators,ou=Groups,dc=example,dc=com";)

要获取有效权限信息,您必需具有使用有效权限控制的访问控制权限,并且具有对 aclRights 属性的读取权限。这种双层访问控制提供了可在必要时进一步微调的基本安全性。与代理类似,如果您对某个条目中的 aclRights 属性具有读取访问权限,则可以请求任何人对于该条目及其属性的权限信息。这表明管理资源的用户可以确定具有该资源权限的人员,即使此用户实际上并不管理具有这些权限的人员。

如果请求权限信息的用户没有使用有效权限控制的权限,则此操作将会失败,并返回错误消息。但是,如果请求权限信息的用户具有使用此控制的权限,但没有读取 aclRights 属性的权限,则 aclRights 属性不会出现在返回的条目中。此行为反映了目录服务器的常规搜索行为。

使用“获得有效的权限”控制

通过在 ldapsearch 命令中使用 -J "1.3.6.1.4.1.42.2.27.9.5.2" 选项可指定“获得有效的权限”控制。默认情况下,此控制将在搜索结果中返回绑定 DN 对条目和属性的有效权限。

可使用以下选项更改默认行为:


注 –

aclRightsaclRightsInfo 属性的行为与虚拟操作属性类似。这些属性并未存储在目录中,如果未经明确请求,将不会返回这些属性。它们是由目录服务器在响应“获得有效的权限”控制时生成的。

因此,这些属性无法用在任何类型的过滤器或搜索操作中。


有效权限功能继承了影响访问控制的其他参数。这些参数包括时间、验证方法、计算机地址和名称。

以下示例说明用户 Carla Fuente 如何查看她在目录中的权限。在结果中,1 表示授予权限,0 表示拒绝权限。


$ ldapsearch -J "1.3.6.1.4.1.42.2.27.9.5.2 -h host1.Example.com -p 389 \
 -D "uid=cfuente,ou=People,dc=example,dc=com" -w - -b "dc=example,dc=com" \
 "(objectclass=*)" aclRights
Enter bind password:
dn: dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=Groups, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Accounting Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=HR Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=bjensen,ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

此结果为 Carla Fuente 显示了她在目录中至少具有读取权限的条目,并表明她可以修改自身的条目。有效权限控制不会避开普通访问权限,因此用户看不到他们没有读取权限的条目。在以下示例中,目录管理员可以看到 Carla Fuente 没有读取权限的条目:


$ ldapsearch -h host1.Example.com -p 389 -D cn=admin,cn=Administrators,cn=config -w - \
 -c "dn: uid=cfuente,ou=People,dc=example,dc=com" -b "dc=example,dc=com" \
 "(objectclass=*)" aclRights
Enter bind password:
dn: dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=Groups, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Directory Administrators, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0
dn: ou=Special Users,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0
dn: ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Accounting Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=HR Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=bjensen,ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

在前面的输出中,目录管理员可以看出 Carla Fuente 甚至无法查看目录树的 Special Users 和 Directory Administrators 分支。在以下示例中,目录管理员可以看出 Carla Fuente 无法修改其自身条目中的 mailmanager 属性:


$ ldapsearch -h host1.Example.com -p 389 -D cn=admin,cn=Administrators,cn=config -w - \
 -c "dn: uid=cfuente,ou=People,dc=example,dc=com" -b "dc=example,dc=com" \
 "(uid=cfuente)" aclRights "*"
Enter bind password:
version: 1
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;attributeLevel;mail: search:1,read:1,compare:1,
 write:0,selfwrite_add:0,selfwrite_delete:0,proxy:0
mail: cfuente@Example.com
aclRights;attributeLevel;uid: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
uid: cfuente
aclRights;attributeLevel;givenName: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
givenName: Carla
aclRights;attributeLevel;sn: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
sn: Fuente
aclRights;attributeLevel;cn: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
cn: Carla Fuente
aclRights;attributeLevel;userPassword: search:0,read:0,
 compare:0,write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
userPassword: {SSHA}wnbWHIq2HPiY/5ECwe6MWBGx2KMiZ8JmjF80Ow==
aclRights;attributeLevel;manager: search:1,read:1,compare:1,
 write:0,selfwrite_add:0,selfwrite_delete:0,proxy:0
manager: uid=bjensen,ou=People,dc=example,dc=com
aclRights;attributeLevel;telephoneNumber: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
telephoneNumber: (234) 555-7898
aclRights;attributeLevel;objectClass: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0

高级访问控制:使用宏 ACI

使用重复目录树结构的组织可以通过宏来优化目录中所使用的 ACI 的数量。如果减少目录树中的 ACI 数,将更容易管理访问控制策略。此外,还会提高 ACI 内存使用的效率。

是一种占位符,用于在 ACI 中表示 DN 或 DN 的一部分。可以使用宏来表示 ACI 目标部分和/或绑定规则部分中的 DN。实际上,当目录服务器收到传入的 LDAP 操作时,将根据 LDAP 操作的目标资源对 ACI 宏进行匹配。进行匹配的目的是为了找出匹配的子串(如果有)。如果存在匹配项,将使用匹配的子串扩展绑定规则端的宏,并通过评估已扩展的绑定规则来确定对资源的访问权限。

本部分包含宏 ACI 的示例和有关宏 ACI 语法的信息。

宏 ACI 示例

使用示例说明宏 ACI 的优点及其工作方式最为清楚。图 7–1显示了一个目录树,您可以在该目录树中使用宏 ACI 来有效减少 ACI 的总数。

请注意,在此图例中,相同的树结构 (ou=groups,ou=people) 具有重复的子域模式。此模式在整个树中也是重复的,因为 Example.com 目录树存储两个后缀 dc=hostedCompany2,dc=example,dc=comdc=hostedCompany3,dc=example,dc=com(图中未显示)。

目录树中的 ACI 也具有重复的模式。例如,以下 ACI 位于 dc=hostedCompany1,dc=example,dc=com 节点上:


aci: (targetattr="*")
 (targetfilter=(objectClass=nsManagedDomain))(version 3.0;
 acl "Domain access"; allow (read,search) groupdn=
 "ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,
 dc=example,dc=com";)

此 ACI 为 domainAdmins 组授予对 dc=hostedCompany1,dc=example,dc=com 树中任何条目的读取和搜索权限。

图 7–1 宏 ACI 的示例目录树

示例目录树的剖析图,其中显示了 dc=hostedcompany1,dc=example,dc=com 和各个子域。

以下 ACI 位于 dc=hostedCompany1,dc=example,dc=com 节点上:


aci: (targetattr="*")
 (targetfilter=(objectClass=nsManagedDomain))
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com";)

以下 ACI 位于 dc=subdomain1,dc=hostedCompany1, dc=example,dc=com 节点上:


aci: (targetattr="*")
 (targetfilter=(objectClass=nsManagedDomain))
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany1,
  dc=example,dc=com";)

以下 ACI 位于 dc=hostedCompany2,dc=example,dc=com 节点上:


aci: (targetattr="*")
 (targetfilter=(objectClass=nsManagedDomain))
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany2, dc=example,dc=com";)

以下 ACI 位于 dc=subdomain1,dc=hostedCompany2, dc=example,dc=com 节点上:


aci: (targetattr="*")
 (targetfilter=(objectClass=nsManagedDomain))
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany2,
 dc=example,dc=com";)

在上述四个 ACI 中,唯一的不同之处是在 groupdn 关键字中指定的 DN。通过为 DN 使用宏,可以在树的根部(即 dc=example,dc=com 节点上)使用一个 ACI 替换这些 ACI。此宏 ACI 如下所示:


aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com")
 (targetattr="*")(targetfilter=(objectClass=nsManagedDomain))
 (version 3.0; acl "Domain access"; allow (read,search) 
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=com";)

请注意,此时需要使用之前未使用的关键字 target

在上述示例中,ACI 的数量从四个减少到一个。但其真正的好处取决于您在整个目录树中的重复模式数。

宏 ACI 语法

为了简便起见,本部分将用于提供绑定凭证的 ACI 关键字(如 userdnroledngroupdnuserattr)统称为 ACI 的主题。主题可确定应用 ACI 的对象。

下表显示可用于替换特定 ACI 关键字的宏。

表 7–1 宏 ACI 关键字

宏 

描述 

ACI 关键字 

($dn)

用于在目标中进行匹配,并在主题中直接替换。 

target、targetfilter、userdn、roledn、groupdn、userattr

[$dn]

用于替换在主题的子树中使用的多个 RDN。 

targetfilter、userdn、roledn、groupdn、userattr

($attr.attrName)

用于将目标条目中的 attributeName 属性值替换到主题中。

userdn、roledn、groupdn、userattr

宏 ACI 关键字具有以下限制:

匹配目标中的 ($dn)

ACI 目标中的 ($dn) 宏通过比较自身与 LDAP 请求的目标条目来确定替换值。例如,您的 LDAP 请求将以下条目作为目标:


cn=all,ou=groups,dc=subdomain1, dc=hostedCompany1,dc=example,dc=com

此外,您还具有按如下方式定义目标的 ACI:


(target="ldap:///ou=Groups,($dn),dc=example,dc=com")

($dn) 宏与 "dc=subdomain1, dc=hostedCompany1" 相匹配。因此会将此子串用作 ACI 主题中的替换值。

在主题中替换 ($dn)

在 ACI 的主题中,($dn) 宏将被替换为目标中匹配的整个子串。例如:


groupdn="ldap:///cn=DomainAdmins,ou=Groups,($dn),dc=example,dc=com"

此主题将变为:


groupdn="ldap:///cn=DomainAdmins,ou=Groups,
 dc=subdomain1,dc=hostedCompany1,dc=example,dc=com"

扩展宏之后,目录服务器将在完成普通进程后评估 ACI,以确定是否授予访问权限。


注 –

与标准 ACI 不同,使用宏替换的 ACI 不一定会授予对目标条目的子条目的访问权限。这是因为当目标为子 DN 时,替换可能不会在主题字符串中创建有效 DN。


在主题中替换 [$dn]

[$dn] 的替换机制与 ($dn) 略有不同。将对目标资源的 DN 进行多次检查,每次都舍弃最左侧的 RDN 部分,直到找到匹配项为止。

例如,假定您的 LDAP 请求将 cn=all,ou=groups, dc=subdomain1,dc=hostedCompany1,dc=example,dc=com 子树作为目标,并具有以下 ACI:


aci: (targetattr="*")
 (target="ldap:///ou=Groups,($dn),dc=example,dc=com")
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],
 dc=example,dc=com";)

    服务器将按如下方式继续操作,以扩展此 ACI:

  1. 服务器验证目标中的 ($dn) 是否与 dc=subdomain1,dc=hostedCompany1 相匹配。

  2. 服务器将主题中的 [$dn] 替换为 dc=subdomain1,dc=hostedCompany1

    得到的主题为 groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=subdomain1,dc=hostedCompany1,dc=example,dc=com"。如果因为绑定 DN 是该组的成员而授予访问权限,则宏扩展将停止,并对此 ACI 进行评估。如果绑定 DN 不是其成员,则此过程将继续。

  3. 服务器将主题中的 [$dn] 替换为 dc=hostedCompany1

    得到的主题为 groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com"。再次将绑定 DN 作为此组的成员进行测试,如果是其成员,则对此 ACI 进行完全评估。如果此绑定 DN 不是其成员,宏扩展将在最后一个具有匹配值的 RDN 处停止,并且对此 ACI 的评估将结束。

[$dn] 宏的优点在于它提供了一种灵活的方法,可以为域级别管理员授予对目录树中所有子域的访问权限。因此,[$dn] 宏在表示域之间的层次关系方面非常有用。

例如,请考虑以下 ACI:


aci: (target="ldap:///ou=*,($dn),dc=example,dc=com") (targetattr="*")
(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) groupdn= 
"ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=com";)

此 ACI 为 cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com 的成员授予对 dc=hostedCompany1 下所有子域的访问权限。因此,属于该组的管理员可以访问 ou=people,dc=subdomain1.1,dc=subdomain1 等子树。

但同时将拒绝 cn=DomainAdmins,ou=Groups, dc=subdomain1.1 的成员访问 ou=people,dc=subdomain1, dc=hostedCompany1ou=people,dc=hostedCompany1 节点。

($attr.attrName ) 的宏匹配

将始终在 DN 的主题部分使用 ($attr.attrname) 宏。例如,您可以定义以下 roledn


roledn = "ldap:///cn=DomainAdmins,($attr.ou),dc=HostedCompany1,dc=example,dc=com"

现在假定服务器收到了将以下条目作为目标的 LDAP 操作:


dn: cn=Babs Jensen,ou=People,dc=HostedCompany1,dc=example,dc=com
cn: Babs Jensen
sn: Jensen
ou: Sales
...

为了评估 ACI 的 roledn 部分,服务器会读取存储在目标条目中的 ou 属性值。然后,服务器将在主题中替换此值以扩展宏。在此示例中,roledn 将按如下方式扩展:


roledn = "ldap:///cn=DomainAdmins,ou=Sales,dc=HostedCompany1,dc=example,dc=com"

然后目录服务器将根据普通 ACI 评估算法来评估此 ACI。

如果宏中指定的属性为多值属性,将依次使用每个值来扩展宏。将使用提供成功匹配的第一个值。

记录访问控制信息

要获取错误日志中的访问控制信息,必须设置相应的日志级别。

Procedure设置 ACI 的日志记录

无法使用 DSCC 执行此任务。请使用命令行,如以下过程所述。

  1. 设置日志级别,以便记录 ACI 处理信息。


    $ dsconf set-log-prop -h host -p port error level:err-acl

通过 TCP 包装控制客户端-主机访问

可以使用 TCP 包装器,控制在 TCP 级别接受或拒绝连接的主机或 IP 地址。可以通过 TCP 包装限制客户端-主机访问。这样,您可以对目录服务器的初始 TCP 连接使用非主机式保护。

虽然可以为目录服务器设置 TCP 包装,但 TCP 包装可能会导致性能显著下降,特别是在拒绝服务攻击期间。要获取最佳性能,可以使用在目录服务器外部维护的基于主机的防火墙,或者使用 IP 端口过滤。

Procedure启用 TCP 包装

无法使用 DSCC 执行此任务。请使用命令行,如以下过程所述。

  1. 在实例路径中的某个位置创建 hosts.allow 文件或 hosts.deny 文件。

    例如,在 instance-path/config 中创建此文件。请确保所创建的文件格式符合 hosts_access(4)

  2. 设置该访问文件的路径。


    $ dsconf set-server-prop -h host -p port host-access-dir-path:path-to-file
    

    例如:


    $ dsconf set-server-prop -h host -p port host-access-dir-path:/local/ds1/config
    "host-access-dir-path" property has been set to "/local/ds1/config".
    The "/local/ds1/config" directory on host1 must contain valid hosts.allow
    and/or hosts.deny files.
    Directory Server must be restarted for changes to take effect. 

Procedure禁用 TCP 包装

无法使用 DSCC 执行此任务。请使用命令行,如以下过程所述。

  1. 将主机访问路径设置为 ""


    $ dsconf set-server-prop -h host -p port host-access-dir-path:""