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.rbvim /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
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/server/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-password1、配置 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 通过旧密码⽅式重置密码
7.4 通过邮箱⽅式重置密码
1、 点击邮箱,输⼊需要修改密码的⽤户名,系统会根据⽤户在 LDAP 中的 mail 属性查询其绑定的邮箱地址,并将密码重置的链接发送到该邮箱,如果邮箱不正确则⽆法收到重置密码的邮件。
2、登陆邮箱,查询重置密码的邮件

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


浙公网安备 33010602011771号