Jenkins提供了用户认证和权限控制两种维度的安全策略:
1、Security Realm(安全域):判断用户名和密码是否有效、判断用户所属的group;
2、Authorization Strategy(授权策略):分配用户执行操作的权限;
Jenkins默认的Security Realm是Jenkins’s own user database,而Jenkins使用LDAP并非大部分文章中简单地配置一下LDAP Plugin就能万事大吉的。这些文章大多言之不详,实际上坑比较多。Jenkins使用LDAP主要分为两个关键环节:
1、正确地配置LDAP;
2、合理地配置Jenkins LDAP Plugin;
基本上就是围绕如下的插件配置展开的:
![Jenkins配置LDAP登陆及权限控制](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-ldap-configuration.png)
Jenkins配置LDAP登陆及权限控制
需要注意, 一旦启用了LDAP,那么本地认证的账户都将无法再使用,所以需要确保LDAP配置正确后再保存,否则一旦有问题就没法登陆了。
一、正确且合理地配置LDAP
主要指相关user、group、membership的search及配置,在LDAP中group主要涉及groupOfNames和groupOfUniqueNames等属性,用memberOf表达people与group的关系。笔者对LDAP完全一无所知,因此直接使用了389 Directory Server自带的example组织架构,事实证明还是脑补出了很多东西,如果不想花时间去了解LDAP的过多细节那么非常推荐从example入手。
memberOf需要在schema中自行定义,否则根本无法添加这个attribute:
![LDAP不能在实体中增加memberOf属性](http://www.meilongkui.com/wp-content/uploads/2020/08/can-not-add-attribute-memberOf.png)
LDAP不能在实体中增加memberOf属性
网上有些关于OpenLDAP手工添加memberOf支持的文章;而对于389 Directory Server而言,有一个默认没有开启的插件MemberOf Plugin:
![389 Directory Server的MemberOf插件](http://www.meilongkui.com/wp-content/uploads/2020/08/389-directory-serer-member-of-plugin.png)
389 Directory Server的MemberOf插件
我们将其开启,然后根据文档Run Fix Task来修复开启memberOf插件前就已经存在的实体:
![389 Directory Server MemberOf插件的Fixup任务](http://www.meilongkui.com/wp-content/uploads/2020/08/389-directory-serer-member-of-plugin-fixup-task.png)
389 Directory Server MemberOf插件的Fixup任务
然而执行报错,搜索无结果。不过,我们可以手工进行处理,根据文档,在实体上增加一个objectClass=extensibleObject的属性后就能够在people中增加memberOf的属性了:
![在LDAP实体中增加memberOf属性](http://www.meilongkui.com/wp-content/uploads/2020/08/jenking-ldap-member-of.png)
在LDAP实体中增加memberOf属性
对于group而言,有两个objectClass比较重要,即groupOfNames和groupOfUniqueNames,如果group的实体没有这个两个配置的话需要增加上,否则搜索会有问题:
![Jenkins中未能正确设置group的search或者group未能正确配置](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-ldap-wrong-group-configuration.png)
Jenkins中未能正确设置group的search或者group未能正确配置
我们可以看到Jenkins中对LDAP group的搜索规则:
![Jenkins对LDAP中group的默认search](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-ldap-group-search.png)
Jenkins对LDAP中group的默认search
因此,在LDAP中作为group使用的ou也需要配置上述两个属性,有这两个属性的ou图标也会发生改变:
![LDAP中配置group](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-group.png)
LDAP中配置group
这样,把Root DN、之类的配置好,LDAP插件就算是初步配置完成了。接下来多找几个账号、模拟账号不存在、账号存在密码不正确、账号存在密码正确等等的情况进行测试。然而,我们在接下来的“Test LDAP settings”中发现一个诡异的情况,即当输入错误的用户名和密码时,LDAP插件能够读到对应Entity中映射的Attribute;但是当输入正确的用户名和密码时,LDAP插件却不能能够读到对应Entity中映射的Attribute:
![在Jenkins中LDAP登陆失败时能够正确读取到实体的属性](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-wrong-ldap-authorization-can-access-right-attributes.png)
在Jenkins中LDAP登陆失败时能够正确读取到实体的属性
![在Jenkins中LDAP登陆成功时反而不能读取到实体的属性](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-right-ldap-authorization-can-not-access-attributes.png)
在Jenkins中LDAP登陆成功时反而不能读取到实体的属性
该问题搜遍全网没有答案,最后从389 Directory Server的Access Log中看到了端倪:
![Jenkins配置LDAP的诡异错误](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-user-can-not-access-own-entity-2.png)
Jenkins配置LDAP的诡异错误
我们发现Test的逻辑是首先使用Manager DN进行BIND,然后search指定的实体,再BIND到对应的实体上进行search。根据日志的情况看,当输入正确的用户名和密码时,LDAP插件BIND成功后却没有search到自己。为了验证,我们在Apache Directory Studio使用UID=test4,ou=people,dc=example,dc=com的DN登陆到LDAP上,发现test4确实是search不到自己的:
![LDAP中以某个people的身份BIND后search不到自己](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-user-can-not-access-own-entity.png)
LDAP中以某个people的身份BIND后search不到自己
这也就解释了为什么Jenkins LDAP插件给出了诡异的报错。接下来,笔者通过参考资料2学习到了需要用aci来控制search的权限:
![LDAP Enabling Users to Access Their Own Entries](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-user-access-own-entity.png)
LDAP Enabling Users to Access Their Own Entries
在people实体上增加如下的一个aci属性:
![LDAP Enabling Users to Access Their Own Entries的配置](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-user-access-own-entity-2.png)
LDAP Enabling Users to Access Their Own Entries的配置
这样,在Apache Directory Studio使用UID=test4,ou=people,dc=example,dc=com的DN登陆到LDAP上后发现test4能够search到自己了:
![LDAP中以某个people的身份BIND后能够search到自己](http://www.meilongkui.com/wp-content/uploads/2020/08/ldap-user-can-access-own-entity.png)
LDAP中以某个people的身份BIND后能够search到自己
而LDAP插件的测试结果也终于正常了:
![Jenkins正确配置LDAP后的测试](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-ldap-right-configuration.png)
Jenkins正确配置LDAP后的测试
点击右上角的用户名称,也能够看到该用户在LDAP中所属的group了:
![Jenkins中正确配置LDAP后可以直接看到用户所属的group](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-right-ldap-configration-load-ldap-group-information.png)
Jenkins中正确配置LDAP后可以直接看到用户所属的group
二、授权策略
Jenkins的授权策略有如下几种:
- Anyone can do anything
- Legacy mode
- Logged-in users can do anything,登陆用户可进行所有操作
- Role-Based Strategy
- Matrix-based Security
- Project-based Matrix Authorization Strategy
我们使用的是基于项目的矩阵授权策略:
![Jenkins Project-based Matrix Authorization Strategy](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-project-based-matrix-authorization-strategy.png)
Jenkins Project-based Matrix Authorization Strategy
其中的group直接使用LDAP中的group名称即可。我们应该注意到,LDAP中的group被加载到LDAP中后是没有层次关系的,因此需要通过名称合理区分。
Project-based Matrix Authorization Strategy是Matrix-based Security的加强版,Matrix-based针对的是整个系统,而Project-based Matrix Authorization Strategy则可以进一步设置用户在每个具体Project上的权限。由于Project-based Matrix Authorization Strategy是一个全局的配置,因此在Project-based Matrix Authorization Strategy中只能按照最小的权限授权,额外的权限可以到具体的项目权限矩阵中添加。Read是Jenkins中很基础的权限,没有Read权限就登不进Jenkins。
当启用了Project-based Matrix Authorization Strategy后,Project的Configure界面中会出现Enable project-based security的复选框,选中后就可以基于矩阵设置用户能够对该Project操作的权限了:
![Jenkins配置具体某个项目的Project-based Matrix Authorization Strategy](http://www.meilongkui.com/wp-content/uploads/2020/08/jenkins-project-based-matrix-authorization-strategy-2.png)
Jenkins配置具体某个项目的Project-based Matrix Authorization Strategy
这样就可以实现利用LDAP在Jenkins中细粒度地实现基于组及用户的授权策略了。
参考资料:
1、https://directory.fedoraproject.org/docs/389ds/design/memberof-plugin.html
2、https://access.redhat.com/documentation/en-us/red_hat_directory_server/10/html/administration_guide/defining_bind_rules#enabling_users_to_access_their_own_entries
3、https://www.adimian.com/blog/2014/10/how-to-enable-memberof-using-openldap/
转载时请保留出处,违法转载追究到底:进城务工人员小梅 » Jenkins使用LDAP