0%

ldap

ldap

什么是ldap

1
2
3
4
首先LDAP是一种通讯协议,LDAP支持TCP/IP。协议就是标准,并且是抽象的。在这套标准下,AD(Active Directory)是微软出的一套实现。
那AD是什么呢?暂且把它理解成是个数据库。也有很多人直接把LDAP说成数据库(可以把LDAP理解成存储数据的数据库)。像是其他数据库一样,LDAP也是有client端和server端。server端是用来存放资源,client端用来操作增删改查等操作。
而我们通常说的LDAP是指运行这个数据库的服务器。
可以简单理解AD =LDAP服务器+LDAP应用。

用途

1
用于统一认证管理,统一公司内部服务账号密码。

LDAP 模型

基本模型

1
2
3
4
5
目录树:在一个目录服务系统中,整个目录信息集可以表示为一个目录信息树,树中的每个节点是一个条目。
条目:每个条目就是一条记录,每个条目有自己的唯一可区别的名称(DN)。
对象类:是某个实体类型对应的一组属性,对象类可以继承,父类的必须属性也会被继承下来。
属性:描述条目的某个方面的信息,一个属性由一个属性类型和一个或多个属性值组成,属性有必须属性和非必须属性。

关键字 英文全称 含义
dc Domain Component 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com(一条记录的所属位置)
uid User Id 用户ID songtao.xu(一条记录的ID)
ou Organization Unit 组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织)
cn Common Name 公共名称,如“Thomas Johansson”(一条记录的名称)
sn Surname 姓,如“许”
dn Distinguished Name “uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一)
rdn Relative dn 相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson”
1
2
3
4
dn :一条记录的详细位置。目录位置
dc :一条记录所属区域 (哪一颗树)。根名称
ou :一条记录所属组织 (哪一个分支)。组名称
cn/uid:一条记录的名字/ID (哪一个苹果名字)。用户名称

img

信息模型

LDAP中,信息以树状方式进行组织的,在树状信息中的基本数据单元是条目,而每个条目由属性构成,属性中存储有属性值;

命名模型

即LDAP中的条目定位方式,在LDAP中每个条目均有自己的DN。
DN是该条目在整个树中的唯一名称标识,

如同文件系统中,带路径的文件名就是DN。

功能模型

在LDAP中共有四类10种操作︰
查询类操作:如搜索、比较;
更新类操作:如添加条目、删除条目、修改条目、修改条目名;
认证类操作:如绑定、解绑定;
其它操作:如放弃和扩展操作。

除了扩展操作,另外9种是LDAP的标准操作﹔

扩展操作是LDAP中为了增加新的功能,提供的一种标准的扩展框架,当前已经成为LDAP标准的扩展操作,有修改密码和startTLS扩展,

在新的RFC标准和草案中正在增加一些新的扩展操作,不同的LDAP厂商也均定义了自己的扩展操作。

安全模型

安全模型主要通过身份认证、安全通道和访问控制来实现。

ldap server

一般ldap服务端比较常用的是openldap,这里仅记录openldap的部署及使用。

openldap

ldap二进制部署

安装

1
2
3
4
5
sudo yum install -y openldap-servers openldap-clients
sudo cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
sudo chown ldap. /var/lib/ldap/DB_CONFIG
sudo systemctl enable slapd
sudo systemctl start slapd

设置root配置密码

备注:root配置密码用于命令行交互及更改提交配置时使用,客户端或ui服务连接server端不使用这个密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.生成密码
slappasswd -s 123456 #123456是密码,下面以{SSHA}是生成的加密字符串
{SSHA}S2l/T1ksX1bGBBIcz0jF9hMNeFPsjbis
2.生成配置导入文件
cat > chrootpw.ldif << EOF
#######
# specify the password generated above for "olcRootPW" section
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}S2l/T1ksX1bGBBIcz0jF9hMNeFPsjbis
#######将slappasswd命令生成的加密字符串填入到olcRootPW字段后面
EOF
3.执行ldapadd命令将配置导入到openldap server端
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif

导入基础schema

1
2
3
4
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

设置顶级域(top domain)信息

ldap正常使用需要存在顶级域。假设dc=mydomain,dc=com 或 dc=finsiot,dc=com。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
1.生成密码
slappasswd -s 123456
{SSHA}R2+srzimGU2i+1q+prffJoyWXtv6z08U
2.生成配置导入文件
cat > chdomain.ldif << EOF
#######该配置文件中定义了顶级域以及顶级域的管理员账号密码
# replace to your own domain name for "dc=***,dc=***" section
# specify the password generated above for "olcRootPW" section
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=admin,dc=mydomain,dc=com" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=mydomain,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=mydomain,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}R2+srzimGU2i+1q+prffJoyWXtv6z08U

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=admin,dc=mydomain,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=admin,dc=mydomain,dc=com" write by * read
#######1、里面的dc=mydomain,dc=com为顶级域,生成使用请自行修改。cn=admin是管理员cn(登录管理员)。2、olcRootPW需要填入刚刚生成的密码 3、客户端登录顶级域的时候使用的就是这里定义的admin以及密码
EOF
3.执行ldapadd命令将配置导入到openldap server端。
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif

设置域的组织架构

备注:该配置均可以通过客户端或ui服务配置,非必要配置以及非必要命令行方式。

该配置为顶级域下面的子级域生成(根据需求生成),例如我这里有一个dc=mydomain,com为顶级域,在实际使用中我需要至少再拥有两个域用于分别存储用户和组,则有以下几个域:

1
2
3
dc=mydomain,dc=com
| \
ou=people ou=group

用户域:ou=people,dc=mydomain,dc=com

组域:ou=group,dc=mydomain,dc=com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1.生成配置导入文件:
cat > basedomain.ldif << EOF
#######
dn: dc=mydomain,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: mydomain
dc: mydomain

dn: cn=admin,dc=mydomain,dc=com
objectClass: organizationalRole
cn: admin
description: LDAP admin

dn: ou=people,dc=mydomain,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=group,dc=mydomain,dc=com
objectClass: organizationalUnit
ou: group
#######每一个子级域为一个dn,objectclass是ldap对象的类型。
EOF
2.执行ldapadd命令将配置导入到openldap server端
sudo ldapadd -x -D cn=admin,dc=mydomain,dc=com -W -f basedomain.ldif

其他配置

备注:该配置均可以通过客户端或ui服务配置,非必要配置以及非必要命令行方式。

添加用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.生成密码
slappasswd -s 123456
{SSHA}BLXezbJTXbKQfovIPBmoBrVS9gcVI8x1
2.生成配置导入文件
cat > ldapuser.ldif << EOF
#######
dn: uid=user1,ou=people,dc=mydomain,dc=com
objectClass: inetOrgPerson
cn: commonname
sn: surname
uid: user1
userPassword: {SSHA}BLXezbJTXbKQfovIPBmoBrVS9gcVI8x1
#######将slappasswd命令生成的加密字符串填入到olcRootPW字段后面
3.执行ldapadd命令将配置导入到openldap server端
sudo ldapadd -x -D cn=admin,dc=mydomain,dc=com -W -f ldapuser.ldif
查询
1
ldapsearch -x -D "cn=admin,dc=mydomain,dc=com" -W -b "dc=mydomain,dc=com" -H ldap://
删除
1
ldapdelete -H ldap:// -D "cn=admin,dc=mydomain,dc=com" -w <password> "uid=user1,ou=people,dc=mydomain,dc=com"

k8s部署

相较于二进制部署,k8s的部署更为简单,这里通过bitnami提供的openldap镜像进行部署,这里在部署的时候顶级域以及admin域通过变量传参实现。所以这里部署的时候需要注意两个点,传参以及挂载,下面直接附上部署yaml,docker部署也可以参考该文件进行部署。

关于镜像的详细信息可以参考dockerhub:https://hub.docker.com/r/bitnami/openldap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
apiVersion: apps/v1
kind: Deployment
metadata:
name: openldap
spec:
replicas: 1
selector:
matchLabels:
app: openldap
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: openldap
spec:
containers:
- env:
- name: LDAP_ADMIN_USERNAME #admin用户
value: admin
- name: LDAP_ADMIN_PASSWORD #admin密码
value: "123456"
- name: LDAP_USERS #ldap用户
value: manager
- name: LDAP_PASSWORDS #ldap用户密码
value: "123456"
- name: LDAP_ROOT #顶级域
value: dc=finsiot,dc=com
image: bitnami/openldap:latest
imagePullPolicy: Always
name: openldap
ports:
- containerPort: 1389
name: service
protocol: TCP
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: "1"
memory: 2Gi
volumeMounts:
- mountPath: /bitnami/openldap/data
name: openldap-pvc
subPath: ldap
- mountPath: /bitnami/openldap/slapd.d
name: openldap-pvc
subPath: slapd.d
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: openldap-pvc
persistentVolumeClaim:
claimName: ldap-pvc
---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ldap-pvc
labels:
app: ldap
spec:
storageClassName: csi-rbd-sc #这里的storageclass是我们之前申请的
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: openldap
spec:
#clusterIP: 192.168.110.29
#externalTrafficPolicy: Cluster
ports:
- nodePort: 30300
port: 1389
protocol: TCP
targetPort: service
selector:
app: openldap
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}

ldap ui管理

管理操作ldap数据可以使用ldap客户端或者ldap管理服务工具实现。如果使用ldap windows客户端可以下载LDAPSoft Ldap Browser使用,如果使用管理web页面可以部署服务:ldapphpadmin。

ldapphpadmin

二进制部署

安装

1
2
3
yum -y install epel-release
yum -y install httpd php php-ldap php-gd php-mbstring php-pear php-bcmath php-xml
yum --enablerepo=epel -y install phpldapadmin

修改配置

修改phpldapadmin的配置文件

1
2
3
4
5
6
7
8
9
vim /etc/phpldapadmin/config.php
### 取消下面配置的注释
$servers->setValue(‘server’,’host’,’127.0.0.1’);
$servers->setValue(‘server’,’port’,389);
$servers->setValue(‘server’,’base’,array('dc=mydomain,dc=com')); # array里加上openldap配置文件中设置的olcSuffix
$servers->setValue(‘login’,’auth_type’,’session’);
$servers->setValue(‘login’,’attr’,’dn’);
### 注释该行
#$servers->setValue(‘login’,’attr’,’uid’);

修改httpd的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vim /etc/httpd/conf.d/phpldapadmin.conf 
#
# Web-based tool for managing LDAP servers
#

Alias /phpldapadmin /usr/share/phpldapadmin/htdocs
Alias /ldapadmin /usr/share/phpldapadmin/htdocs

<Directory /usr/share/phpldapadmin/htdocs>
<IfModule mod_authz_core.c>
# Apache 2.4
Require local
#添加下面这一行
Require all granted
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Allow from ::1
#添加下面这一行
Allow from all
</IfModule>
</Directory>

1
2
3
4
5
systemctl start httpd.service
访问 http://ip/phpldapadmin
登录账号密码为openldap安装完成后配置的顶级域管理员账号以及密码,例如我这里根据上面部署openldap的配置,我的账号密码为:
账号:cn=admin,dc=mydomain,dc=com
密码:123456

k8s部署

这个部署也比较简单,注意修改PHPLDAPADMIN_LDAP_HOSTS的变量值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f docker-compose.yml
kompose.version: 1.16.0 (0c01309)
creationTimestamp: null
labels:
io.kompose.service: phpldapadmin
name: phpldapadmin
spec:
replicas: 1
strategy: {}
selector: #定义选择器
matchLabels: #匹配上面的标签
io.kompose.service: phpldapadmin #匹配模板名称
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: phpldapadmin
spec:
containers:
- env:
- name: PHPLDAPADMIN_HTTPS
value: "false"
- name: PHPLDAPADMIN_LDAP_HOSTS
value: 'ldap://192.168.110.29:30389'
image: osixia/phpldapadmin:0.7.1
name: phpldapadmin
ports:
- containerPort: 80
resources: {}
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:ZZ
labels:
io.kompose.service: phpldapadmin
name: phpldapadmin
spec:
ports:
- name: "8080"
port: 8080
targetPort: 80
selector:
io.kompose.service: phpldapadmin

ldapphpadmin使用需要注意的地方

登录

登录的时候使用的是创建顶级域时创建的管理员账号以及其密码,账号是admin管理员的完整dn路径。例如我这里是账号为:cn=admin,dc=mydomain,dc=com。密码为:123456 。其他客户端登录也是使用这个账号密码密码

image-20230731162541776

创建条目

创建条目中,需要先点击该条目,然后会出现创建子条目

image-20230731163627151

子条目中用的最多的就是这三个:organisational unit、posix group、 user account。organisational unit是ou,posix group是用户组,user account是用户。创建用户也可以除了用useraccount也可以 使用simple security object,它们的区别主要在于useraccount有很多用户属性,而simple security object只有用户名和密码(当然,这个是由它们的objectclass决定的),如果仅仅只需要用户名和密码,可以使用这个创建。

image-20230731163805247

条目属性

首先是创建的条目dn,dn也就是其条目的全路径,而ou和cn是这个条目的路径名称,例如创建了一个组的条目,则这个条目是ou,创建一个用户或用户组,这个条目为cn。这里需要注意的是,例如这里创建了一个用户,其条目中有很多字段属性,但这里的字段属性名有些是不太准确的,这一点主要体现在应用于ldap对接时会配置一些用户的属性名,比如常见的登录用户名我们会用uid的字段,但这里显示uid字段为User name。所以这里在使用确认字段的时候请以尽量使用客户端登录ldap服务器并查看字段属性。image-20230731164556497

下面是ldapphpadmin和ldap browser的属性对比,可以看到实际上,这里客户端看到的才是真正的属性名。

image-20230731165300532

image-20230731165328380

所以这里一般ldapphpadmin用于管理ldap使用,但在进行配置查看其属性的时候,还是优先通过客户端连接查看。

关于ldap实现统一认证登录

对于ldap这种树形数据结构的数据库,在使用时,通常会存储两种信息:用户、用户组 ,但一般情况下这两种条目不会放在一起,会通过ou分开,这个ou是ldap的组,ou里面包含的下一级条目就是用户和用户组,每一个用户组以及每一个用户信息就是cn,cn的全路径被称为dn

1
2
3
4
5
6
7
8
9
例:
dc=mydomain,dc=com
| \
ou=group ou=people
| \
cn=group1 cn=group2 cn=user1 cn=user2

这里的ou=people下面的cn=user1、cn=user2就是用户,而ou=group下面的cn=group1、cn=group2就是用户组。应用在对接ldap时会有寻找用户位置dn的配置,通过用户dn位置来找到用户,例如这里要找到所有用户就应该是:ou=people,dc=mydomain,dc=com。
而用户组group是用于过滤用户的,仅允许在用户组里面的用户登录(里面一般会有一个memberuid的字段,该字段中包含改组的所有用户的用户名)。但用户组的配置一般是指定到具体组,例如我需要group1的用户登录该应用,配置应该为cn=group1,ou=group,dc=mydomain,dc=com 。指定到组的具体dn位置,而非像用户一样指定到用户dn的上一级目录。

用户以及用户组常用字段

用户和用户组里面本身还包含很多字段,这些字段是固定的,由objectclass提供的(objectclass是它们的顶级类,提供条目的所有字段)。这些字段则是用于对接应用的时候提供给应用的用户信息,像用户名、密码、邮箱、姓名、部门名称等信息都是记录在这里。

用户账号以及密码

通过上面可以知道,一个用户就是一个cn,但cn里面还有很多字段属性,如下图:

image-20230731153330696

1
2
3
4
首先是objectclass,这个是cn的顶级字段,objectclass下面的所有字段都继承于该字段,也可以说一个cn有哪些字段取决于它的objectclass有哪些字段。用户cn和组cn以及ou的本质区别也是objectclass的不同。objectclass本身定义了其对象的所有字段以及该对象的类型(在使用中大部分用户相关字段都源于inetorgpersion,该字段常用于用户过滤)。

用户名,这个没有固定的,也就是一般在配置的时候会指定某一个字段为用户名,常见的用户名字段有:cn、uid、sn。默认一般使用uid。
密码,这个是固定字段,就是userPassword字段,但真正使用的时候,不会让填写密码字段,因为这个是固定字段。

用户组

该条目一般记录该用户组中有哪些用户,用于ldap登录用户组过滤。其中记录组成员的字段是memberuid,该字段值一般对应用户的登录账号,默认是对应用户的uid字段。但使用用户组过滤的前提是应用有组过滤的配置(很多服务不提供组过滤配置项)。

image-20230731170647167

用户其他常用字段

用户名称:这个没有统一的字段表示,使用description或者displayname等字段都可以

邮箱:一般使用mail字段

ou:用于记录用户组的字段。一般情况下用用户组来记录成员,通过应用的组筛选就可以实现用户过滤,但对于大多数应用服务来说,是没有group筛选的(或者很多是商业版才支持),只有用户筛选,就可以通过该字段来识别用户是否为该组。

objectclass介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
LDAP中,一个条目(Entry)必须包含一个对象类(objectClass)属性,且需要赋予至少一个值。每一个值将用作一条LDAP条目进行数据存储的模板;模板中包含了一个条目必须被赋值的属性和可选的属性。

objectClass有着严格的等级之分,最顶层是top和alias。例如,organizationalPerson这个objectClass就隶属于person,而person又隶属于top。

objectClass可分为以下3类:
结构型(Structural):如account、inetOrgPerson、person和organizationUnit;
辅助型(Auxiliary):如extensibeObject;
抽象型(Abstract):如top,抽象型的objectClass不能直接使用。

每种objectClass有自己的数据结构,比如我们有一种叫“电话薄”的objectClass,肯定会内置很多属性(attributes),如姓名(uid),身份证号(uidNumber),单位名称(gid),家庭地址(homeDirectory)等,这些属性(attributes)中,有些是必填的,例如,account就要求userid是必填项,而inetOrgPerson则要求cn(common name,常用名称)和sn(sure name,真实名称)是必填项。

accout内置的attributes有:userid、description、host、localityName、organizationName、organizationalUnitName、seeAlso;

inetOrgPerson内置的attributes有cn、sn、description、seeAlso、telephoneNumber、userPassword、destinationIndicator、facsimileTelephoneNumber、internationaliSDNNumber、l、ou、physicalDeliveryOfficeName、postOfficeBox、postalAddress、postalCode、preferredDeliveryMethod、registeredAddress、st、street、telephoneNumber、teletexTerminalIdentifier、telexNumber、title、x121Address、audio、usinessCategory、carLicense、departmentNumber、isplayName、employeeNumber、employeeType、givenName、homePhone、homePostalAddress、initials、jpegPhoto、labeledURI、mail、manager、mobile、o、pager、photo、preferredLanguage、roomNumber、secretary、uid、userCertificate等;

由上可见,accout仅仅预置了几个必要且实用的属性(完成登陆验证肯定是够了),而inetOrgPerson内置了非常之多的属性,例如电话号码、手机号码、街道地址、邮箱号码,邮箱地址,房间号码,头像,经理,雇员号码等等。

因此,在配置LDAP时,如果仅仅是基于验证登陆的目的,建议将objectClass类型设置为accout,而如果希望打造一个大而全的员工信息宝库,建议将objectClass设置为inetOrgPerson。

当然,对于一个Entry来说,仅仅有accout或者inetOrgPerson是不够的,在安装配置LDAP时,本文介绍了使用migrationtools工具,将Linux系统用户转化为ldif格式的文件,进而导入到LDAP中。在这个过程里,导出的user,会同时具备accout、posixAccount、shadowAccount、top这4个objectClass,而导出的group,则会同时具备和posixGroup、top两个objectClass。

上面已经写出,account的必要属性是userid,而
posixAccount的必要属性是cn、gidNumber、homeDirectory、uid、uidNumber;
shadowAccount的必要属性是uid,可选属性有shadowExpire、shadowInactive、shadowMax、shadowMin、userPassword等;
top必要属性是objectClass(可见,top和其它objectClass是继承的关系)。

服务集成ldap

nexus for ldap

本文主要为nexus集成到ldap的配置,由于网上关于该功能的配置大都层次不齐且写的太模糊,故记录此文档。

1、ldap配置

这里ldap用的是openldap,所以首先需要部署好openldap。首先想要在nexus中集成ldap,ldap的服务端必须要有组和用户。

1
2
这里的组用来映射与nexus的角色,使其组下面的用户都拥有nexus映射角色的权限,无需额外配置。
这里的用户则用来登录nexus。

所以需要创建好组和用户,这里以映射一个nexus管理员为例子,首先创建准备好ldap的用户和组:

1
2
3
创建一个ou为nexus,组为manager,用户为nexus,先创建组,然后创建用户指定组。
组:cn=manager,ou=nexus,dc=finsiot,dc=com
用户:cn=nexus,ou=nexus,dc=finsiot,dc=com

image-20221110171353237

2、nexus配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1.访问nexus-web管理页面,登录管理员账号,进入设置-》secruity-》LDAP-》create connection
2.connection配置:
name:这个是要创建的ldap名称,可以随便填,非关键性参数。
Ldap server address:填入ldap地址
Search base Dn:填入dn地址(dc的地址)
Authentication method: Simple Authentication
Username or DN: 填入登录用户名(一般用admin管理员登录)
password: 密码
3.User and group配置:
configuration template: 选择一个模板,非关键性参数,只是会预先给出下面一些参数的值。这里可以选posix with static groups
user relative dn(base dn):对应于用作用户条目基础的专有名称集合。此DN与前面的search base相关。例如,如果用户都包含在ou = nexus,dc=finsiot,dc=com中,前面登录时指定了dc=finsiot,dc=com的搜索库,则这里使用值ou = nexus。
User subtree: 如果基本DN下面的树可以包含用户条目,则值为true;如果所有用户都包含在指定的基本DN中,则为false。例如,如果所有用户都在ou = users,dc = sonatype,dc = com,则此字段应为False。如果用户可以在组织单位内的组织单位中显示,例如ou = development,ou = users,dc = sonatype,dc = com,则此字段应为True。
Object class: 此值是RFC-2798中定义的标准对象类。它为用户指定对象类。常见值为inetOrgPerson,person,user或posixAccount。这里使用模板默认的posixAccount
User filter: 这允许您配置过滤器以限制对用户记录的搜索。它可以用作性能改进。这里不用填写。
User ID attribute: 这是上面指定的对象类的属性,它从LDAP服务器提供用户的标识符。存储库管理器使用此属性作为用户ID值。在ldap创建了用户以后,里面有一个属性值(默认为uid),例如我这里创建了一个nexus的用户,则会有一个uid的值为nexus,nexus服务需要通过这个key:value来找到该用户
Real name attribute: 这是Object类的属性,它提供用户的真实姓名。存储库管理器在需要显示用户的真实姓名时使用此属性,类似于内部名字和姓氏属性的使用。这个也是去找ldap里面的kv属性,默认是key的名称为cn。
Email attribute: 同上面的User ID attribute和Real name attribute,默认key的名称为mail。
Password attribute:不用填写,这里为空则会在登录时读取ldap中用户的password字段。
Map LDAP groups as roles:这里需要勾选,下面是组的配置,用于将ldap组映射于nexus。
Group type: static Groups 这里选择静态组
Group relative DN: 指名组的DN位置,例如我这里manager组在nexus下面,则这里填ou=nexus。
Group subtree: 勾选,表示是位于group下面的子组。例如我上面ou=nexus,则这里勾选的意思是nexus下面的组。
Group object class: 组创建时会有这个字段,默认为posixGroup。和上面定义User ID attribute和Real name attribute和Email attribute是一样的。
Group ID attribute: 这里表示组的id属性,和上面定义User ID attribute和Real name attribute和Email attribute是一样的。
Group member attribute: 这里表示组里面有哪些成员,和上面两个属性一样,也是ldap组中的字段,但默认不会创建这个字段,请手动创建memberUid的字段并把成员的字段值写入该字段,否则会找不到映射的角色。
Group member format: 该字段用来找到memberUid中的组员名称的,使用变量${username}。

image-20221110171338946

image-20221110171215302

image-20221110171237900

image-20221110171249864

创建角色

在nexus设置-》security-》roles中添加一个role,type为external role mapping,external role type为ldap。

image-20221110171612944

1
2
3
4
5
Mapped Role:请填写为ldap中创建的组名称,两个服务会通过名称进行映射,例如我这里ldap中有一个nexus用户,在manager组下面,于是这里我定义一个mapped role为manager,则nexus以及ldap中manager组中所有用户都会拥有这里定义好的权限,也就是组权限映射。
Role Name: role角色的名称。
Role Description: 角色介绍。
Privileges:定义的是角色的权限。
Roles:可以与其它定义好的role关联权限。

测试

创建好以后回到刚刚的ldap设置,点击刚刚创建的ldap,进入user and group设置,最下方有一个 verify user mapping 。

image-20221110171936912

点击属于ldap密码就可以看到目前定义映射的组和用户情况

image-20221110172056058

这里user id其实就是上面user id attribute配置,name为Real name attribute配置,email为Email attribute,roles是Map LDAP groups as roles及下面所有组配置定义的。如果有没有数据的字段,请检查该项对应配置的字段是否正常配置,例如如果roles没有,请看一下Map LDAP groups as roles下面的配置是否正确。

jenkins for ldap

jenkins集成ldap的方法

1、安装插件

Jenkins安装LDAP插件

2、配置ldap

进入管理设置(manage jenkins)->全局安全设置(configure global security),设置安全域为ldap

image-20230210101753775

配置项

1
2
3
4
5
6
7
8
9
10
11
Server:ldap的地址url
root DN:根DN目录路径
User search base:查找用户的目录
User search filter:查找用户的条件
Group search base: 查找用户组的目录
Group search filter: 用户组条件(查找用户的条件)
Group membership:选择 Search for LDAP groups containing user
Manager DN: 管理员所在路径
Manager Password: 管理员密码
Display Name LDAP attribute: jenkins对应ldap用户名的字段
Email Address LDAP attribute:email字段

配置示例:

image-20230210102814010

这里ldap的结构为,用户目录:ou=people,dc=xxx,dc=com,用户组目录:ou=group,dc=xxx,dc=com

image-20230210103422255

image-20230210103437606

这里需要注意的点是:user search filter用于找到用户,如果这里填错了将会找不到用户。group search base则是用于找到用户组,如果这里填错了将找不到用户,而search filter用于找到用户组中的用户(&(objectClass=posixGroup)(memberUid={1})),这里的用户组主要用于授权时使用,对组进行授权。

测试

配置完成可以点击test ldap settings测试一下:

image-20230210104457142

image-20230210104515248

gitlab for ldap

gitlab并不能直接通知页面设置来对接ldap,而是通过配置文件。

1、ldap配置(二进制部署)

这里配置分为两种:一种是二进制包部署的gitlab,这个由于我并没有部署过,所以下面的配置摘抄于网上,不清楚版本有没有配置变化,但配置大致的字段基本应该是一致的;还有一种方法是k8s的配置,这种也是目前我在使用的方式,会在下面列出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
如果是二进制部署的则直接更改配置文件
vi /etc/gitlab/gitlab.rb

gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'LDAP', # 随便自定义
'host' => '10.0.20.19', # ldap的server地址
'port' => 389, # ldap端口
'uid' => 'cn', # 配置为cn或者sn都可以,但要注意用户名称将会以此处配置为依据
'bind_dn' => 'cn=admin,dc=aihelp,dc=net', # 管理员账号
'password' => '123456', # 管理员密码
'encryption' => 'plain', # 加密
'allow_username_or_email_login' => false, # 是否启用邮件作为用户名登陆
'block_auto_created_users' => false,
'base' => 'dc=aihelp,dc=net', # 核心配置,表示从哪一层读取用户信息
'user_filter' => '(memberof=cn=jenkins,ou=group,dc=aihelp,dc=net)', # LDAP用户进行过滤
'lowercase_usernames' => false,
'group_base' => '',
'admin_group' => '',
'external_groups' => [],
'sync_ssh_keys' => false
}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
其中:
label 是显示在GitLab登录框的上方文字描述。
host 和 port 是 LDAP 服务的主机地址及端口
bind_dn 和 password 是一个管理 LDAP 的 dn 及密码
base 表示 LDAP 将以该 dn 为 节点,向下查找用户
user_filter 表示以某种过滤条件筛选用户,比如假设我们只希望所属组为 java-platform 的用户来访问 GitLab,则可以在这里设置 (memberOf=ou=java-platform,ou=people,dc=domain,dc=com)

配置添加之后,依旧像安装时候那样,重载一下配置:
gitlab-ctl reconfigure


Checking LDAP ...
LDAP: ... Server: ldapmain
LDAP authentication... Success
LDAP users with access to your GitLab server (only showing the first 100 results)
DN: uid=test01,ou=people,dc=eryajf,dc=net cn: ceshi
DN: uid=test02,ou=people,dc=eryajf,dc=net cn: test02
DN: uid=test03,ou=people,dc=eryajf,dc=net cn: test03
DN: uid=admin,ou=people,dc=eryajf,dc=net cn: Admin
Checking LDAP ... Finished
使用ldap用户名密码进行登陆即可,此时登陆进去是没有任何项目的权限,如果需要某权限,可以对用户进行组或者单项目的授权。

2、ldap配置(k8s)

ldap这里直接用helm的values.yaml传递配置文件信息,所以在ldap中配置就行了。这里如果是部署也建议采用helm部署,由于gitlab新版本模块过多,如果写yaml文件的话再加上配置文件和需要持久化的存储路径很麻烦,所以使用helm是比较理想的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
values.yaml:
----
ldap:
# prevent the use of LDAP for sign-in via web.
preventSignin: false
servers:
main:
label: 'LDAP'
host: '192.168.110.29' #ldap地址
port: 30389 #端口
uid: 'uid'
bind_dn: 'cn=admin,dc=finsiot,dc=com' #管理员路径
password: #管理员密码
secret: my-ldap-password-secret
key: the-key-containing-the-password
encryption: 'plain'
base: 'ou=people,dc=finsiot,dc=com' #用户路径
verify_certificates: true #忽略证书
active_directory: false
allow_username_or_email_login: true #支持邮件和用户名登录
block_auto_created_users: false
user_filter: ''
attributes:
username: ['cn'] #用户名对应ldap字段
email: ['mail','email'] #邮箱对应ldap字段
name: 'description' #用户显示名字对应ldap字段
fister_name: 'givenName'
last_name: 'sn'

需要注意的是,gitlab-ce仅支持ldap的用户配置,不支持ldap用户组的配置,如果想要使用ldap用户组,需要使用gitlab-ee(商业版本)。

ldap的配置文件是configmap:gitlab-webservice下面的gitlab.yml.erb,挂载于gitlab-webservice-default的/var/opt/gitlab/templates/gitlab.yml.erb路径。

gitlab拉取ldap账号数据

问题

ldap与应用结合一般有两种,一种是服务需要登录时去调用ldap的账号数据实现结合,还有一种是服务预先将ldap存在自己数据库中然后通过ldap的账号进行登录。而gitlab则是后者,这种情况会导致新加了账号但是ldap却没办法直接用新账号登录,因为gitlab并非是登录直接去ldap调用,而是从自己数据库中找ldap账号数据。

解决办法
1、定时

​ 可以在gitlab中设置每日定时任务,定时从ldap中拉取数据到自己的数据库。

1
2
3
4
5
6
7
8
9
10
K8S:
这里k8s是在helm的部署文件values.yaml添加修改:
cron_jobs:
ldap_sync_worker:
cron: "30 1 * * *"
ldap_group_sync_worker:
cron: "0 * * * *"
二进制部署:
请查看官方文档:https://docs.gitlab.cn/jh/administration/auth/ldap/ldap_synchronization.html

2、手动拉取
1
2
手动拉取使用gitlab-rake gitlab:ldap:check命令就可以,这个是测试ladp的命令,测试的同时会拉取一遍数据。
如果是k8s需要在gitlab-toolbox容器中执行该命令

mindoc for ldap

mindoc是一款开源wiki服务,由于比较冷门,后面可能几乎用不到,这里就简略记录一下,直接贴上配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
app.conf #mindoc配置文件
#是否启用ldap
ldap_enable=true
#ldap主机名
ldap_host=192.168.110.29
#ldap端口
ldap_port=30389
#ldap内哪个属性作为用户名
ldap_attribute=uid
#搜索范围
ldap_base=dc=finsiot,dc=com
#第一次绑定ldap用户dn
ldap_user=cn=admin,dc=finsiot,dc=com
#第一次绑定ldap用户密码
ldap_password=123456
#自动注册用户角色:0 超级管理员 /1 管理员/ 2 普通用户
ldap_user_role=2
#ldap搜索filter规则,AD服务器: objectClass=User, openldap服务器: objectClass=inetOrgPerson ,也可以定义为其他属性,如: title=mindoc
ldap_filter=objectClass=inetOrgPerson(常用的objectClas有top、inetOrgPerson、posixAccount)

直接配置好重启应用就可以使用ldap账号登录了。

zentao for ldap

禅道服务接入ldap

ldap插件部署

禅道本身不支持ldap,需要额外安装ldap插件。插件地址:https://github.com/yihoyoung/zentao-ldap

需要注意的是目前这个版本最高仅支持禅道12,本人测试在禅道18版本上面不兼容。

其安装步骤在github的readme中有说明:

1
2
3
4
1.打包 ldap 文件夹为 ldap.zip 文件
2.创建文件:
touch /www/zentaopms/www/ok.txt
3.admin 账户登陆禅道,后台 -> 插件 -> 本地安装,选择打包的 ldap.zip 文件安装即可

具体步骤

下载ldap代码,将这个文件打包成zip。

image-20230213152207304

在服务器上面创建该文件:touch /www/zentaopms/www/ok.txt

然后登录禅道管理员账号,部署插件如下:

image-20230213152502090

安装文件时提示版本不兼容点击强制安装即可。

image-20230213152747071

安装成功以后后台会有ldap配置项:

image-20230213140948096

ldap配置说明

1
2
3
4
5
6
7
8
9
LDAP服务器: ldap地址
协议版本: 默认填写3
BindDN: 管理账号地址
BindDN 密码: 管理账户密码
BaseDN: 用户地址
Search filter: 搜索用户的条件,objectClass=inetOrgPerson(常用的objectClas有top、inetOrgPerson、posixAccount),不同的ldap服务不一样
账号字段: 登录用户名字段
EMail 字段: 邮箱字段
姓名字段: 名字字段

ldap配置完以后先点击保存配置,然后点击手动同步,如果有同步的用户信息那就表示没问题了。

image-20230213153228070

最后在组织-》用户中查看已经通过ldap导入的用户信息。

注意:配置了ldap以后系统原账号登录需要在用户名前面加上“$”符号,例如$admin。

jellfin for ldap

管理员登陆,设置-》控制台-》插件-》目录-》LDAP-Auth-》安装-》重启jellyfin。

然后再设置-》控制台-》插件-》目录-》我的插件-》LDAP-Auth-》点击进去

这里直接看图,因为jellyfin配置ldap很简单并且很难再用到,这里就不详细说这个了。

image-20230424173258695

image-20230424173316006

image-20230424173340649

jumpserver for ldap

管理员登陆-》系统设置(右上角)-》认证设置-》LDAP

1
2
3
4
5
6
7
8
9
10
11
12
LDAP 地址 : ldap://ldap:389
绑定 DN: cn=admin,dc=xxx,dc=com #这里填管理员dn
密码: xxx #管理员密码
用户 OU: 用户所在OU
用户过滤器: (&(objectClass=posixAccount)(!(uid={0}))) #用户objectClass需要有posixaccount才行
用户属性映射:
{
"username": "uid",
"name": "description",
"email": "email"
} #账号名字邮箱映射字段

image-20230424174123144

填完以后右下角提交,然后测试连接后用户导入。用户导入时要点一下刷新键用户才会出来。

metersphere for ldap

系统设置-》系统参数设置-》LDAP设置

1
2
3
4
5
6
LDAP地址:ldap的地址
绑定DN: ldap管理员dn路径
密码: ldap管理员密码
用户OU: 用户所在的OU路径(用户所在路径的上一级OU路径)
用户过滤器: 过滤用户的配置,这里(uid={0})表示用户名为uid的用户
LDAP属性映射:将ldap的字段映射为metersphere的用户字段

image-20230801135314157

配置完需要测试连接和登录测试,如果测试连接有问题那需要检查LDAP地址、绑定DN、密码的配置,如果是测试登录有问题,请检查用户OU、用户过滤器、LDAP属性映射的配置,测试连接和登录时只有出现以下弹框时才是正常的。

image-20230801140702008

image-20230801141812238