Overview
访问控制 (Access Control) 是对目录树中的IDT访问的权限控制。主要指 “谁” 应该能够 “访问记录” 在 “什么条件下” 他们应该能看到多少这样的记录,这些将是本节中阐述的问题 。
OpenLDAP控制目录数据访问的主要方法是 通过访问控制列表 (Access Control List)。使 slapd 服务端在处理来自客户端的请求时,会评估客户端是否具有访问所请求的 DIT 的权限。要执行此计算,slapd 将依次计算LDIF 中配置的每个ACL策略,以检查客户端是否有权限访问该 DIT。
Note:
- ACL策略由上而下依次进行匹配
- 默认的访问控制策略是对所有客户端都允许读取,不管定义了什么ACL策略,
rootdn
(databases部分设置的)总是允许对所有和任何东西拥有完全的权限(即身份验证、搜索、比较、读和写 )
ACL介绍
访问控制主要定义三大方面:
what
定义对那些地方的访问,部分选择应用访问的条目和/或属性who
定义人员,部分指定授予哪些实体访问access
定义权限,部分指定授予的访问。
|
|
|
|
对于完整的ACL语法,如下面所示 [1]
|
|
what
部分将确定如何控制客户端访问的条目,通常为三种方式:- 通过DN
- 通过过滤器 (filter)
- 通过属性 (attributes)
who
部分将确定被授予访问权限的用户实体<who>
,<access>
,<control>
access
部分确定了实体的访问权限
控制访问内容
访问内容也是 ACL 中 what 部分,例如下属为简单表示的语法格式
|
|
- 其中
to *
表示选择所有条目 to dn[.<basic-style>]=<regex>
:通过正则表达式与DIT规范的DN来选择内容to dn.<scope-style>=<DN>
:内容将被限制在DN范围内
其中范围包含下述几项:
- base:仅匹配提供DN的条目
- one:父条目是指定DN的条目
- subtree:匹配指定DN下的所有子树中的条目,包含RootDN
- children:匹配指定的DN下的所有子条目,不包含RootDN
例如下列实例
|
|
- 如果请求为
dn.base="ou=people,o=suffix"
将匹配2 - 如果请求为
dn.one="ou=people,o=suffix"
将匹配 3, 5 - 如果请求为
dn.subtree="ou=people,o=suffix"
将匹配 2, 3, 4, 5 - 如果请求为
dn.children="ou=people,o=suffix"
将匹配 3, 4, 5
Notes:在配置ACL时,
to *
通常放置在ACL策略中最下层,即代表不匹配所有的权限时给的权限
通过DN匹配示例
|
|
这表示 所有 来自任意 uid 为逗号开头的 ou=Users,dc=example,dc=com
域的权限
使用filter匹配
|
|
例 :DN与filter可以同时包含在 <what>
子句中
|
|
例 : <what>
子句中也可以包含属性来进行过滤,多个属性可以通过符号 “,
” 分割
|
|
例:通过使用单个 attribute
与使用value选择器来过滤出特定的属性
|
|
Notes: “
*
” 代表dn=*
WHO
<who>
部分标识被授权访问的角色,例如被授权访问的用户
Notes:who 代表的是一个实体,例如用户,组,域,二不是访问的条目
下表总结了who拥有的角色
标识符 | 访问实体 |
---|---|
* | 所有,包括匿名和经过身份验证的用户 |
anonymous | 匿名用户(未验证) |
users | 通过身份验证的用户 |
self | 与目标条目关联的用户 |
dn[.<basic style>]=<regex> | 匹配正则表达式的用户 |
dn.<scope-style>=<DN> | DN范围内的用户 |
例:who子句中的 dnattr
仅适用于符合ldap语法的DN的属性,而不是其他属性
|
|
ACCESS
access
类型可以是下列之一:
级别 | 权限 | 描述 |
---|---|---|
none | 0 | 禁止访问 |
disclose | d | 检测信息是否存在 |
auth | dx | 需要验证 |
compare | cdx | 需要比较 |
search | scdx | 需要应用搜索过滤器 |
read | rscdx | 需要读搜索结果 |
write | wrscdx | 需要修改/重命名 |
manage | mwrscdx | 需要管理 |
其中权限字段字母意思为:
w
:对记录或属性的写访问。r
:对记录或属性的读访问。s
:对记录或属性的搜索访问。c
:访问对记录或属性运行比较操作。x
:访问对记录或属性执行服务器端身份验证操作。d
:访问记录或属性是否存在的信息 (d 代表“disclose” )。0
:不允许访问记录或属性。这相当于 wrscxd 。m
:管理权限
例 :最简单的access策略,限制所有人都可以读
|
|
例 :下面示例为,对于条目所属者可以修改自己,匿名用户需要登陆,所有人可以读,对于 by anonymous auth
仅仅是声明了匿名用户可以登录,而读的属性是下面那条声明的。
|
|
例 :使用 SSF Security Strength Factor
进行认证,SSF表示为openldap中保护的强度,与密钥长度有关
下列带包了,如果ssf强度大于128的将允许被修改自己,大于64的匿名用户可以读操作
|
|
例 :下面示例为 DN示例,这将代表了人员必须有所有用户搜索 dc=example,dc=com
子目录,并且对 dn.children="dc=com
的子目录有读权限,而这里 dc=example,dc=com
为 dc=com
子目录,所以说如果要读 目录 dc=example,dc=com
此时没有权限,因为ACL策略是按照顺序进行的,匹配到后就结束了
|
|
例 :还需要注意的一点是,所有列出的策略结尾都会隐式增加一条 access to * by * none
即,当没有通过who子句,也会被拒绝。
例如该策略将允许 dc=example,dc=com
子目录,并且属性 homePhone
的属于自己条目的可以写入,可以进行搜索,并包含 dn=dc=example,dc=com
下的所有子条目,并且网络客户端为10开头的ip都可以读,其他的将被隐式策略拒绝
|
|
例 :有些场景下需要只有组内成员才能删除自己租的条目对象,这个时候就需要用到 dnattr
作为 who 子句的选择器;下面的策略表示只有符合这个域中的成员才能删除自己的DN,这里attrs是必须的
|
|
ACL的排序
ACL的顺序也非常重要,如果不配置,将按照默认的固定顺序进行,但是也可以控制顺序的先后,通过为每个值添加 {x}
x 为数字,这样可以做到ACL的排序
例如下列策略,在执行时是由 slapd 服务自动维护的
|
|
比如说在生成好的策略进行动态修改时,例如下列所示,此时时修改顺序将是乱的
|
|
为了确保可以修改到指定的条目,需要指定对应条目的index,如果并不确定index是多少,可以通过 /etc/openldap/slapd.d/
对应的文件查看
|
|
访问控制示例
- 关闭匿名访问
- 创建一个目录管理员组,属于该组的人员都具有管理目录的权限
- 创建一个配置管理员组,属于该组的人员都具有配置 openldap 的权限
- 创建一个复制权限用户 ,该账号用于高可用之间的复制
- 创建一个搜索用户,用于 linux 集中账号认证时的,搜索
提示:
- 目录管理员组:操作目录树的管理员都属于目录管理员组。
- 配置管理员组:可以操作服务器配置的(
slapd.ldif
)属于配置管理员组
关闭匿名访问
首先slapd默认是允许匿名用户登录的,现在关闭匿名用户登录 在全局部分配置如下(通常全局在配置文件前几行)
|
|
初始化一些组与用户
创建RootDN与一些组,这里创建了三个组 :目录管理员组 dirGroup
,配置管理员组 confGroup
,与高级管理员组 adminGroup
。
注:
- 这些是在初始化安装好 openldap 环境进行的,而不是存在数据的环境
- 这里创建的组使用的
groupOfUniqueNames
|
|
初始化目录管理员用户 syncUser
,配置管理员用户 searchUser
,高级管理员用户 admin
,密码均为111
|
|
创建权限:管理员用户组有所有权限
这句意思是筛选出dn下的所有不包含uniqueMember的用户,即找到dn=cn=adminGroup,ou=tvb,dc=test,dc=com
在上面我们把起规划为一个组,然后检查他的属性 uniqueMember
,*
表示递归,这里不用填,所有的 uniqueMember
均为最底层 [2]
|
|
创建权限:普通用户仅允许修改自己的密码
这里使用属性选择器进行属性筛选
|
|
配置数据库的权限
对于客户端请求过来的权限,一般通过Frontend settings段来配置,这也可以理解是全局的ACL,对于后面的ACL会覆盖全局的ACL
#
# Configuration database
#
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcAccess: to *
by set="[cn=adminGroup,ou=tvb,dc=test,dc=com]/uniqueMember & user" manage
by * none
完整的ACL配置部分
Notes:slapd会根据配置的ACL顺序进行检测,匹配到后就不在继续了,所以在配置时,
what
部分(选择器范围)要从小到大,这样可以控制范围就正确,正如上面例子,用户只能修改自己密码,属性选择器一旦写在DN选择器下面,将用远不被执行
olcAccess: to attrs="userPassword"
by set="[cn=adminGroup,ou=tvb,dc=test,dc=com]/uniqueMember & user" manage
by self write
by * read
olcAccess: to dn.subtree="dc=test,dc=com"
by set="[cn=adminGroup,ou=tvb,dc=test,dc=com]/uniqueMember & user" manage
by dn.children="dc=test,dc=com" read
by anonymous auth
by * read
Troubleshooting
默认情况下,获取schema是没有权限的,此时需要添加权限使其可以读取schema权限。
注:在创建用户和组是需要查看schema权限
slapd.ldif
文件中添加:
|
|
填写配置后重新生成配置文件报类似如下错误
|
|
问题原因:如上配置权限换行方式不可,官网给出的解决方法 [1]
Insufficient access (50)
问题原因:没有权限
Reference
[1] msg00054
[2] Groups of Groups
[3] ACLs