LDAP说明

什么是LDAP?

  轻型目录访问协议(Lightweight Directory Access Protocol,LDAP):是一个开放的、中立的、业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息,它是由目录数据库和一套访问协议组成的系统,详情请查看维基百科LDAP

为什么用LDAP?

  LDAP是开放的Internet标准,市场上或者开源社区的绝大多数软件都支持LDAP协议。简单来说,LDAP协议最大的好处就是能统一管理用户密码,新人报道创建一个用户就能登录公司的所有平台(gitlab、jumpserver、监控等等),离职一键删除即可。

LDAP相关概念

  • dn(Distinguished Name):区分名称,LDAP中每个条目都有自己的dn,dn是该条目在整棵树中的唯一标识,如同文件系统中,带路径的文件名就是DN。
  • rdn(Relative dn):相对区别名称,好比linux中的相对路径。
  • dc(Domain Component):域名组件。其格式是将完整的域名分成几部分,如将example.com变成dc=example,dc=com。
  • uid(User ID):用户ID,如merle.chang。
  • ou(Organization Unit):组织单元。
  • cn(Common Name):公共名称。
  • sn(surname):姓氏。
  • c(Country):国家,如“CN”或者“US”。
  • o(Organization):组织名,如中华人民共和国公安局。

部署OpenLDAP

创建数据目录

1
2
mkdir -pv /data/openldap/{data,conf}
mkdir -pv /data/docker-compose/openldap

配置docker-compose文件

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
version: "3"
services:
openldap:
container_name: openldap
image: osixia/openldap:1.5.0-amd64
restart: always
ports:
- 389:389
- 636:636
volumes:
- /etc/localtime:/etc/localtime
- /etc/localtime:/etc/localtime
- /data/openldap/data:/var/lib/ldap
- /data/openldap/conf:/etc/ldap/slapd.d
environment:
LDAP_TLS_VERIFY_CLIENT: never
LDAP_ORGANISATION: git
LDAP_DOMAIN: git.com.cn
LDAP_ADMIN_PASSWORD: G1T@Ldap
LDAP_CONFIG_PASSWORD: G1T@Ldap

networks:
- openldap
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 1G

phpldapadmin:
container_name: phpldapadmin
image: osixia/phpldapadmin:0.9.0-amd64
restart: always
links:
- openldap
depends_on:
- openldap
ports:
- 8099:80
volumes:
- /etc/localtime:/etc/localtime
environment:
- PHPLDAPADMIN_LDAP_HOSTS=192.168.2.101
- PHPLDAPADMIN_HTTPS=false
networks:
- openldap
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 256M

networks:
openldap:

LDAP_TLS_VERIFY_CLIENT: 客户端认证,never代表不需要认证
LDAP_ORGANISATTON: 组织名称
LDAP_DOMAIN: 域名
LDAP_APMIN_PASSWORD: 超级管理员密码

-p 389:389 # LDAP端口
-p 636:636 # LDAP加密端口

PHPLDAPADMIN_HTTPS: 关闭https认证
PHPLDAPADMIN_LDAP_HOSTS: 需要连接的ldap服务器地址

启动

1
docker-compose up -d

ldapadmin登录

1
2
3
4
dn:
cn=admin,dc=git,dc=com,dc=cn
口令:
G1T@Ldap

常用操作命令

创建OU

创建顶级ou

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat > add_ou.ldif << EOF
dn: ou=Group,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Group

dn: ou=People,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: People

dn: ou=cn,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: cn
EOF

ldapadd -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" -f add_ou.ldif

创建自定义ou

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
cat > add_custom_ou.ldif << EOF
dn: ou=Jenkins,ou=Group,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Jenkins

dn: ou=GitLab,ou=Group,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: GitLab

dn: ou=Jira,ou=Group,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Jira

dn: ou=Confluence,ou=Group,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Confluence

dn: ou=Admin,ou=People,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Admin

dn: ou=Users,ou=People,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Users
EOF

ldapadd -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" -f add_custom_ou.ldif

创建组

添加一个组, 在Jenkins的OU下

1
2
3
4
5
6
7
8
9
cat > group_jenkins.ldif << EOF
dn: cn=users,ou=Jenkins,ou=Group,dc=git,dc=com,dc=cn
objectClass: posixGroup
objectClass: top
cn: users
gidNumber: 4002
EOF

ldapadd -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=example,dc=org" -w "G1T@Ldap" -f group_jenkins.ldif

注意dn的顺序,否则报错

创建账户

添加用户小明, 位置在Users的OU下,并绑定到Jenkins的用户组Users中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat > xiaoming.ldif << EOF
dn: cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: xiaoming
sn: xiao
uid: xiaoming
userPassword: 123456
uidNumber: 44001
gidNumber: 4002
homeDirectory: /home/users/xiaoming
mail: xiaoming@test.com.cn
title: add user xiaoming
EOF

ldapadd -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" -f xiaoming.ldif

为用户设置密码

1
2
3
ldappasswd -x -h 127.0.0.1 -p 389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap"  "cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn"

New password: .NrQ5pow

搜索

1
2
3
4
5
# 搜索全部
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=git,dc=com,dc=cn" -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap"
# 正则匹配
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=git,dc=com,dc=cn" -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" "cn=xiao*"
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=git,dc=com,dc=cn" -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" "ou=*"

删除

删除用户小明

1
ldapdelete -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" "cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn"

删除Jenkins的users组

1
ldapdelete -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" "cn=users,ou=Jenkins,ou=Group,dc=git,dc=com,dc=cn"

modify

添加用户小红

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat > xiaohong.ldif << EOF
dn: cn=xiaohong,ou=Users,ou=People,dc=git,dc=com,dc=cn
changetype: add
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: xiaohong
sn: xiao
uid: xiaohong
userPassword: 123456
uidNumber: 44002
gidNumber: 4002
homeDirectory: /home/users/xiaohong
mail: xiaohong@test.com.cn
title: add user xiaohong
EOF

ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" -f xiaohong.ldif

dn要写在changetype上面

常用方法

  • 添加ou
1
2
3
4
5
dn: ou=Jira,ou=Group,dc=git,dc=com,dc=cn
changetype: add
objectClass: organizationalUnit
objectClass: top
ou: Jira
  • 添加组
1
2
3
4
5
6
dn: cn=jira-administrators,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: add
objectClass: groupOfUniqueNames
objectClass: top
cn: jira-administrators
uniqueMember: cn=admin,ou=Users,ou=People,dc=git,dc=com,dc=cn
  • 修改属性
1
2
3
4
dn: cn=xiaoming,ou=Users,dc=git,dc=com,dc=cn
changetype: modify
replace: title
title: this is a new title
  • 添加属性
1
2
3
4
dn: cn=jira-software-users,ou=Jira,ou=Group,dc=git,dc=com,dc=cn
changetype: add
add: description
description: this is a add description
  • 添加用户到组
1
2
3
4
dn: cn=jira-software-users,ou=Jira,ou=Group,dc=git,dc=com,dc=cn
changetype: modify
add: uniqueMember
uniqueMember: cn=xiaohong,ou=Users,dc=example,dc=org
  • modrdn
1
2
3
4
5
6
7
8
cat > modrdn.ldif << EOF
dn: cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn
changetype: modrdn
newrdn: cn=xiaoming2
deleteoldrdn: 0
newsuperior: ou=Users,ou=People,dc=git,dc=com,dc=cn
EOF
ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w "G1T@Ldap" -f modrdn.ldif
  • 修改密码
1
2
3
4
5
6
7
cat > changepwd.ldif << EOF
dn: cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn
changetype: modify
replace: userPassword
userPassword: xiaomingpwd
EOF
ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=xiaoming,ou=Users,ou=People,dc=git,dc=com,dc=cn" -w .NrQ5pow -f changepwd.ldif

LDAP用户权限配置

创建管理ou

创建顶级manager,在manager下创建admins(管理),readonly(只读),password_manager(密码管理)等ou

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat > add_manager_ou.ldif << EOF
dn: ou=Manager,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: Manager

dn: ou=admins,ou=Manager,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: admins

dn: ou=readonly,ou=Manager,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: readonly

dn: ou=password_manager,ou=Manager,dc=git,dc=com,dc=cn
objectClass: organizationalUnit
objectClass: top
ou: password_manager
EOF

ldapadd -x -D cn=admin,dc=git,dc=com,dc=cn -w 'G1T@Ldap' -f add_manager_ou.ldif

配置权限

  1. 通过查看/etc/ldap/slapd.d/cn=config来确定olcDatabase配置文件, 比如我的是olcDatabase={1}mdb.ldif, 根据olcDatabase={1}mdb.ldif配置文件来确定dn位置, 我的是olcDatabase={1}mdb
  2. 根据olcDatabase={1}mdb.ldif配置文件, 重新编写访问控制
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
cat > new-acl.ldif << EOF 
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange
by self write
by dn="cn=admin,dc=git,dc=com,dc=cn" write
by dn.children="ou=admins,ou=Manager,dc=git,dc=com,dc=cn" read
by dn.children="ou=password_manager,ou=Manager,dc=git,dc=com,dc=cn" write
by anonymous auth
by * none
olcAccess: {2}to *
by self read
by dn="cn=admin,dc=git,dc=com,dc=cn" write
by dn.children="ou=admins,ou=Manager,dc=git,dc=com,dc=cn" write
by dn.children="ou=password_manager,ou=Manager,dc=git,dc=com,dc=cn" read
by dn.children="ou=readonly,ou=Manager,dc=git,dc=com,dc=cn" read
by * none
EOF

ldapmodify -Y EXTERNAL -H ldapi:/// -f new-acl.ldif
1
2
3
4
// 对密码属性访问控制
olcAccess: {1}to attrs=userPassword,shadowLastChange
// 对全局属性访问控制(密码除外)
olcAccess: {2}to *

验证

分别在几个管理ou下创建对应账户,然后访问ldap,验证权限,ldif配置文件示例

1
2
3
4
5
6
7
8
9
10
cat > add_readOnly.ldif << EOF
dn: cn=readuser,ou=readonly,ou=Manager,dc=git,dc=com,dc=cn
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP read only user
cn: readuser
userPassword: readuser123456
EOF

ldapadd -x -D cn=admin,dc=git,dc=com,dc=cn -w 'G1T@Ldap' -f add_readOnly.ldif

Jira集成OpenLDAP

OpenLDAP配置

在Users的ou下创建用户

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
cat > jira-users.ldif << EOF
dn: cn=admin,ou=Users,dc=git,dc=com,dc=cn
changetype: add
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: shadowAccount
cn: admin
sn: ADMIN
uid: admin
userPassword: 123456
uidNumber: 44000
gidNumber: 0
homeDirectory: /home/users/admin
mail: admin@test.com.cn
title: add user xiaohong

dn: cn=xiaoming,ou=Users,dc=git,dc=com,dc=cn
changetype: add
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: shadowAccount
cn: xiaoming
sn: 小明
uid: xiaoming
userPassword: 123456
uidNumber: 44001
gidNumber: 0
homeDirectory: /home/users/xiaoming
mail: xiaoming@test.com.cn
title: add user xiaoming

dn: cn=xiaohong,ou=Users,dc=git,dc=com,dc=cn
changetype: add
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: shadowAccount
cn: xiaohong
sn: 小红
uid: xiaohong
userPassword: 123456
uidNumber: 44002
gidNumber: 0
homeDirectory: /home/users/xiaohong
mail: xiaohong@test.com.cn
title: add user xiaohong
EOF
ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w G1T@Ldap -f jira-users.ldif

在Groups下创建Jira的ou, 在Jira的ou下创建分组

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
cat > jira-groups.ldif << EOF
## 在Group下创建Jira的ou
dn: ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: add
objectClass: organizationalUnit
objectClass: top
ou: Jira

## 创建Jira的用户组并添加用户到组中
dn: cn=jira-administrators,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: add
objectClass: groupOfUniqueNames
objectClass: top
cn: jira-administrators
uniqueMember: cn=admin,ou=Users,dc=git,dc=com,dc=cn

dn: cn=jira-software-users,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: add
objectClass: groupOfUniqueNames
objectClass: top
cn: jira-software-users
uniqueMember: cn=xiaoming,ou=Users,dc=git,dc=com,dc=cn

dn: cn=jira-software-users,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: modify
add: uniqueMember
uniqueMember: cn=xiaohong,ou=Users,dc=git,dc=com,dc=cn

dn: cn=deployment,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: add
objectClass: groupOfUniqueNames
objectClass: top
cn: deployment
uniqueMember: cn=xiaoming,ou=Users,dc=git,dc=com,dc=cn

dn: cn=deployment,ou=Jira,ou=Groups,dc=git,dc=com,dc=cn
changetype: modify
add: uniqueMember
uniqueMember: cn=xiaohong,ou=Users,dc=git,dc=com,dc=cn
EOF
ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=git,dc=com,dc=cn" -w G1T@Ldap -f jira-groups.ldif

Jira用户目录配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
服务器设置
名称: LDAP服务器
目录类型: OpenLDAP
主机名: 192.168.2.101
端口: 389
用户名: cn=admin,dc=git,dc=com,dc=cn
密码: 123456

LDAP设置
基本DN: dc=git,dc=com,dc=cn
附加用户DN: ou=Users
附加组dn: ou=Jira,ou=Groups

LDAP权限:
勾选只读

用户模式设置:
几乎不用设置,核对属性值是否与OpenLDAP中用户属性值是否一致即可

组模式设置
注意组类型,Jira需要在OpenLDAP中创建unique name类型的组

组成员模式:
默认

GitLab集成OpenLDAP

gitlab配置文件gitlab.rb示例

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
gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
gitlab_rails['ldap_group_sync_worker_cron'] = "0 */2 * * * *"
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'LDAP',
'host' => '3.1.101.38',
'port' => 389,
'uid' => 'uid',
'encryption' => 'plain',
'verify_certificates' => false,
'bind_dn' => 'cn=admin,dc=git,dc=com,dc=cn',
'password' => 'G1T@Ldap',
'timeout' => 30,
'active_directory' => false,
'allow_username_or_email_login' => false,
'block_auto_created_users' => false,
'base' => 'ou=People,dc=git,dc=com,dc=cn',
'user_filter' => 'memberOf=cn=credit-rebuild,ou=GitLab,ou=Group,dc=git,dc=com,dc=cn',
'attributes' => {
'username' => ['cn'],
'email' => ['mail',],
'name' => 'sn',
'first_name' => 'givenName',
'last_name' => 'sn'
},
'lowercase_usernames' => false,

# EE Only
'group_base' => '',
'admin_group' => ',
'sync_ssh_keys' => false
}
}
1
2
gitlab-ctl check-config
gitlab-ctl reconfigure