默认情况下,openLDAP安装之后schema中是没有memberof属性的,如果只是通过ldap进行系统登录认证还没有什么影响,但是如果是和第三方应用结合,那么这就成了一件痛苦的事儿。

环境说明

主机名 角色 IP地址
ldapserver.contoso.com openLDAP server 192.168.49.139

一、准备环境

[root@ldapserver ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
[root@ldapserver ~]# getenforce
Disabled
[root@ldapserver ~]# crontab -l
0 * * * * /usr/sbin/ntpdate   210.72.145.44 64.147.116.229 time.nist.gov
[root@ldapserver ~]# grep -i hostname /etc/sysconfig/network
HOSTNAME=ldapserver.contoso.com
[root@ldapserver yum.repos.d]# ll
total 8
drwxr-xr-x 2 root root 4096 Oct 13 18:21 bak
-rw-r--r-- 1 root root 2006 Oct 13 18:21 CentOS-Base.repo

二、安装openLDAP

使用yum安装openLDAP:

yum -y install openldap openldap-clients openldap-servers

生成管理员密码:

[root@ldapserver ~]# slappasswd 
New password: 
Re-enter new password: 
{SSHA}m1AJ7dgK7V7LiqnYxIsXJUDTqmlx02kl  #这个密码后面需要添加到olcDatabase={2}bdb.ldif中

进入slapd.d目录:

[root@ldapserver ~]# cd /etc/openldap/slapd.d/cn\=config
[root@ldapserver cn=config]# ls
cn=schema       olcDatabase={0}config.ldif     olcDatabase={1}monitor.ldif
cn=schema.ldif  olcDatabase={-1}frontend.ldif  olcDatabase={2}bdb.ldif

编辑olcDatabase={2}bdb.ldif文件:

[root@ldapserver cn=config]# cp olcDatabase\=\{2\}bdb.ldif olcDatabase\=\{2\}bdb.ldif.bak
[root@ldapserver cn=config]# vi olcDatabase\=\{2\}bdb.ldif 
[root@ldapserver cn=config]# diff olcDatabase\=\{2\}bdb.ldif.bak olcDatabase\=\{2\}bdb.ldif
7c7
< olcSuffix: dc=my-domain,dc=com
---
> olcSuffix: dc=contoso,dc=com
12c12,13
< olcRootDN: cn=Manager,dc=my-domain,dc=com
---
> olcRootDN: cn=admin,dc=contoso,dc=com
> olcRootPW: {SSHA}m1AJ7dgK7V7LiqnYxIsXJUDTqmlx02kl
# 上面的操作主要是讲dc的信息根据实际情况,修改为我的domain的信息,然后把管理员密码添加进去

编辑olcDatabase={1}monitor.ldif文件:

[root@ldapserver cn=config]# cp olcDatabase\=\{1\}monitor.ldif olcDatabase\=\{1\}monitor.ldif.bak
[root@ldapserver cn=config]# vi olcDatabase\=\{1\}monitor.ldif
[root@ldapserver cn=config]# diff olcDatabase\=\{1\}monitor.ldif.bak olcDatabase\=\{1\}monitor.ldif
7c7
<  nal,cn=auth" read  by dn.base="cn=manager,dc=my-domain,dc=com" read  by * n
---
>  nal,cn=auth" read  by dn.base="cn=admin,dc=contoso,dc=com" read  by * n
# 主要是把文件中有关domain的默认信息修改为个人的domain的信息

编辑olcDatabase={2}bdb.ldif文件,添加如下两行:

olcAccess: {0}to attrs=userPassword by self write by dn.base="cn=admin,dc=contoso,dc=com" write by anonymous auth by * none

olcAccess: {1}to * by dn.base="cn=admin,dc=contoso,dc=com" write by self write by * read

[root@ldapserver cn=config]# diff olcDatabase\=\{2\}bdb.ldif.bak olcDatabase\=\{2\}bdb.ldif
2c2
< # CRC32 c02fb933
---
> # CRC32 2c268e09
7c7
< olcSuffix: dc=my-domain,dc=com
---
> olcSuffix: dc=contoso,dc=com
12c12,13
< olcRootDN: cn=Manager,dc=my-domain,dc=com
---
> olcRootDN: cn=admin,dc=contoso,dc=com
> olcRootPW: {SSHA}m1AJ7dgK7V7LiqnYxIsXJUDTqmlx02kl
46a48,49
> olcAccess: {0}to attrs=userPassword by self write by dn.base="cn=admin,dc=contoso,dc=com" write by anonymous auth by * none
> olcAccess: {1}to * by dn.base="cn=admin,dc=contoso,dc=com" write by self write by * read

修改文件的CRC32值:

因为我修改了olcDatabase={2}bdb.ldif和olcDatabase={1}monitor.ldif这两个文件,所以需要将他们默认的CRC32项目值进行修改,不然启动slapd服务的时候可能会有警告。

1)首先将文件中除了前3行(前三行是注释,包含默认CRC32的值)其他的内容导入到临时文件中:

[root@ldapserver cn=config]# tail -n +3 olcDatabase\=\{1\}monitor.ldif > /tmp/foo.txt
[root@ldapserver cn=config]# tail -n +3 olcDatabase\=\{2\}bdb.ldif > /tmp/foo2.txt

2)然后再对导出的文件进行CRC32校检,这里因为CentOS上没有CRC32校检工具,所以把文件下载下来,然后使用在线校检工具进行校检:

补充一个在线校检的链接:http://www.atool.org/file_hash.php

foo.txt(620/620 b)| 耗时: 0.03s @ 15.93 KiB/s | 1476353878479
CRC-32 525e2b6c
MD5 Hash 2a4e68f0bf46ca0eb3fdfe5e9edb277b
SHA1 Hash 09899189f54c66b92fc53d2d9bbfbe39b39e2065
SHA256 Hash 706fc6bbe1c9c7703a0baab4b2c3cb4993561b409ab0a5c1ce2f3698f3231857
foo2.txt(1.42/1.42 KiB)| 耗时: 0.03s @ 43.17 KiB/s | 1476327845262
CRC-32 2c268e09
MD5 Hash a6a1d8e9b2be9a7261c39e00f7aef297
SHA1 Hash f35c1449eb91462666745e0bdc1d61606fe81160
SHA256 Hash 272fdea0d4273a31f17e77129d8c64698afb095b059c91543d15e4884d15f216

3)然后编辑修改过的文件,将得到的CRC-32值进行修改:

[root@ldapserver cn=config]# head -3 olcDatabase\=\{1\}monitor.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 525e2b6c
dn: olcDatabase={1}monitor
[root@ldapserver cn=config]# head -3 olcDatabase\=\{2\}bdb.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 2c268e09
dn: olcDatabase={2}bdb

启动slapd服务并添加开机启动:

[root@ldapserver cn=config]# service slapd start
Starting slapd:                                            [  OK  ]
[root@ldapserver cn=config]# chkconfig slapd on
[root@ldapserver cn=config]# /etc/init.d/slapd status
slapd (pid  1755) is running...

检查一下openLDAP的数据目录:

[root@ldapserver cn=config]# ll /var/lib/ldap/
total 1096
-rw-r--r-- 1 ldap ldap     2048 Oct 13 19:06 alock
-rw------- 1 ldap ldap     8192 Oct 13 19:36 cn.bdb
-rw------- 1 ldap ldap    24576 Oct 13 19:06 __db.001
-rw------- 1 ldap ldap   188416 Oct 14 02:22 __db.002
-rw------- 1 ldap ldap   270336 Oct 13 19:36 __db.003
-rw------- 1 ldap ldap    98304 Oct 13 19:36 __db.004
-rw------- 1 ldap ldap   753664 Oct 13 19:27 __db.005
-rw------- 1 ldap ldap    32768 Oct 13 19:36 __db.006
-rw------- 1 ldap ldap     8192 Oct 13 19:36 dn2id.bdb
-rw------- 1 ldap ldap    32768 Oct 13 19:36 id2entry.bdb
-rw------- 1 ldap ldap 10485760 Oct 13 19:36 log.0000000001
-rw------- 1 ldap ldap     8192 Oct 13 19:36 objectClass.bdb
-rw------- 1 ldap ldap     8192 Oct 13 19:21 ou.bdb
-rw------- 1 ldap ldap     8192 Oct 13 19:36 uid.bdb

查看/etc/openldap/目录,发现并没有slapd.conf文件:

[root@ldapserver cn=config]# ll /etc/openldap/
total 20
drwxr-xr-x. 2 root root 4096 Oct 13 18:23 certs
-rw-r-----  1 root ldap  121 May 11 07:32 check_password.conf
-rw-r--r--  1 root root  280 May 11 07:32 ldap.conf
drwxr-xr-x  2 root root 4096 Oct 13 18:23 schema
drwx------  3 ldap ldap 4096 Oct 13 18:24 slapd.d

而仅有的一个ldap.conf文件中只有一行内容:

[root@ldapserver cn=config]# egrep -v "#|^$" /etc/openldap/ldap.conf 
TLS_CACERTDIR/etc/openldap/certs

为了测试做一个简单的查询操作:

[root@ldapserver cn=config]# ldapsearch -x -b "dc=contoso,dc=com"
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 32 No such object
# numResponses: 1

说明openLDAP服务是正常的,没有问题。

三、导入数据

1、导入domain入口

[root@ldapserver ~]# vi domain.ldif
[root@ldapserver ~]# cat domain.ldif 
dn: dc=contoso,dc=com
objectClass: dcObject
objectClass: organization
dc: contoso
o : contoso

# domain.ldif只添加domain信息,不要创建用户和组

[root@ldapserver ~]# ldapadd -f domain.ldif -D cn=admin,dc=contoso,dc=com -W
Enter LDAP Password: 
adding new entry "dc=contoso,dc=com"

# 导入成功

[root@ldapserver ~]# ldapsearch -x -LLL -b dc=contoso,dc=com
dn: dc=contoso,dc=com
objectClass: dcObject
objectClass: organization
dc: contoso
o: contoso

# 查询结果

2、导入memberof数据

[root@ldapserver ~]# vim memberof.ldif
[root@ldapserver ~]# cat memberof.ldif 
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectclass: top
olcModuleLoad: memberof.la
olcModulePath: /usr/lib64/openldap
dn: olcOverlay=memberof,olcDatabase={2}bdb,cn=config
objectclass: olcconfig
objectclass: olcMemberOf
objectclass: olcoverlayconfig
objectclass: top
olcoverlay: memberof

# memberof.ldif是为了添加memberof属性

[root@ldapserver ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f memberof.ldif #导入memberof命令
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"
adding new entry "olcOverlay=memberof,olcDatabase={2}bdb,cn=config"

# 导入memberof.ldif成功

3、导入用户和组的OU

[root@ldapserver ~]# vi ou.ldif
[root@ldapserver ~]# cat ou.ldif 
dn: ou=Users,dc=contoso,dc=com
objectClass: organizationalUnit
ou: Users
dn: ou=Groups,dc=contoso,dc=com
objectClass: organizationalUnit
ou: Groups

# ou.ldif只是用户和组所在的根ou的信息

[root@ldapserver ~]# ldapadd -f ou.ldif -D cn=admin,dc=contoso,dc=com -W
Enter LDAP Password: 
adding new entry "ou=Users,dc=contoso,dc=com"
adding new entry "ou=Groups,dc=contoso,dc=com"

# 导入成功

[root@ldapserver ~]# ldapsearch -x -b "dc=contoso,dc=com"
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# contoso.com
dn: dc=contoso,dc=com
objectClass: dcObject
objectClass: organization
dc: contoso
o: contoso
# Users, contoso.com
dn: ou=Users,dc=contoso,dc=com
objectClass: organizationalUnit
ou: Users
# Groups, contoso.com
dn: ou=Groups,dc=contoso,dc=com
objectClass: organizationalUnit
ou: Groups
# search result
search: 2
result: 0 Success
# numResponses: 4
# numEntries: 3

# 查询结果

四、测试memberof属性是否成功导入

1、先导入一个用户

[root@ldapserver ~]# vi test.ldif
[root@ldapserver ~]# cat test.ldif 
dn: uid=test,ou=Users,dc=contoso,dc=com
objectClass: account
uid: test
[root@ldapserver ~]# ldapadd -D "cn=admin,dc=contoso,dc=com" -W -f test.ldif 
Enter LDAP Password: 
adding new entry "uid=test,ou=Users,dc=contoso,dc=com"

2、再导入一个组

[root@ldapserver ~]# vi group.ldif
[root@ldapserver ~]# cat group.ldif 
dn: cn=testgroup,ou=Groups,dc=contoso,dc=com
objectClass: groupOfNames
cn: testgroup
member: uid=test,ou=Users,dc=contoso,dc=com
[root@ldapserver ~]# ldapadd -D "cn=admin,dc=contoso,dc=com" -W -f group.ldif 
Enter LDAP Password: 
adding new entry "cn=testgroup,ou=Groups,dc=contoso,dc=com"

3、使用ldapsearch进行查看,看能否查到memberof属性

[root@ldapserver ~]# ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=test)" -b dc=contoso,dc=com memberof
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
version: 1

dn: uid=test,ou=Users,dc=contoso,dc=com
memberOf: cn=testgroup,ou=Groups,dc=contoso,dc=com

对于openLDAP中没有memberof属性的问题,在chinaunix上有一个帖子:

http://bbs.chinaunix.net/thread-4082706-1-1.html

这个帖子中提到了如下解决方法,我尝试了但是不成功,如果有人使用该方法成功了,欢迎告诉我一下,谢谢。   

我也试着搞定了,备份下
删除我的slapd.conf文件中

database config  
rootpw  secret

然后加上 
modulepath /usr/lib64/openldap  
moduleload memberof
overlay memberof
就可以实现,操作系统centos6



本文中的方法主要参考:https://www.softwareab.net/wordpress/setup-openldap-centos-6-x/(需×××才能打开)