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;
基本上就是围绕如下的插件配置展开的:
需要注意, 一旦启用了LDAP,那么本地认证的账户都将无法再使用,所以需要确保LDAP配置正确后再保存,否则一旦有问题就没法登陆了。
一、正确且合理地配置LDAP
主要指相关user、group、membership的search及配置,在LDAP中group主要涉及groupOfNames和groupOfUniqueNames等属性,用memberOf表达people与group的关系。笔者对LDAP完全一无所知,因此直接使用了389 Directory Server自带的example组织架构,事实证明还是脑补出了很多东西,如果不想花时间去了解LDAP的过多细节那么非常推荐从example入手。
memberOf需要在schema中自行定义,否则根本无法添加这个attribute:
网上有些关于OpenLDAP手工添加memberOf支持的文章;而对于389 Directory Server而言,有一个默认没有开启的插件MemberOf Plugin:
我们将其开启,然后根据文档Run Fix Task来修复开启memberOf插件前就已经存在的实体:
然而执行报错,搜索无结果。不过,我们可以手工进行处理,根据文档,在实体上增加一个objectClass=extensibleObject的属性后就能够在people中增加memberOf的属性了:
对于group而言,有两个objectClass比较重要,即groupOfNames和groupOfUniqueNames,如果group的实体没有这个两个配置的话需要增加上,否则搜索会有问题:
我们可以看到Jenkins中对LDAP group的搜索规则:
因此,在LDAP中作为group使用的ou也需要配置上述两个属性,有这两个属性的ou图标也会发生改变:
这样,把Root DN、之类的配置好,LDAP插件就算是初步配置完成了。接下来多找几个账号、模拟账号不存在、账号存在密码不正确、账号存在密码正确等等的情况进行测试。然而,我们在接下来的“Test LDAP settings”中发现一个诡异的情况,即当输入错误的用户名和密码时,LDAP插件能够读到对应Entity中映射的Attribute;但是当输入正确的用户名和密码时,LDAP插件却不能能够读到对应Entity中映射的Attribute:
该问题搜遍全网没有答案,最后从389 Directory Server的Access Log中看到了端倪:
我们发现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不到自己的:
这也就解释了为什么Jenkins LDAP插件给出了诡异的报错。接下来,笔者通过参考资料2学习到了需要用aci来控制search的权限:
在people实体上增加如下的一个aci属性:
这样,在Apache Directory Studio使用UID=test4,ou=people,dc=example,dc=com的DN登陆到LDAP上后发现test4能够search到自己了:
而LDAP插件的测试结果也终于正常了:
点击右上角的用户名称,也能够看到该用户在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
我们使用的是基于项目的矩阵授权策略:
其中的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操作的权限了:
这样就可以实现利用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