在22年的时候,我写了一篇文章,详细地介绍了slapd的配置,非常详细,详细到有些例子太不常用。这次配置Keycloak,使用基于LDAP的用户联合,在ACL踩了坑,因此再写一篇文章专门介绍下ACL的配置。
安装slapd
OpenLDAP的实现软件包叫slapd,安装过程简单再提一嘴。
首先,安装软件包
apt install slapd
安装过程中会提示创建管理员密码,其实无所谓,因为下一步还要配置一次
然后,重新配置软件包
dpkg-reconfigure slapd
重新配置时会有一系列的弹窗问题:
- Omit OpenLDAP server configuration?是否忽略已有的配置?反正是新装的,无所谓,我选择No
- DNS domain name:域名,比如mewwoof.cn,对应dc=mewwoof,dc=cn的域
- Name of your organization:可以自定义组织名,可以随便填,我还是填的mewwoof.cn
- 创建管理员密码
- Do you want your database to be removed when slapd is purged?用apt purge删除slapd软件包时删除数据库?建议No
- Remove old database?是否删除已有的数据库?我选Yes,建议删一下,因为安装软件包时的默认配置是根据hostname和dns搜索域确定的,往往不是我们想要的
slapd配置方式
配置树结构
slapd使用动态配置的方式配置整个服务器(网上的关于修改conf文件的教程已经过时了),所有的配置都存储在slapd的数据库里。这样的好处是配置可以动态加载,修改配置后无需重启整个服务即可应用。
我们可以打开slapd文档:https://www.openldap.org/doc/admin26/slapdconf2.html,可以看到第一张图片就介绍了配置数据库的结构:
简单来说,整个树形配置数据库至少有以下实体:
- cn=config
- cn=module{0},cn=config
- cn=schema,cn=config
- cn={0}core,cn=schema,cn=config
- cn={1}cosine,cn=schema,cn=config
- (cn={2}nis,cn=schema,cn=config)
- (cn={3}inetorgperson,cn=schema,cn=config)
- olcDatabase={-1}frontend,cn=config
- olcDatabase={0}config,cn=config
- olcDatabase={1}mdb,cn=config
每个实体所存储的内容都不一样,具体的可以查看文档。
查看当前配置
没有什么比参考更好的事物了,生活中那些没有参考且无标准的事物才是最难对付的,咳咳,扯远了,我们来看看怎样查看当前服务器中的所有配置。
非常简单,使用slapcat命令即可(强调一下使用root或相关用户运行):
sudo slapcat -b cn=config
然后就会输出长长的信息,仔细看看内容,可以发现都是上一节说的这些配置的数据。
配置ACL
在部署LDAP的时候,我们常常需要任命多个管理员,将权限分开来,比如任命某位组管理员专门管理其组下的人员,任命某台设备具有管理权限等等。此时我们需要用到ACL。
slapd访问控制文档:https://www.openldap.org/doc/admin26/access-control.html
其实文档看懂了就非常简单,再加上可以参考slapcat的输出,就可以自己仿照着写了。
查看slapcat的输出,关于olcAccess的记录如下:
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
这三句话就是说:
- {0}用户允许写入自己的密码,匿名用户可以认证密码,其他用户均不能访问(none)
- {1}用户可以写入自己的shadowLastChange,其他用户可以访问
- {2}对所有人允许查看所有字段
ACL规则按升序匹配,构成了整个规则列表。通过配置我们就可以实现更加细致的权限配置。
权限
官方文档列出了了如下权限:
这里补充说明一下,如果想要对某个组添加用户,需要拥有该组的write权限。(比如向ou=groupA,dc=root添加用户cn=user1,ou=groupA,dc=root,需要拥有ou=groupA,dc=root的权限)
匹配方式
看文档即可,这里不再赘述了
ACL顺序
ACL顺序非常重要,一定要按照范围从小到大排,否则可能导致提前命中规则。
具体的看我提供的实例吧
一个实例
olcAccess: {0}to dn.base="ou=group1,dc=root"
by dn="cn=user1,dc=awaworks,dc=net" manage
by * none
olcAccess: {1}to dn.one="ou=group1,dc=root" attrs=userPassword
by dn="cn=user1,dc=root" manage
by self write by anonymous auth
by * none
olcAccess: {2}to dn.one="ou=group1,dc=root" attrs=shadowLastChange
by dn="cn=user1,dc=root" manage
by self write
by * read
olcAccess: {3}to dn.one="ou=group1,dc=root"
by dn="cn=user1,dc=awaworks,dc=net" manage
by * read
olcAccess: {4}to attrs=userPassword
by self write
by anonymous auth
by * none
olcAccess: {5}to attrs=shadowLastChange
by self write
by * read
olcAccess: {6}to *
by * read
LDIF保存配置
以上实例,编写成LDIF格式如下:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to dn.base="ou=group1,dc=root"
by dn="cn=user1,dc=root" manage
by * none
-
add: olcAccess
olcAccess: {1}to dn.one="ou=group1,dc=root" attrs=userPassword
by dn="cn=user1,dc=root" manage
by self write
by anonymous auth
by * none
-
add: olcAccess
olcAccess: {2}to dn.one="ou=group1,dc=root" attrs=shadowLastChange
by dn="cn=user1,dc=root" manage
by self write
by * read
-
add: olcAccess
olcAccess: {3}to dn.one="ou=group1,dc=root"
by dn="cn=user1,dc=root" manage
by * read
-
add: olcAccess
olcAccess: {4}to attrs=userPassword by self write by anonymous auth by * none
-
add: olcAccess
olcAccess: {5}to attrs=shadowLastChange by self write by * read
-
add: olcAccess
olcAccess: {6}to * by * read
第一个操作replace就会将所有已有的olcAccess清除并替换,然后逐个添加其他条目即可。
将文件保存为比如acl.ldif,然后使用root或相关用户执行:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./acl.ldif
就可以将数据保存到数据库了。