部署openLDAP

LDAP 代表 轻量级目录访问协议。顾名思义,它是一种用于访问目录服务的基于X.500协议的轻量级目录服务。

LDAP信息模型基于条目。条目是具有全局唯一性的属性集合专有名称(DN)。DN用于明确指代条目。每个条目的属性都有一个类型和一个或多个值。这些类型通常是助记符字符串,例如“ cn ”表示公用名,或“ mail ”表示电子邮件地址。值的语法取决于属性类型。

在LDAP中,目录条目以分层树状结构排列。此外,LDAP允许您通过使用名为objectClass的特殊属性来控制条目中所需和允许的属性。objectClass属性的值确定条目必须遵守的模式规则。

更多简介请访问:http://www.openldap.org/doc/admin24/intro.html

部署 openLDAP

安装 openLDAP

1
2
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# yum -y install openldap-servers openldap-clients openldap-devel

OpenLDAP 2.3及更高版本已转换为使用动态运行时配置引擎slapd-config:
http://www.openldap.org/doc/admin24/slapdconf2.html

生成LDAP密码

1
2
# slappasswd -s zhijian
{SSHA}pQdy+1y8IfIw9ZgIExIdOsjC/tqsmb86

复制相关文件

1
2
# cp /usr/share/openldap-servers/slapd.ldif /etc/openldap/
# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG

配置 slapd.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
# vim /etc/openldap/slapd.ldif 
#
# Server status monitoring
#

dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c
n=auth" read by dn.base="cn=admin,dc=openldap,dc=flywzj,dc=com" read by * none

#
# Backend database definitions
#

dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcSuffix: dc=openldap,dc=flywzj,dc=com
olcRootDN: cn=admin,dc=openldap,dc=flywzj,dc=com
olcRootPW: {SSHA}OLvPaV6PzzgRSCDivSzY8xVwk4fEWfZ9
olcDbDirectory: /var/lib/ldap
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub

测试配置

1
2
# slaptest -u  
config file testing succeeded

删除原始配置文件并重置配置

1
2
3
# rm -rf /etc/openldap/slapd.d/*
# slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif
# chown -R ldap:ldap /etc/openldap/slapd.d/

启用 openLDAP

1
2
# systemctl start slapd
# systemctl status slapd

检查服务器是否正在运行并正确配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: namingContexts
#

#
dn:
namingContexts: dc=openldap,dc=flywzj,dc=com

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

部署 phpldapadmin

安装 phpldapadmin

1
# yum -y install httpd php-ldap phpldapadmin

配置访问控制

1
2
3
4
5
6
# vim /etc/httpd/conf.d/phpldapadmin.conf
<IfModule mod_authz_core.c>
# Apache 2.4
Require local
Require ip 192.168.100
</IfModule>

注:如上为允许本地和192.168.100.0网段访问phpldapadmin,其他Apache Require访问控制指令请自行搜索。

更改登录方式

1
2
3
4
# vim /etc/phpldapadmin/config.php
// line 397
$servers->setValue('login','attr','dn');
// $servers->setValue('login','attr','uid');

导入默认 schema 模块

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
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=cosine,cn=schema,cn=config"

# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=nis,cn=schema,cn=config"

# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=inetorgperson,cn=schema,cn=config"

# ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=schema,cn=config "(objectClass=olcSchemaConfig)" dn
dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

注1:这里的模版对应在 phpldapadmin 里 “创建一个子条目” 下的 “Select a template for the creation process” 模版。

注2: 如出现 “Automatically removed objectClass from template
Courier Mail: Account: courierMailAccount removed from template as it is not defined in the schema” 问题,那既是没有导入相关 objectClass 模版的原因。我曾试着将余下的 schema 也导入进去,但是没有成功,余下的几个模版依然是disable的。

配置 DN

1
2
3
4
5
6
7
8
9
10
# vim /etc/openldap/base.ldif 
dn: dc=openldap,dc=flywzj,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: flywzj

# ldapadd -x -D "cn=admin,dc=openldap,dc=flywzj,dc=com" -W -f /etc/openldap/base.ldif
Enter LDAP Password:
adding new entry "dc=openldap,dc=flywzj,dc=com"

注:如未配置默认DC即登录 phpldapadmin 会提示 “This base cannot be created with PLA.”问题。

启用 phpldapadmin

1
# systemctl start httpd

浏览器使用 http://yourip/ldapadmin 进入 phpldapadmin,点击登录,在“登录DN”中输入”cn=admin,dc=openldap,dc=flywzj,dc=com”并输入相应密码即可登录创建条目。

使用命令创建 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
# vim /etc/openldap/group.ldif 
dn: ou=Groups,dc=openldap,dc=flywzj,dc=com
ou: Groups
objectClass: organizationalUnit
objectClass: top

dn: ou=People,dc=openldap,dc=flywzj,dc=com
ou: People
objectClass: organizationalUnit
objectClass: top

dn: cn=k8s,ou=Groups,dc=openldap,dc=flywzj,dc=com
cn: k8s
gidNumber: 500
objectClass: posixGroup
objectClass: top

dn: cn=test,ou=Groups,dc=openldap,dc=flywzj,dc=com
cn: test
gidNumber: 501
objectClass: posixGroup
objectClass: top

# ldapadd -x -D "cn=admin,dc=openldap,dc=flywzj,dc=com" -W -f /etc/openldap/group.ldif
Enter LDAP Password:
adding new entry "ou=Groups,dc=openldap,dc=flywzj,dc=com"

adding new entry "ou=People,dc=openldap,dc=flywzj,dc=com"

adding new entry "cn=k8s,ou=Groups,dc=openldap,dc=flywzj,dc=com"

adding new entry "cn=test,ou=Groups,dc=openldap,dc=flywzj,dc=com"

注:可使用 phpldapadmin 来创建。

创建用户

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
# vim /etc/openldap/user.ldif 
dn: uid=wang,ou=People,dc=openldap,dc=flywzj,dc=com
cn: wang
gidnumber: 500
givenname: wang
homedirectory: /home/users/wang
loginshell: /bin/sh
mail: wangzhijiansd@qq.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
objectClass: shadowAccount
objectClass: organizationalPerson
sn: wang
uid: wang
uidnumber: 1000
userpassword: wangzhijian

dn: uid=zhi,ou=People,dc=openldap,dc=flywzj,dc=com
cn: zhi
gidnumber: 501
givenname: zhi
homedirectory: /home/users/zhi
loginshell: /bin/sh
mail: wangzhijiansd@qq.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
objectClass: shadowAccount
objectClass: organizationalPerson
sn: zhi
uid: zhi
uidnumber: 1001
userpassword: zhijian

# ldapadd -x -D "cn=admin,dc=openldap,dc=flywzj,dc=com" -W -f /etc/openldap/user.ldif
Enter LDAP Password:
adding new entry "uid=wang,ou=People,dc=openldap,dc=flywzj,dc=com"

adding new entry "uid=zhi,ou=People,dc=openldap,dc=flywzj,dc=com"

查看具体用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ldapsearch -x -W -D "uid=wang,ou=People,dc=openldap,dc=flywzj,dc=com" -b "uid=wang,dc=openldap,ou=People,dc=flywzj,dc=com"
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <uid=wang,dc=openldap,ou=People,dc=flywzj,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

查看该CN下的所有条目

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
# ldapsearch -x -H ldap:/// -b dc=openldap,dc=flywzj,dc=com -D "cn=admin,dc=openldap,dc=flywzj,dc=com" -W
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=openldap,dc=flywzj,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# openldap.flywzj.com
dn: dc=openldap,dc=flywzj,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: flywzj
dc: openldap

# Groups, openldap.flywzj.com
dn: ou=Groups,dc=openldap,dc=flywzj,dc=com
ou: Groups
objectClass: organizationalUnit
objectClass: top

# People, openldap.flywzj.com
dn: ou=People,dc=openldap,dc=flywzj,dc=com
ou: People
objectClass: organizationalUnit
objectClass: top

# k8s, Groups, openldap.flywzj.com
dn: cn=k8s,ou=Groups,dc=openldap,dc=flywzj,dc=com
cn: k8s
gidNumber: 500
objectClass: posixGroup
objectClass: top

# test, Groups, openldap.flywzj.com
dn: cn=test,ou=Groups,dc=openldap,dc=flywzj,dc=com
cn: test
gidNumber: 501
objectClass: posixGroup
objectClass: top

# wang, People, openldap.flywzj.com
dn: uid=wang,ou=People,dc=openldap,dc=flywzj,dc=com
cn: wang
gidNumber: 500
givenName: wang
homeDirectory: /home/users/wang
loginShell: /bin/sh
mail: wangzhijiansd@qq.com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
objectClass: organizationalPerson
sn: wang
uid: wang
uidNumber: 1000
userPassword:: d2FuZ3poaWppYW4=

# zhi, People, openldap.flywzj.com
dn: uid=zhi,ou=People,dc=openldap,dc=flywzj,dc=com
cn: zhi
gidNumber: 501
givenName: zhi
homeDirectory: /home/users/zhi
loginShell: /bin/sh
mail: wangzhijiansd@qq.com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
objectClass: organizationalPerson
sn: zhi
uid: zhi
uidNumber: 1001
userPassword:: emhpamlhbg==

# search result
search: 2
result: 0 Success

# numResponses: 8
# numEntries: 7

注: 亦可使用 phpldapadmin 创建。

配置 zabbix 使用 LDAP

这里以配置 zabbix 使用 LDAP 来进行测试。

配置 zabbix 的 “管理” ===> “认证” 下的 “LDAP settings”项:

  • Enable LDAP authentication: √
  • LDAP主机: yourip
  • 端口: 389(默认端口,如使用使用 ldaps 协议则为636)
  • 基于 DN: dc=openldap,dc=flywzj,dc=com
  • 搜索属性: uid
  • 绑定 DN: cn=admin,dc=openldap,dc=flywzj,dc=com
  • 绑定密码: 输入该DN的密码
  • 测试认证[必需为一个正确的LDAP用户]-登录: 如如上配置的wang
  • 测试认证[必需为一个正确的LDAP用户]-用户密码:如如上配置的wangzhijian

点击 “测试”,成功则会提示“LDAP登录成功”。

注: 如要使用 LDAP 登录 zabbix,还需在 zabbix 的 “用户群组” 下创建同名的用户并赋予其权限,之后配置”更新”默认认证方式为“LDAP”即可使用LDAP下的该用户进行登录。

使用 kubernetes 部署 openLDAP

详询: docker-openldap,在部署时请查看对比构建方的环境变量。如需进行定制构建,构建方也给了构建方法。

配置 PVC

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
# vim openldap-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ldap-data
namespace: default
labels:
app: ldap
spec:
storageClassName: default-rbd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "5Gi"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ldap-config
namespace: default
labels:
app: ldap
spec:
storageClassName: default-rbd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1Gi"
# kubectl create -f openldap-pvc.yaml
persistentvolumeclaim/ldap-data created
persistentvolumeclaim/ldap-config created

配置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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# vim openldap.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ldap
labels:
app: ldap
spec:
replicas: 1
template:
metadata:
labels:
app: ldap
spec:
containers:
- name: ldap
image: 192.168.100.100/library/openldap:1.2.2
volumeMounts:
- name: ldap-data
mountPath: /var/lib/ldap
- name: ldap-config
mountPath: /etc/ldap/slapd.d
- name: ldap-certs
mountPath: /container/service/slapd/assets/certs
ports:
- containerPort: 389
name: openldap
env:
- name: LDAP_LOG_LEVEL
value: "256"
- name: LDAP_ORGANISATION
value: "zhi"
- name: LDAP_DOMAIN
value: "flywzj.com"
- name: LDAP_ADMIN_PASSWORD
value: "admin"
- name: LDAP_CONFIG_PASSWORD
value: "config"
- name: LDAP_READONLY_USER
value: "false"
- name: LDAP_READONLY_USER_USERNAME
value: "readonly"
- name: LDAP_READONLY_USER_PASSWORD
value: "readonly"
- name: LDAP_RFC2307BIS_SCHEMA
value: "false"
- name: LDAP_BACKEND
value: "mdb"
- name: LDAP_TLS
value: "true"
- name: LDAP_TLS_CRT_FILENAME
value: "ldap.crt"
- name: LDAP_TLS_KEY_FILENAME
value: "ldap.key"
- name: LDAP_TLS_CA_CRT_FILENAME
value: "ca.crt"
- name: LDAP_TLS_ENFORCE
value: "false"
- name: LDAP_TLS_CIPHER_SUITE
value: "SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:-RSA:-DHE-DSS:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC"
- name: LDAP_TLS_VERIFY_CLIENT
value: "demand"
- name: LDAP_REPLICATION
value: "false"
- name: LDAP_REPLICATION_CONFIG_SYNCPROV
value: "binddn=\"cn=admin,cn=config\" bindmethod=simple credentials=$LDAP_CONFIG_PASSWORD searchbase=\"cn=config\" type=refreshAndPersist retry=\"60 +\" timeout=1 starttls=critical"
- name: LDAP_REPLICATION_DB_SYNCPROV
value: "binddn=\"cn=admin,$LDAP_BASE_DN\" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase=\"$LDAP_BASE_DN\" type=refreshAndPersist interval=00:00:00:10 retry=\"60 +\" timeout=1 starttls=critical"
- name: LDAP_REPLICATION_HOSTS
value: "#PYTHON2BASH:['ldap://ldap-one-service', 'ldap://ldap-two-service']"
- name: KEEP_EXISTING_CONFIG
value: "false"
- name: LDAP_REMOVE_CONFIG_AFTER_SETUP
value: "true"
- name: LDAP_SSL_HELPER_PREFIX
value: "ldap"
volumes:
- name: ldap-data
persistentVolumeClaim:
claimName: ldap-data
#hostPath:
# path: "/data/ldap/db"
- name: ldap-config
persistentVolumeClaim:
claimName: ldap-config
#hostPath:
# path: "/data/ldap/config"
- name: ldap-certs
hostPath:
path: "/data/ldap/certs"
---
apiVersion: v1
kind: Service
metadata:
labels:
app: ldap
name: ldap-service
spec:
type: NodePort
ports:
- port: 389
nodePort: 38989
selector:
app: ldap
# kubectl create -f openldap.yaml
deployment.extensions/ldap created
service/ldap-service created
# kubectl get pods -l app=ldap
NAME READY STATUS RESTARTS AGE
ldap-65f5786ff8-b9dnx 1/1 Running 1 11d

使用 kubernetes 部署 openldapadmin

详询: docker-phpLDAPadmin,部署时请详细查看对比构建方给定的环境变量。如需进行定制构建,构建方也给出了构建方法。

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
# vim phpldapadmin.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
name: phpldapadmin-controller
labels:
app: phpldapadmin
spec:
replicas: 1
selector:
app: phpldapadmin
template:
metadata:
labels:
app: phpldapadmin
spec:
containers:
- name: phpldapadmin
image: 192.168.100.100/library/phpldapadmin:0.7.2
volumeMounts:
- name: phpldapadmin-certs
mountPath: /container/service/phpldapadmin/assets/apache2/certs
- name: ldap-client-certs
mountPath: /container/service/ldap-client/assets/certs
ports:
- containerPort: 443
env:
- name: PHPLDAPADMIN_LDAP_HOSTS
#value: "#PYTHON2BASH:[{'ldap-service': [{'server': [{'tls': 'true'}]}]}]"
value: "ldap-service"
- name: PHPLDAPADMIN_SERVER_ADMIN
value: "wangzhijiansd@qq.com"
- name: PHPLDAPADMIN_SERVER_PATH
value: "/phpldapadmin"
- name: PHPLDAPADMIN_HTTPS
value: "true"
- name: PHPLDAPADMIN_HTTPS_CRT_FILENAME
value: "cert.crt"
- name: PHPLDAPADMIN_HTTPS_KEY_FILENAME
value: "cert.key"
- name: PHPLDAPADMIN_HTTPS_CA_CRT_FILENAME
value: "ca.crt"
- name: PHPLDAPADMIN_LDAP_CLIENT_TLS
value: "true"
- name: PHPLDAPADMIN_LDAP_CLIENT_TLS_REQCERT
value: "demand"
- name: PHPLDAPADMIN_LDAP_CLIENT_TLS_CRT_FILENAME
value: "cert.crt"
- name: PHPLDAPADMIN_LDAP_CLIENT_TLS_KEY_FILENAME
value: "cert.key"
- name: PHPLDAPADMIN_LDAP_CLIENT_TLS_CA_CRT_FILENAME
value: "ca.crt"
volumes:
- name: phpldapadmin-certs
hostPath:
path: "/data/phpldapadmin/ssl/"
- name: ldap-client-certs
hostPath:
path: "/data/phpldapadmin/ldap-client-certs/"
---
apiVersion: v1
kind: Service
metadata:
labels:
app: phpldapadmin
name: phpldapadmin-service
spec:
type: NodePort
ports:
- port: 443
nodePort: 32001
selector:
app: phpldapadmin
# kubectl create -f phpldapadmin.yaml
replicationcontroller/phpldapadmin-controller created
service/phpldapadmin-service created
# kubectl get pods -l app=phpldapadmin
NAME READY STATUS RESTARTS AGE
phpldapadmin-controller-mprjw 1/1 Running 2 14d

输入 https://nodeip:nodeport 点击”login”进行登陆:

  • Login DN: cn=admin,dc=flywzj,dc=com
  • Password: admin

点击 Authenticate 登陆

不在演示如何在 kubernetes 的 openLDAP 上创建用户,既然安装了 phpldapadmin ,用web来创建比较简单(phpldapadmin界面粗糙)。

ZhiJian wechat
欢迎您扫一扫上面的二维码,订阅我的微信公众号!
-------------本文结束,感谢您的阅读-------------