OpenLDAP篇-OpenLDAP对接应⽤系统04

1、OpenLDAP对接应⽤规划

1.1 如何组织LDAP⽬录结构

通常我们会在 LDAP ⽬录中为每个应⽤创建对应的组,然后在这些组下⾯添加对应的⽤户。当⽤户加⼊了某个组之后,就可以访问对应的系统。 问题是,如果每个应⽤都需要创建对应的组,那么每个组中就会出现重复添加相同的⽤户。例如,我们希望 zhangsan 既可以访问 GitLab 也可以访问 Jenkins,那么我们需 要在 GitLab 和 Jenkins 各⾃对应的组中都创建 zhangsan ⽤户,这就违背了我们希望通过 LDAP 实现单⼀⽤户登录多个系统的初衷

为了解决如上的问题,我们会可以将所有⽤户都放置在同⼀个 OU(组织单元)中,这样每个⽤户都可以访问所有的系统,也就实现了单⼀⽤户登陆多个系统。但,这样⼜会带来⼀个新的问题,例如,有 10 个⽤户和 3 个系统的场景下,即便我们只授权了 3 个⽤户访问这些系统,但在实际测试时发现,其他 7 个⽤户也能正常访问这些系统。这显然与实际的⽣产需求不符。

因此,我们需要重新设计 LDAP⽬录结构,以满⾜以下两个需求:

  • 1、精确授权:确保只有被明确授权的⽤户才能访问指定的系统,未授权⽤户⽆法访问。
  • 2、集中管理:确保每个⽤户只需在⼀个地⽅维护,即可对多个系统拥有访问权限,避免重复创建相同⽤户。

1.2 LDAP对接应⽤落地⽅案

为了满⾜上述的两个需求(精确授权、集中管理),我们可以将LDAP当中的⽤户和组进⾏分离管理。具体步骤如下:

第⼀步:创建两个 OU

  • ⼀个⽤于存放公司所有⽤户,叫 app-users
  • 另⼀个⽤于存放所有应⽤的访问组,叫 app-groups

第⼆步:将所有⽤户都创建在 app-users 这个OU中

  • uid=erma
  • uid=zhangsan
  • uid=lisi
  • uid=wangwu
  • uid=laoliu
  • uid=oldxu

第三步:每个应⽤都创建⼀个组,放置在 app-groups 这个OU中

  • cn=zabbix-group
  • cn=gitlab-group
  • cn=jenkins-group
  • cn=harbor-group
  • cn=openvpn-group
  • cn=...-group

第四步:配置应⽤授权逻辑,当⽤户需要访问某个应⽤时,只需将该⽤户加⼊到对应的组中

  • 示例:如果 zhangsan 和 lisi 需要登录 GitLab,那么将他们加⼊到gitlab-group 组中。
  • 效果: 当 GitLab 通过 LDAP 进⾏⽤户验证时,会查询⽤户的 memberof 属性是否包含 cn=gitlab-group (即属于 gitlab-group 组),如果⽤户的 memberof 属性中包含 cn=gitlab-group ,则证明⽤户(如 zhangsan 和 lisi )能正常访问, 反之 wangwu、oldxu 的 memberof 属性中不包含 cn=gitlab-group ,因此⽆法登录 GitLab。

第五步:权限撤销

  • 示例: 如果 lisi 不再需要访问 GitLab,只需将他从 gitlab-group组中移出。
  • 效果:当 GitLab 通过 LDAP 进⾏⽤户认证时,会再次查询⽤户的 memberof 属性。由于 lisi 已不再属于 gitlab-group ,其 memberof 属性中不再包含 cn=gitlab-group ,因此他将被拒绝访问 GitLab。

总结:

通过这种⽅式,每个⽤户的访问权限可以根据其“所属的组”来动态控制。如果 zhangsan 属于 gitlab-group ,他就可以访问 GitLab;如果他同时属于 jenkins-group ,他也可以访问 Jenkins。这种基于组的动态权限控制,⼤⼤的简化了⽤户的管理流程,并且还实现了集中管理和精确授权的双重⽬标。

1.3 LDAP创建相关⽤户以及组

1、创建 app-users 和 app-groups 的OU
# app-users
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 << EOF
dn: ou=app-users,dc=oldxu,dc=net
objectClass: organizationalUnit
ou: app-users
EOF
# app-groups
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 << EOF
dn: ou=app-groups,dc=oldxu,dc=net
objectClass: organizationalUnit
ou: app-groups
EOF

2、为 app-users 这个OU创建对应的⽤户,例如: erma、zhangsan、lisi、wangwu、laoliu、oldxu

# erma
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=erma,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: erma
cn: erma
sn: App Server User
mail: erma@qq.com
userPassword: 123
EOF
# zhangsan
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=zhangsan,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: zhangsan
cn: zhangsan
sn: App Server User
mail: zhangsan@qq.com
userPassword: 123
EOF
# lisi
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=lisi,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: lisi
cn: lisi
sn: App Server User
mail: lisi@qq.com
userPassword: 123
EOF
# wangwu
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=wangwu,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: wangwu
cn: wangwu
sn: App Server User
mail: wangwu@qq.com
userPassword: 123
EOF
# laoliu
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=laoliu,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: laoliu
cn: laoliu
sn: App Server User
mail: laoliu@qq.com
userPassword: 123
EOF
# oldxu
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: uid=oldxu,ou=app-users,dc=oldxu,dc=net
objectClass: inetOrgPerson
uid: oldxu
cn: oldxu
sn: App Server User
mail: oldxu@qq.com
userPassword: 123
EOF

3、如果要在 app-groups 这个OU创建对应的组,则必须指定组中有哪些⽤户,因此,后续根据需求在创建组,并加⼊对应的⽤户

2、OpenLDAP对接Zabbix

2.1 配置OpenLDAP⽤户权限

1、在 app-groups 下创建 zabbix-group 的组,⽤来存储普通⽤户,并将 erma 和 zhangsan 加⼊组中
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=zabbix-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: zabbix-group
member: uid=erma,ou=app-users,dc=oldxu,dc=net
member: uid=zhangsan,ou=app-users,dc=oldxu,dc=net
EOF

2、在 app-groups 下在创建⼀个 zabbix-admin-group 的组,⽤来存储管理员⽤户,并将 oldxu ⽤户加⼊该组中

ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=zabbix-admin-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: zabbix-admin-group
member: uid=oldxu,ou=app-users,dc=oldxu,dc=net
EOF

2.2 Docker部署ZabbixServer

1、下载zabbix相关镜像
docker pull uhub.service.ucloud.cn/oldxu/zabbix-server-mysql:latest
docker pull uhub.service.ucloud.cn/oldxu/zabbix-web-nginx-mysql:latest
docker pull uhub.service.ucloud.cn/oldxu/mysql:8.0

2、创建⼀个⾃定义 Docker ⽹络,这样所有容器可以通过(容器名)相互通信

docker network create zabbix-net

3、在 zabbix-net ⽹络中启动 MySQL 容器

docker run --name zabbix-mysql \
--network zabbix-net \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root_password" \
-td uhub.service.ucloud.cn/oldxu/mysql:8.0 \
--character-set-server=utf8mb4 --collation-server=utf8mb4_bin

4、在 zabbix-net ⽹络中启动 Zabbix Server 容器

docker run --name zabbix-server \
--network zabbix-net \
-e DB_SERVER_HOST="zabbix-mysql" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root_password" \
-p 10051:10051 \
-td uhub.service.ucloud.cn/oldxu/zabbix-server-mysql:latest

5、在 zabbix-net ⽹络中启动 Zabbix Web 容器

docker run --name zabbix-web \
--network zabbix-net \
-e DB_SERVER_HOST="zabbix-mysql" \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix" \
-e MYSQL_ROOT_PASSWORD="root_password" \
-p 80:8080 \
-d uhub.service.ucloud.cn/oldxu/zabbix-web-nginx-mysql:latest

6、访问zabbix-web前端UI,默认⽤户名 Admin ,密码 zabbix

2.3 配置Zabbix对接LDAP

1、点击⽤户-->认证-->LDAP设置
  • 启⽤LDAP 验证:开启LDAP认证(勾选)
  • 启⽤即时供应:会⾃动创建⽤户,⾃动分配组(勾选)

2、点击服务器-->添加

  • 名称(⾃定义): LDAPServer
  • 主机(LDAP服务器地址): ldap.oldxu.net
  • 端⼝(不使⽤TLS则默认): 389
  • 基于 DN(从哪⾥开始搜索⽤户): ou=app-users,dc=oldxu,dc=net
  • 搜索属性(⽤户的属性是什么): uid
  • 绑定 DN(拥有搜索权限的账户): cn=admin,dc=oldxu,dc=net
  • 绑定密码(拥有搜索权限账户密码): 123456

3、组配置(memberOf)优选

  • 组配置(通过⽤户获取组信息): 选择memberOf
  • 组名属性(组名称属性⼀般是cn): cn
  • ⽤户组成员属性: memberOf
  • ⽤户名属性: uid
  • ⽤户姓⽒属性:
  • ⽤户组映射(将对应的组映射为zabbix中的组,并可以分配⻆⾊权限)
    • zabbix-group :映射为zabbix中的 User role ⻆⾊,也就是普通⽤户
    • zabbix-admin-group :映射为zabbix中的 Super adminrole ⻆⾊,也就是超级管理员
  • 媒体类型映射(是否将⽤户的邮箱映射为zabbix中的告警媒介):属性为mail

3、组配置(groupOfNames)备选

  • 组配置(通过组搜索⽤户信息): groupOfNames
  • 基准⽬录(DN)组(指定组的基础路径,从中获取组名称的属性。): ou=app-groups,dc=oldxu,dc=net
  • 组名属性(组名称属性⼀般是cn): cn
  • 组成员属性(组成员的属性): member
  • 引⽤属性(获取⽤户名称): uid
  • 组过滤器(获取⽤户对应的组): (member=uid=%{ref},ou=app-users,dc=oldxu,dc=net)
  • ⽤户名属性: uid
  • ⽤户组映射(将对应的组映射为zabbix中的组,并可以分配⻆⾊权限)
    • zabbix-group:映射为zabbix中的 User role ⻆⾊,也就是普通⽤户
    • zabbix-admin-group:映射为zabbix中的 Super admin role ⻆⾊,也就是超级管理员
  • 媒体类型映射(是否将⽤户的邮箱映射为zabbix中的告警媒介): 属性为mail

4、点击测试,验证ldap⽤户是否能登陆系统,并获取到对应的⻆⾊权限。

5、点击⽤户-->认证

  • 将默认的认证⽅式,修改为LDAP
  • 将取消预配置的⽤户组,选择为 Disabled

2.4 验证LDAP⽤户登陆zabbix

1、测试普通⽤户 zhangsan 登陆zabbix

2、测试管理员账户 oldxu 登陆zabbix

3、也可以通过管理-->⽤户中查看⽤户是否是通过ldap登陆的

2.5 提升LDAP⽤户权限
1、lisi⽤户是⽆法登陆zabbix系统的,因为它不在 zabbix-group 或 zabbix-admin-group 组中,如果想登陆,则添加⽤户⾄对应的组中,即可完成登陆。

ldapmodify -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=zabbix-admin-group,ou=app-groups,dc=oldxu,dc=net
changetype: modify
add: member
member: uid=lisi,ou=app-users,dc=oldxu,dc=net
EOF

2、使⽤lisi⽤户登陆zabbix系统测试

3、如果需要将lisi⽤户从管理组中移出,则通过如下⽅式实现

ldapmodify -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=zabbix-admin-group,ou=app-groups,dc=oldxu,dc=net
changetype: modify
delete: member
member: uid=lisi,ou=app-users,dc=oldxu,dc=net
EOF

4、再次测试会发现lisi没有权限登陆系统

3、OpenLDAP对接Gitlab

3.1 配置OpenLDAP⽤户权限

1、在 app-groups 下创建 gitlab-group 的组,⽤来存储普通⽤户,并将 zhangsan、lisi、wangwu 加⼊组中
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=gitlab-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: gitlab-group
member: uid=zhangsan,ou=app-users,dc=oldxu,dc=net
member: uid=lisi,ou=app-users,dc=oldxu,dc=net
member: uid=wangwu,ou=app-users,dc=oldxu,dc=net
EOF

2、在 app-groups 下在创建⼀个 gitlab-admin-group 的组,⽤来存储管理员⽤户,并将 oldxu ⽤户加⼊该组中但是该功能只能在gitlab-ee企业版本中才可以使⽤;gitlab-ce社区版不⽀持;

ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=gitlab-admin-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: gitlab-admin-group
member: uid=oldxu,ou=app-users,dc=oldxu,dc=net
EOF

3.2 Docker部署Gitlab

1、删除zabbix容器,避免端⼝冲突
[root@k8s-node35 ~]# docker rm -f zabbix-web zabbix-server zabbix-mysql
zabbix-web
zabbix-server
zabbix-mysql

2、下载gitlab镜像

docker pull uhub.service.ucloud.cn/oldxu/gitlab-ce:16.10.0-ce.0

3、使⽤Docker部署Gitlab,并将对应的配置⽂件挂载到宿主机的 /data/gitlab ⽬录下;

docker run -d --name gitlab \
-p 80:80 -p 9022:22 \
--restart always \
--privileged=true \
--hostname "gitlab.oldxu.net" \
-v /data/gitlab/etc:/etc/gitlab \
-v /data/gitlab/log:/var/log/gitlab \
-v /data/gitlab/opt:/var/opt/gitlab \
uhub.service.ucloud.cn/oldxu/gitlab-ce:16.10.0-ce.0

4、获取gitlab的 Root 密码

[root@k8s-node35 etc]# cat /data/gitlab/etc/initial_root_password|grep Password:
Password: GbCMvn3CuFIkekiOZu7cmo4K7SQ63cadkce//V0bMDc=

5、使⽤root超级管理员⽤户登陆gitlab

3.3 配置Gitlab对接LDAP

1、修改 gitlab.rb 配置⽂件,由于采⽤的是容器部署,因此配置⽂件在 /data/gitlab/etc/gitlab.rb
vim /data/gitlab/etc/gitlab.rb
gitlab_rails['ldap_enabled'] = true # 启⽤ GitLab 的 LDAP 认证功能
gitlab_rails['prevent_ldap_sign_in'] = false # 是否禁⽤LDAP⽤户登陆;false:允许、true:禁⽤
gitlab_rails['ldap_servers'] = YAML.load <<-EOS
main:
 label: 'LDAP' # 登录界⾯显示的标签,可以⾃定义
 host: 'ldap.oldxu.net' # LDAP 服务器的主机名或 IP 地址
 port: 389 # ⾮加密的端⼝是 389。如果使⽤加密TLS,则使⽤ 636 端⼝
 uid: 'uid' # 当⽤户登录 GitLab 时,GitLab 会根据这个属性在 LDAP 中搜索⽤户,通常是uid和cn
 bind_dn: 'cn=admin,dc=oldxu,dc=net' # 绑定管理员账户的dn,也可以创建⼀个专属账户
 password: '123456' # 管理员账户的密码
 encryption: 'plain' # 使⽤⾮加密连接,如果加密以将其设置为 'start_tls (389)' 或 'simple_tls (636)'。
 verify_certificates: false # ⾮加密模式下,设置为 false
 # ca_file: '/gitlab/ssl/ca.crt' # 指定 CA 证书⽂件的路径
 smartcard_auth: false # 是否启⽤智能卡认证。⼤多数情况下为 false
 active_directory: false # 如果使⽤的是windows的ad则为true,使⽤ OpenLDAP则设置为 false。,
 allow_username_or_email_login: true # 是否允许⽤户通过⽤户名或电⼦邮件登录。false则只允许通过 LDAP uid 登录。
 lowercase_usernames: false # 是否将⽤户名转为⼩写,通常设置为false,以保持与 LDAP 服务器中的⽤户名⼀致。
 block_auto_created_users: false # 允许通过 LDAP ⾃动创建帐户。如果设置为 true,则阻⽌⾃动创建⽤户,需要⼿动创建⽤户。
 base: 'ou=app-users,dc=oldxu,dc=net' # 搜索⽤户的起始位置。确保需要登录的⽤户都位于这个路径下。如果⽤户不在这个路径下,将⽆法登录。
 group_base: 'ou=app-groups,dc=oldxu,dc=net' # 这是⽤于搜索组的起始位置。确保所有的组(包括管理员组)都位于该路径下。
 user_filter: '(|(memberof=cn=gitlab-group,ou=app-groups,dc=oldxu,dc=net) (memberof=cn=gitlab-admin-group,ou=app-groups,dc=oldxu,dc=net))'
 # 确保 gitlab-group 和 gitlab-admin-group 组中的⽤户能正常登录。
 #admin_group: 'gitlab-admin-group' # 组内的成员在 GitLab 中将被授予管理员权限(企业版才⽀持)
 sync_ssh_keys: false # 是否从LDAP⽤户中同步SSH密钥,通常设置为 false,因为多数情况密钥是由 GitLab 单独管理的
EOS

2、重新应⽤gitlab的配置

docker exec -it gitlab gitlab-ctl reconfigure	

3、再次访问Gitlab,就能看到LDAP登陆⼊⼝了。

3.4 验证ldap⽤户登陆gitlab

1、使⽤ gitlab-rake gitlab:ldap:check 命令验证gitlab是否能获取到ldap中的⽤户
[root@k8s-node35 etc]# docker exec -it gitlab bash
root@gitlab:/# vim /etc/hosts
bash: vim: command not found
root@gitlab:/# vi /etc/hosts
root@gitlab:/#
exit
[root@k8s-node35 etc]# docker exec -it gitlab gitlab-rake gitlab:ldap:check
Checking LDAP ...

LDAP: ... Server: ldapmain
LDAP authentication... Success
LDAP users with access to your GitLab server (only showing the first 100 results)
        DN: uid=lisi,ou=app-users,dc=oldxu,dc=net        uid: lisi
        DN: uid=oldxu,ou=app-users,dc=oldxu,dc=net       uid: oldxu
        DN: uid=wangwu,ou=app-users,dc=oldxu,dc=net      uid: wangwu
        DN: uid=zhangsan,ou=app-users,dc=oldxu,dc=net    uid: zhangsan

Checking LDAP ... Finished

2、测试 zhangsan、lisi、wangwu、oldxu ,是否能正常登陆gitlab

3.5 Gitlab分配LDAP⽤户权限

此前我们创建了四个⽤户,我们可以在gitlab中进⾏如下权限划分,并验证
  • 1、使⽤ GitLab 的 root ⽤户,将 oldxu (LDAP ⽤户)设置为 GitLab 管理员权限。
  • 2、使⽤ldap的oldxu⽤户登陆gitlab, 在 GitLab 中创建dev和ops组;
  • 3、将 zhangsan、lisi 加⼊dev组,并分配 zhangsan 为主程序员、lisi 为开发者
  • 4、将 wangwu 加⼊ops组,并分配 wangwu 为主程序员。
  • 5、基于dev组创建mall项⽬仓库。
  • 6、验证 zhangsan 权限,将代码更新⾄mall仓库的主⼲分⽀ (main/master);
  • 7、 验证 lisi 权限,它只能提交代码到⾮主⼲分⽀,⽽后合并到主⼲,不能直接推送到主⼲分⽀。
  • 8、验证 wangwu 权限,由于它不是dev组成员,因此它看不到mall项⽬。

1、使⽤root⽤户,将oldxu设置为Gitlab管理员, 管理中⼼-->⽤户-->找到oldxu-->编辑-->访问级别-->管理员

2、使⽤ldap的oldxu⽤户登陆gitlab, 在 GitLab 中创建dev和ops组; 管理中⼼-->群组-->新建群组-->私有

3、点击dev组,管理-->成员

  • 将 zhangsan 加⼊群组,dev群组-->管理-->成员-->邀请 zhangsan 成员,并选择⻆⾊为 Maintainer
  • 将 lisi 加⼊群组,dev群组-->管理-->成员-->邀请 lisi 成员,并选择⻆⾊为 Developer

4、点击ops,管理-->成员,将 wangwu 加⼊群组,ops群组-->管理-->成员- ->邀请 wangwu 成员,并选择⻆⾊为 Maintainer

3.6 Gitlab⽤户权限验证

1、基于dev组创建mall项⽬仓库, 创建项⽬-->空⽩项⽬-->项⽬组选择dev--> 项⽬名称mall

2、验证 zhangsan 是否能更新代码⾄主⼲分⽀(main/master);

git config --global user.name "zhangsan"
git config --global user.email "zhangsan@qq.com"
git clone http://gitlab.oldxu.net/dev/mall.git
cd mall
echo "zhangsan commit" >> README.md
git add .
git commit -m "zhangsan add"
git push origin main

7、 验证 lisi ⽤户权限,它只能提交代码到⾮主⼲分⽀,并且不能直接推送到主⼲分⽀。

git config --global user.name "lisi"
git config --global user.email "lisi@qq.com"
git clone http://gitlab.oldxu.net/dev/mall.git
cd mall
echo "lisi commit" >> README.md
git add .
git commit -m "lisi add"
git push origin main
# 提交到主⼲分⽀,会提示如下错误(因此它只能提交到其他分⽀在合并到主⼲)
remote: GitLab: You are not allowed to push code to protected branches on
this project.
To http://gitlab.oldxu.net/dev/mall.git
 ! [remote rejected] main -> main (pre-receive hook declined)
错误:⽆法推送⼀些引⽤到 'http://gitlab.oldxu.net/dev/mall.git'

8、验证 wangwu 能否查看mall项⽬。(很显然是不⾏的)

4、OpenLDAP对接Jenkins

4.1 配置OpenLDAP⽤户权限

1、在 app-groups 下创建 jenkins-group 的组,并将 wangwu 和 laoliu 加⼊组中
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=jenkins-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: jenkins-group
member: uid=wangwu,ou=app-users,dc=oldxu,dc=net
member: uid=laoliu,ou=app-users,dc=oldxu,dc=net
EOF

2、在 app-groups 下创建 jenkins-admin-group 的组,并将 oldxu 加⼊组中

ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=jenkins-admin-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: jenkins-admin-group
member: uid=oldxu,ou=app-users,dc=oldxu,dc=net
EOF

4.2 Docker部署Jenkins

1、删除gitlab容器,避免端⼝冲突
docker rm -f gitlab

2、下载镜像

 docker pull uhub.service.ucloud.cn/oldxu/jenkins:2.452.1-lts-jdk17

3、运⾏Jenkins

docker run -d --name jenkins \
--hostname "jenkins.oldxu.net" \
--restart=always \
-p 80:8080 \
-p 50000:50000 \
-u root \
--privileged=true \
-e TZ=Asia/Shanghai \
-v /etc/localtime:/etc/localtime:ro \
-v /data/jenkins/jenkins_home:/var/jenkins_home \
uhub.service.ucloud.cn/oldxu/jenkins:2.452.1-lts-jdk17

3、获取Jenkins的root密码(登陆后记得修改密码)

[root@k8s-node35 ~]# cat /data/jenkins/jenkins_home/secrets/initialAdminPassword
155e3aff40ae4c3a9dfdf02fec4e8fae

4、安装jenkins插件

  • ldap相关: LDAP
  • 中⽂语⾔: Localization
  • RBAC权限管理: Role-based Authorization Strategy

4.3 配置Jenkins对接LDAP

1、点击系统管理—>全局安全配置-->安全域-->选择LDAP,并配置ldap服务器地址信息为: Server:ldap://ldap.oldxu.net:389

2、点击⾼级配置,填写基础配置信息

  • root DN(LDAP ⽬录树的根节点,定义 LDAP 搜索的起始位置): dc=oldxu,dc=net
  • User search base(定义⽤户查询的起始位置 ): ou=app-users
  • User search filter(基于uid查询⽤户名称,后续登陆系统后会被替换为⽤户名称): uid={0}
  • Group search base(定义⽤户组查询的起始位置 ): ou=app-groups
  • Group search filter(过滤组的查询条件):可不配置
  • Group membership attribute(使⽤memberOf获取⽤户对应的组): memberOf

3、继续配置

  • Manager DN(⽤于绑定到LDAP服务器的⽤户,要有权限): cn=admin,dc=oldxu,dc=net
  • Manager Password(绑定到LDAP服务器⽤户对应的密码): 123456
  • Display Name LDAP attribute( LDAP 中⽤于显示⽤户姓名的属性字段): uid
  • Email Address LDAP attribute( LDAP 中⽤于存储⽤户电⼦邮件地址的属性字段): mail

4、点击 Test LDAP settings ,测试LDAP⽤户是否能登陆系统,并获取到⽤户对应的组

4.4 验证LDAP⽤户登陆Jenkins

![](https://cdn.nlark.com/yuque/0/2025/png/35962777/1739020687457-7b3d2f49-b1c6-4fd3-8be8-24af1f8a9fa5.png)

2、测试⾮ jenkins-group 组中的⽤户能否登陆系统,例如: erma

4.5 配置Jenkins RBAC权限

前⾯测试发现,纵使不是 jenkins-group 组中的⽤户,同样能登陆系统,也能获取管理员权限。表明当前的LDAP认证没有问题,但是权限的设定有问题。因此我们需要配置RBAC权限来限制哪些组可以登陆,并拥有什么权限,例如:
  • jenkins-group :可以登陆,但只有普通⽤户的权限;
  • jenkins-admin-group :可以登陆,拥有超级管理员权限
  • 其他组 :登陆后会发现没有任何权限,相当于限制其他组登陆

1、配置授权策略为RBAC-->点击系统管理-->全局安全配置-->授权策略-->选择 Role-Based Strategy ,然后点击应⽤。

2、点击系统管理--> Manage and Assign Roles -->配置全局⻆⾊, 添加⼀个名为 user 的⻆⾊,为其分配普通⽤户权限

3、点击⻆⾊分配全局 Assign Roles

  • 1、关闭匿名访问
  • 2、将user⻆⾊分配给 jenkins-group 组
  • 3、将默认的admin⻆⾊分配给 jenkins-admin-group 组

4.6 测试Jenkins RBAC权限

1、测试jenkins-group成员登陆的权限

2、测试 jenkins-admin-group 成员登陆的权限

3、测试其他组成员的权限。例如: zhangsan 虽然可以登陆,但没有任何权限

4.7 提升LDAP⽤户权限

1、将erma加⼊ jenkins-admin-group 组,是否会拥有超级管理员权限
[root@k8s-master31 ~]# ldapmodify -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=jenkins-admin-group,ou=app-groups,dc=oldxu,dc=net
changetype: modify
add: member
member: uid=erma,ou=app-users,dc=oldxu,dc=net
EOF
modifying entry "cn=jenkins-admin-group,ou=app-groups,dc=oldxu,dc=net"

2、再次访问,会发现erma拥有超级管理员权限

5、OpenLDAP对接Harbor

5.1 配置OpenLDAP⽤户权限

1、在 app-groups 下创建 harbor-group 的组,⽤来存储普通⽤户,并将 lisi、wangwu 加⼊组中
[root@k8s-master31 ~]# ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=harbor-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: harbor-group
member: uid=lisi,ou=app-users,dc=oldxu,dc=net
member: uid=wangwu,ou=app-users,dc=oldxu,dc=net
EOF
adding new entry "cn=harbor-group,ou=app-groups,dc=oldxu,dc=net"

2、在 app-groups 下在创建⼀个 harbor-admin-group 的组,⽤来存储管理员⽤户,并将 laoliu、oldxu ⽤户加⼊该组中

ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=harbor-admin-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: harbor-admin-group
member: uid=laoliu,ou=app-users,dc=oldxu,dc=net
member: uid=oldxu,ou=app-users,dc=oldxu,dc=net
EOF

5.2 Docker部署Harbor

1、下载Harbor离线包
wget https://mirror.ghproxy.com/https://github.com/goharbor/harbor/releases/download/v2.12.0/harbor-offline-installer-v2.12.0.tgz

2、配置harbor仓库,然后通过脚本启动Harbor (如果使⽤http协议,需要注释掉https相关字段,否则会报错)

[root@harbor-node1 ~]# cd harbor/
[root@harbor-node1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor-node1 harbor]# vim harbor/harbor.yml
hostname = harbor.oldxu.net
harbor_admin_password = Harbor12345
[root@harbor-node1 harbor]# ./install.sh

3、通过 http://harbor.oldxu.net 访问harbor,⽤户:admin、密码: Harbor12345

5.3 配置Harbor对接ldap

1、点击配置管理-->认证模式-->选择LDAP
  • LDAP URL: ldap://ldap.oldxu.net:389
  • LDAP搜索DN: cn=admin,dc=oldxu,dc=net
  • LDAP搜索密码: 123456
  • LDAP基础DN(⽤户): ou=app-users,dc=oldxu,dc=net
  • LDAP过滤器
  • LDAP⽤户UID: uid
  • LDAP搜索范围: ⼦树
  • LDAP组基础DN: ou=app-groups,dc=oldxu,dc=net
  • LDAP组过滤器: objectClass=groupOfNames
  • LDAP组ID属性: cn
  • LDAP组管理员DN: cn=harbor-admin-group,ou=app-groups,dc=oldxu,dc=net
  • LDAP 组成员: memberof
  • LDAP组搜索范围: ⼦树

2、点击测试LDAP服务器,最后保存即可。

5.3 验证ldap⽤户登陆Harbor

1、测试 harbor-group 组成员登陆系统,例如: lisi、wangwu

2、测试 harbor-admin-group 组成员登陆Harbor

3、测试其他组成员登陆Harbor,会发现也能正常登陆,因此我们需要对Harbor的项⽬单独权限配置

5.4 配置Harbor项⽬权限

1、关闭默认所有⽤户都能创建项⽬的权限,配置管理-->系统设置-->,将项⽬创建权限修改为 仅管理员 ;

2、创建ops仓库,配置只能 harbor-admin-group 组成员可以管理,并且权限为项⽬管理员

3、创建dev仓库,配置 harbor-group 组成员可以有维护权限(上传镜像、下载镜像、删除镜像等。其他操作⽆权限)

5.5 验证Harbor项⽬权限

1、验证 harbor-admin-group 管理员权限,管理员能看到所有的项⽬

2、验证 harbor-group 普通⽤户权限,能看到dev项⽬,但看不到ops项⽬, 同时也不能创建新项⽬

3、验证其他组成员权限,只能看到公开项⽬,除此外什么也看不到,也不能创建新项⽬,等于没有任何权限

6、OpenLDAP对接OpenVPN

6.1 配置OpenLDAP⽤户权限

1、在 app-groups 下创建 openvpn-group 的组,并将 laoliu 和 oldxu 加⼊组中
ldapadd -x -D cn=admin,dc=oldxu,dc=net -w 123456 <<EOF
dn: cn=openvpn-group,ou=app-groups,dc=oldxu,dc=net
objectClass: groupOfNames
cn: openvpn-group
member: uid=laoliu,ou=app-users,dc=oldxu,dc=net
member: uid=oldxu,ou=app-users,dc=oldxu,dc=net
EOF

6.2 部署OpenVPN

1、安装openvpn、以及openvpn与ldap相关软件包

yum install ntpsec openvpn openvpn-auth-ldap -y
ntpdate time.windows.com
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p

2、上传openvpn服务端的证书,以及openvpn服务端的配置

wget http://file.oldxu.net/openvpn/openvpn_server_ldap.tar.gz
tar xf openvpn_server_ldap.tar.gz -C /etc/openvpn/server/

3、启动openvpn服务

systemctl start openvpn-server@server

4、配置对应的Iptables转发规则

iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -d 172.16.1.0/24 -j SNAT --to-source 当前主机内⽹IP
# 如果有docker的环境还需要加如下两条规则(允许 VPN 客户端访问内部⽹络,并允许内部⽹络返回相关的响应流量。)
[root@node03 ~]# iptables -A FORWARD -s 10.8.0.0/24 -d 172.16.1.0/24 -j ACCEPT
[root@node03 ~]# iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

5、客户端下载对应openvpn的配置⽂件

http://file.oldxu.net/openvpn/openvpn_client_ldap.tar.gz

6.3 配置OpenVPN对接LDAP

1、修改服务端 /etc/openvpn/server/server.conf 配置⽂件,告诉 OpenVPN 使⽤ openvpn-auth-ldap.so 插件,并从 /etc/openvpn/ser

ver/auth-ldap.conf ⽂件中读取 LDAP 相关配置

[root@node03 ~]# vim /etc/openvpn/server/server.conf
...
plugin /usr/lib64/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/server/
auth-ldap.conf
...

2、 创建 /etc/openvpn/server/auth-ldap.conf ⽂件,并定义LDAP相关配置信息

[root@node03 ~]# cat /etc/openvpn/server/auth-ldap.conf
<LDAP>
 # OpenLDAP 服务器的 URL
 URL ldap://ldap.oldxu.net:389
 # 基本的 DN,所有的搜索都从这个 DN 开始
 BindDN cn=admin,dc=oldxu,dc=net
 Password 123456
 # 不启⽤TLS认证
 TLSEnable no
 # 连接超时时间(秒)
 Timeout 15
</LDAP>
<Authorization>
 # ⽤户搜索的基本 DN
 BaseDN ou=app-users,dc=oldxu,dc=net
 # ⽤户登陆的⽤户名称
 SearchFilter "(uid=%u)"
 # true 强制要求⽤户必须属于某个特定的组才能连接
 RequireGroup true
 <Group>
 # ⽤户组的搜索基础 DN
 BaseDN ou=app-groups,dc=oldxu,dc=net
 
 # 组成员的属性
 MemberAttribute member
 
 # 允许连接的组名称,这⾥是 openvpn-group
 SearchFilter "cn=openvpn-group"
 </Group>
</Authorization>

3、重启openvpn服务

systemctl restart openvpn-server@server

6.4 OpenVPN客户端连接测试

1、修改客户端配置⽂件,启⽤⽤户名密码认证

auth-user-pass

2、使⽤ openvpn-group 组成员连接,能够成功链接VPN

3、使⽤⾮openvpn-group组成员测试,会发现连接失败

4、将 erma ⽤户加⼊到 openvpn-group

ldapmodify -x -D "cn=admin,dc=oldxu,dc=net" -w 123456 <<EOF
dn: cn=openvpn-group,ou=app-groups,dc=oldxu,dc=net
changetype: modify
add: member
member: uid=erma,ou=app-users,dc=oldxu,dc=net
EOF

5、再次测试连接,会发现已经正常了。

7、⾃助密码服务Self-Service-Password

7.1 为什么需要Self-Service-Password

在前⾯,我们已经成功的将OpenLDAP对接到了所有的应⽤系统上,但是,我们 会发现⽤户没办法直接通过应⽤系统完成密码的修改。原因是,所有的⽤户和密 码都存储在 LDAP 的服务中,⽽密码的修改必须在 LDAP 服务上进⾏操作,因此 应⽤系统⽆法直接变更对应⽤户的密码。

当然我们可以直接让管理员为⽤户进⾏密码修改,这种⽅法看似可⾏,却会带来以下两个问题:

  • 1、安全问题:管理员修改密码后,能直接获取到⽤户的密码信息,这显然不太安全。
  • 2、效率问题:当⽤户量增多时,频繁的密码修改,会给管理员带来不⼩的⼯作负担。

为了解决这些问题,我们可以引⼊⾃助密码管理⼯具Self-Service Password(SSP),它允许⽤户通过 Web 界⾯,⾃⾏修改存储在 LDAP 中的密码(⽆需管理员介⼊),这样就可以避免⽤户密码的泄露,同时还能提升管理效率。

7.2 安装Self-Service-Password

官⽅站点:https://github.com/ltb-project/self-service-password

1、配置 Self-Service-Password 的yum源

cat >> /etc/yum.repos.d/ltb-project.repo <<EOF
[ltb-project-noarch]
name=LTB project packages (noarch)
baseurl=https://ltb-project.org/rpm/\$releasever/noarch
enabled=1
gpgcheck=0
EOF

2、安装 httpd、php、self-service-password

yum install httpd php self-service-password -y

7.3 配置Self-Service-Password

1、编辑 /etc/self-service-password/config.inc.php 配置⽂件,以设置 Self-Service Password 与 OpenLDAP 的连接。
vim /etc/self-service-password/config.inc.php
// LDAP 服务器地址
$ldap_url = "ldap://ldap-master01.oldxu.net";
$ldap_starttls = false;
// LDAP 搜索基准(Base DN)
$ldap_base = "dc=oldxu,dc=net";
// LDAP 管理员绑定账户(⽤于修改密码时的身份验证)
$ldap_binddn = "cn=admin,dc=oldxu,dc=net";
$ldap_bindpw = '123456';
// ⽤户登录属性和过滤器
$ldap_login_attribute = "uid"; // ⽤户名字段(如 uid 或 cn)
$ldap_fullname_attribute = "cn"; // ⽤户全名字段
$ldap_filter = "(&(objectClass=person)($ldap_login_attribute={login}))";
// 加密算法(新密码采⽤的加密算法,避免明⽂存储)
$hash = "SSHA";
//在使⽤凭据加密前,必须在 keyphrase 设置中填写⼀个随机字符串
$keyphrase = "oldxuedu_20990909";
// 当⽤户请求密码重置时,系统会通过 $reset_url ⽣成完整的 URL地址发送到⽤户的邮箱。
$reset_url = "http://ssp.oldxu.net/";
## Mail
// 查找⽤户邮箱地址的属性,按顺序依次查找。
$mail_attributes = array( "mail", "gosaMailAlternateAddress", "proxyAddresses" );
//是否从LDAP中读取⽤户邮箱地址。如果设置为false,则需要⽤户⼿动输⼊邮件地址,但系统还是会与 LDAP 中的邮箱进⾏匹配。
$mail_address_use_ldap = true;
// 发件⼈信息
$mail_from = "572891887@qq.com";
$mail_from_name = "Self-Service-Password⾃助修改密码服务";
$mail_signature = ""; // 签名
$notify_on_change = false; // 密码修改后是否发送修改成功通知
$mail_sendmailpath = '/usr/sbin/sendmail'; // 发送邮件程序,如果使⽤ SMTP 协议,则此配置不会⽣效。
//SMTP配置
$mail_protocol = 'smtp';
$mail_smtp_host = 'smtp.qq.com';
$mail_smtp_auth = true;
$mail_smtp_user = '572891887@qq.com';
$mail_smtp_pass = 'jkgibvlqsepbbeic'; //授权码
$mail_smtp_port = 587; // SMTP 服务器的端⼝号 465(SSL/TLS)、587(STARTTLS)。
$mail_smtp_secure = 'tls'; // tls 则使⽤587端⼝、ssl则使⽤465端⼝。
$mail_smtp_autotls = true; // 是否⾃动启⽤ TLS。
$mail_smtp_options = array();
// 邮件内容
$mail_contenttype = 'text/plain'; // 纯⽂本格式邮件。
$mail_wordwrap = 0; // ⾃动换⾏的字符数。0表示不⾃动换⾏
$mail_charset = 'utf-8'; // 邮件的字符编码。
$mail_priority = 3; // 邮件的优先级。1:⾼优先级。3:普通优先级(默认)。5:低优先级。

2、修改 httpd 配置⽂件中 Self-Service-Password 服务对应的域名

[root@ldap-client01 ~]# cat /etc/httpd/conf.d/self-service-password.conf
<VirtualHost *:80>
 ServerName ssp.oldxu.net
 DocumentRoot /usr/share/self-service-password/htdocs
 DirectoryIndex index.php
 AddDefaultCharset UTF-8
 <Directory /usr/share/self-service-password/htdocs>
 AllowOverride None
 <IfVersion >= 2.3>
 Require all granted
 </IfVersion>
 <IfVersion < 2.3>
 Order Deny,Allow
 Allow from all
 </IfVersion>
 </Directory>
 Alias /rest /usr/share/self-service-password/rest
 <Directory /usr/share/self-service-password/rest>
 AllowOverride None
 <IfVersion >= 2.3>
 Require all denied
 </IfVersion>
 <IfVersion < 2.3>
 Order Deny,Allow
 Deny from all
 </IfVersion>
 </Directory>
 LogLevel warn
 ErrorLog /var/log/httpd/ssp_error_log
 CustomLog /var/log/httpd/ssp_access_log combined
</VirtualHost>

3、重启httpd服务

systemctl restart httpd

7.3 通过旧密码⽅式重置密码

![](https://cdn.nlark.com/yuque/0/2025/png/35962777/1739024938130-75d0f6a0-f36d-464c-854f-67b903c1c830.png)

7.4 通过邮箱⽅式重置密码

1、 点击邮箱,输⼊需要修改密码的⽤户名,系统会根据⽤户在 LDAP 中的 mail 属性查询其绑定的邮箱地址,并将密码重置的链接发送到该邮箱,如果邮箱不正确则⽆法收到重置密码的邮件。

2、登陆邮箱,查询重置密码的邮件

3、点击链接可以直接对⽤户进⾏密码变更

posted @ 2025-08-15 14:37  broadviews  阅读(38)  评论(0)    收藏  举报