Ldap  服务应用指南 兼容(5.X&6.X)

1.1  Ldap 目录服务介绍

1.1.1 什么是目录服务(active directory)??

目录是一类为了浏览和搜索数据为设计的特殊的数据库,目录服务是按照树状存储信息的

目录进行更新的操作,可以说是要么全部,要么都不得原子性操作

目录不支持大多数事物型数据库所支持的高吞吐量和复杂的更新操作,适应于大量的查询和搜索操作,为了保证数据的可靠性和可用性,他也有主从服务器同步数据信息能力。

ldap 也可以一主多从.

ldap 可以说是活动目录在linux上的一个开源实现.

1.1.2 什么是Ldap??

LDAP是轻量级目录访问协议(lightweight directory access protocol),LDAP运行在TCP/IP或者其他的面向连接传输之上。

LDAP是在X.500标准上产生的一个简化版本

1.1.3 LDAP基本概念中的常用名词缩写及含义

dc    domain component    域名部分   example.com  dc=example,dc=com
uid   user id             用户id 如wyb
ou    organization unit   组织单位 如tech
cn    common name         公共名称 thomas johansson
sn    surname             姓 
dn    distinguished       唯一辨别名      uid=wyb,ou=market,dc=example,dc=com 
rdn   relative dn         相对辨别名
c     country 
o      organization

1.1.4 LDAP(openldap) 目录服务的特点

ldap 是一个跨平台的,标准的协议。

ldap 的结构用树型结构来表示,而不是表格,因此不需要用SQL语句维护

ldap 提供了静态数据的快速查询方式

ldap 是一个安全的协议

ldap 支持异类数据存储

ldap 是C/S架构,server端用于存储树,client端提供操作目录信息树的工具

ldap   是一种目录服务,保存在特殊的数据库中,数据的读取速度远高于写入速度。

  • ldap 对查询做了优化,读取速度优于普通关系数据库。

  • ldap  不支持事务、不能进行回滚,需要进行这些操作的应用只有选择关系数据库。

  • ldap  采用服务器/客户端模式,支持分布式结构。

  • ldap  中的条目以树形结构组织和存储。

  • ldap  基于Internet协议,直接运行在简单和通用的TCP/IP或其他可靠的传输协议层上,使连接的建立和包的处理简单、快捷,对于互联网和企业网应用都很方便。

  • ldap  协议简单,通过使用查找操作实现列表操作和读操作。

  • ldap  通过引用机制实现分布式访问,通过客户端API实现分布式操作(对于应用透明),平衡了负载。

  • ldap  实现具有低费用、易配置和易管理的特点,并提供了满足应用程序对目录服务所需求的特性。

1.1.5 ldap的目录结构

ldap 目录服务是通过目录数据库存储网络信息提供目录服务的,目录数据库是以目录信息树DIT为存储 方式存储结构,目录是按照树型结构组织--目录信息书(DIT)DIT是一个主要

进行读写操作的数据库

DIT是由条目(entry)组成,条目相当于关系型数据库中的表的记录

ldap目录用OU 从逻辑上把数据分开

ou 是一种条目--容器条目   OU下面才是真正的用户条目

1.1.6  什么是dn?

(1) 在ldap 中,一个条目的分辨名叫做DN,DN是该目录在整个树种的一名名称识,DN相当于关系型数据库中的关键字,它是一个识别属性,通常用于检索

(2) DN的两张设置

基于 cn(公共名称)  cn=test,ou=tech,dc=example,dc=org   最常见的cn是从、etc/group转了的条目

基于 uid(user id)  uid=test,ou=tech,dc=example,dc=org  最常见的uid是etc/passwd转来的条目

(3) ldap 目录树的最顶部就是根,也就是Base DN

(4) LDIF格式是LDAP数据,导入,到处的格式。LDIF是LDAP数据信息的一种文本格式

1.1.7  什么样的信息可以存在目录当中???

LDAP的信息模型是基于条目的(entry),一个条目就是一些具有全局唯一的标识名的属性的集合

下面是ldap中条目信息的例子:相当于数据表中的两行记录

条目一:

dn: uid=user01,ou=people,dc=wyb,dc=com
objectClass: posixAccount
.
.
.
uid:
cn:
uidnumber:
gidnumber:
userpassword:
sn:
givenname:

LDAP允许你通过使用一种叫做objectclass 的特殊属性来控制那些属性是条目必须的,那些条目属性是可选的

1.1.8  信息在目录中是如何组织的??

在ldap 中,条目是按照层次结构组织的。

目录树的结构图

如图ldap结构图

wKiom1YeDD6jLzhrAADgQeKR_kw301.jpg

DIT

DC

OU

CN

1.1.9  ldap 目录数据内容讲解

LDIF 是一种ASCii 文件格式,用来交换数据,并使得LDAP服务器之间交换数据成为可能。

LDIF文件的特点:

(1)通过空行分割一个条目或者定义        ***********

(2)以#开始行为注释

(3)所有属性的赋值方法为:属性:属性值

(4)属性可以被重新赋值

(5)每行的结尾不允许有空格    ***********

1.2.0 ldap是怎么工作的??

ldap 目录服务是基于客户端/服务器(c/s)模式的。ldap 客户端连接到服务器并且发出一个请求,然后服务器要么以一个回答予以回应,要么给一个指针,客户可以通过指针获取到所

需数据(通常,该指针指向另一个ldap服务器),无论客户端连到那个ldap服务器,它看到的都是同一个目录视图。这是ldap这类全局目录服务的一个重要特征

1.2.1 ldap的几个重要模式

ldap服务的几个重要功能:

(1)基本的目录查询服务 **********************

(2)目录查询代理服务

(3)异机copy数据(主从同步)  ***************

1.2.1.1 本地基本的查询目录

       request

client---------》 server 

       <--------

        response

1.2.1.2 带有指针的本地目录服务,即目录查询代理服务

1.2.1.3 同步复制目录服务   可以做主从

1.2.1.4 ldap的简单的同步复制方案

inotify+ldap客户端命令方案

如图所示ldap的同步方案

1.2.1.5 分布式目录服务

ldap企业架构逻辑案例:ldap+haproxy/nginx/heartbeat集群高可用,验证的时候不夸机房

如图ldap集群

wKioL1YeDKOBCadUAACnASRE2MA863.jpg

 

 

 

 

1.3.0 openldap的环境搭建准备

ldap master服务安装
1.3.1 安装前环境准备
Centos 6.5 ,ldap2.4版本为主
1.3.1.1  查看系统版本信息
[root@localhost ~]# cat /etc/redhat-release 
CentOS release 6.5 (Final)
[root@localhost ~]# uname -r
2.6.32-431.el6.x86_64

1.3.1.2 补全所缺安装包:

yum groupinstall "Base" -y 
Base
Compatibility libraries
Debugging Tools
Development Tools
Performance Tools
Hardware monitoring utilities
Dial-up Networking Support

1.3.1.3 更新Centos6.4 yum源配置方法

wget http://mirrors.163.com
1.3.1.4 可以保留缓存rpm 包
[root@localhost ~]# grep keepcache /etc/yum.conf 
keepcache=0
[root@localhost ~]# sed -i 's#keepcache=0#keepcache=1#g' /etc/yum.conf 
[root@localhost ~]# grep keepcache /etc/yum.conf 
keepcache=1

1.3.1.5 关闭selinux ,iptables ,防止影响安装

1.3.1.6 记得时间同步

/usr/sbin/ntpdate  time.nist.gov >/dev/null 2>&1

1.3.1.7 配置域名

[root@localhost ~]# echo "192.168.2.221 aapingou.com" >> /etc/hosts
[root@localhost ~]# ping aapingou.com
PING aapingou.com (192.168.2.221) 56(84) bytes of data.
64 bytes from aapingou.com (192.168.2.221): icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from aapingou.com (192.168.2.221): icmp_seq=2 ttl=64 time=0.022 ms
^C

1.3.1.8 开始安装ldap

yum install openldap openldap-* 
yum install nscd nss-pam-ldapd nss-* pcre pcre-* -y
 

1.4.0  开始配置 ldap master 

1.4.0.1
对于6.4 来说,openldap的配置和5.8的配置文件有变化,目前6.4的配置文件在/etc/openldap/slapd.d/cn-config/ 下
此时还是安装openldap2.3版本安装
cp /usr/share/openldap-servers/slapd.conf.obsolete slapd.conf 
[root@localhost openldap]# ls
certs  check_password.conf  ldap.conf  schema  slapd.conf  slapd.d
[root@localhost openldap]# 
[root@localhost openldap]# slappasswd -s 123456   以123456为管理员密码
{SSHA}cJOGvZaS/W2Sli6wqtrQCHxk/6BcNE4t
[root@localhost openldap]# 
 
也可以用sed 直接生成密码,并添加到配置文件中
[root@localhost openldap]# slappasswd -s 123456 |sed -e 's#{SSHA}#rootpw\t{SSHA}#g' 
rootpw{SSHA}QHJb0AzNWAP5retRMiC2D+qhvpSe8D0C
[root@localhost openldap]# slappasswd -s 123456 |sed -e 's#{SSHA}#rootpw\t{SSHA}#g' >> slapd.conf 
[root@localhost openldap]# tail -2 slapd.conf 
#     authcId=host/ldap-master.example.com@EXAMPLE.COM
rootpw{SSHA}fgMtXr09LbqS+Bt2/dKJ+pGKA4zDGJgG
 

1.4..0.2  openldap2.3 和 openldap2.4 的区别

http://www.openldap.org/doc/admin24/slapdconf2.html
1.4.0.3
备份sladp.conf
[root@localhost openldap]# cp slapd.conf  slapd.conf.bak
vim slapd.conf 
注释一下4行
#database       bdb
#suffix         "dc=my-domain,dc=com"
#checkpoint     1024 15
#rootdn         "cn=Manager,dc=my-domain,dc=com"
然后增加一下三行
database        bdb
suffix          "dc=aapingou,dc=com"
rootdn          "cn=admin,dc=aapingou,dc=com"
提示:空行和以#开头的注释行可以忽略
此时LDAP的管理账号为 :admin:123456

1.4.0.4 以上修改参数的含义解释 

database    bdb   #指定使用数据库BDB,berkeley DB
suffix      "dc=aapingou,dc=com"   #指定要搜索的后缀
rootdn      "cn=admin,dc=aapingou,dc=com"    #指定管理员dn路径,使用这个dn可以登录ldap server
rootpw       {SSHA}fgMtXr09LbqS+Bt2/dKJ+pGKA4zDGJgG   #指定ldap 管理员密码,改密码有值钱slappsswd生产
     

1.4.0.5 更多ldap参数配置优化

a,日志以及缓存参数
[root@localhost openldap]# cat >> slapd.conf << EOF
> #add new feature 15-10-14
> loglevel   296
> cachesize  1000
> checkpoint 2048 10
> # end 
> EOF
[root@localhost openldap]# tail -6 slapd.conf
rootpw{SSHA}fgMtXr09LbqS+Bt2/dKJ+pGKA4zDGJgG
#add new feature 15-10-14
loglevel   296          日志级别
cachesize  1000         ldap缓存的条目数
checkpoint 2048 10      上面的设置时达到2048或者10分钟执行一次checkpoint,把内存中的数据写回数据文件中  
# end

1.4.0.6 权限控制管理

http://www.openldap.org/doc/admin24/access-control.html
先简单配置权限管理
删除以下内容:
 database config
 99 access to *
100         by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
101         by * none
102 
103 # enable server status monitoring (cn=monitor)
104 database monitor
105 access to *
106         by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
107         by dn.exact="cn=Manager,dc=my-domain,dc=com" read
108         by * none
新增:
access to *
        by self write
        by anonymous auth
        by * read
1.4.1 配置rsyslog,记录ldap日志
[root@localhost openldap]# cp /etc/rsyslog.conf  /etc/rsyslog.conf.bak 
 echo "local4.*            /var/log/ldap.log " >>/etc/rsyslog.conf 
[root@localhost openldap]# tail -1 /etc/rsyslog.conf
local4.*                             /var/log/ldap.log
[root@localhost openldap]# 
/etc/init.d/rsyslog restart
 

1.4.2  配置ldap数据库路径

[root@localhost openldap]# grep  directory  slapd.conf
# Do not enable referrals until AFTER you have a working directory
# The database directory MUST exist prior to running slapd AND 
directory/var/lib/ldap   此时的路径为数据库路径
[root@localhost openldap]# 
###6.4操作步骤
 cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@localhost openldap]# ls /var/lib/ldap/
DB_CONFIG
chmod  700 /var/lib/ldap/
chown ldap:ldap /var/lib/ldap/DB_CONFIG 
[root@localhost openldap]# slaptest -u
config file testing succeeded
 

1.4.3  启动LDAP

[root@localhost openldap]# /etc/init.d/slapd start
Starting slapd:                                            [  OK  ]
[root@localhost openldap]# ps -ef | grep slapd
ldap      2073     1  0 11:10 ?        00:00:00 /usr/sbin/slapd -h  ldap:/// ldapi:/// -u ldap
root      2079  1973  0 11:10 pts/4    00:00:00 grep slapd
[root@localhost openldap]# 
加入开机自启动
[root@localhost openldap]# chkconfig slapd on 
[root@localhost openldap]# chkconfig  --list | grep slapd
slapd          0:off1:off2:on3:on4:on5:on6:off
 

###此时服务器端的安装和配置完毕

 

1.4.5  查看数据库内容

此时还没有数据,属于正常情况  ,后面会以web端方式进行数据添加

[root@localhost openldap]# ldapsearch -LLL -W -x -H ldap://aapingou.com -D "cn=admin,dc=aapingou,dc=com" -b "dc=aapingou,dc=com (uid=*)"
Enter LDAP Password: 
ldap_bind: Invalid credentials (49)  ---版本不一样导致,5.8 与6.4的区别
how to solve??
[root@localhost openldap]# rm -rf slapd.d/*   删除默认2.4的配置文件
 

***************以2.3的配置为主,再去生产2.4的配置   *****************

[root@localhost openldap]# slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
561dcadf bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
config file testing succeeded
[root@localhost openldap]# /etc/init.d/slapd restart
Stopping slapd:                                            [  OK  ]
Checking configuration files for slapd:                    [FAILED]
561dcb11 ldif_read_file: Permission denied for "/etc/openldap/slapd.d/cn=config.ldif"
slaptest: bad configuration file!
root@localhost openldap]# chown -R ldap:ldap /etc/openldap/slapd.d/
[root@localhost openldap]# /etc/init.d/slapd restart
Stopping slapd:                                            [FAILED]
Starting slapd:                                            [  OK  ]
[root@localhost openldap]# ps -ef | grep slapd
ldap      2161     1  0 11:25 ?        00:00:00 /usr/sbin/slapd -h  ldap:/// ldapi:/// -u ldap
root      2167  1973  0 11:25 pts/4    00:00:00 grep slapd
[root@localhost openldap]# ldapsearch -LLL -W -x -H ldap://aapingou.com -D "cn=admin,dc=aapingou,dc=com" -b "dc=aapingou,dc=com  " "uid=*"
Enter LDAP Password: 
No such object (32)        -----表示配置成功,只是没有数据,数据正常
 

1.4.6 为ldap 数据库添加数据

 

在下面部分中会以web端进行添加数据操作

 

1.4.7 为ldap客户端配置web管理接口

 yum install httpd php php-ldap php-gd -y 
 cd /var/www/html/
  381  ls
  382  rz xvf ldap-account-manager-3.7.tar.gz 
  383  ls
  384  tar xvf ldap-account-manager-3.7.tar.gz 
  385  ls
  386  mv ldap-account-manager-3.7 ldap
  387  cd ldap
  390  cd config
  391  ls
  392  cp config.cfg_sample config.cfg 
  393  cp lam.conf_sample lam.conf 
修改lam.conf 配置文件
[root@localhost config]# pwd
/var/www/html/ldap/config
[root@localhost config]# sed -i 's#cn=Manager#cn=admin#g' lam.conf
[root@localhost config]# sed -i 's#dc=my-domain#dc=aapingou#g' lam.conf
授权
[root@localhost config]# chown -R apache:apache /var/www/html/ldap
1.4.7.1  测试访问ldap web 客户端
[root@localhost ldap]# /etc/init.d/httpd  restart
Stopping httpd:                                            [FAILED]
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
                                                           [  OK  ]
[root@localhost ldap]# netstat -tnlp | grep 80
tcp        0      0 :::80                       :::*                        LISTEN      2404/httpd          
[root@localhost ldap]#
 

1.4.7.2 登陆web端 进行添加用户操作

步骤如下图所示

 

wKioL1YeC2SjZ5DTAAGhIAZRoCY714.jpg

 

 

 

 

 

 

 

 

 

 

  

 

wKiom1YeC4KDxMDlAAFxs7c63LI379.jpg

 

wKioL1YeC7Czti9yAACzbZBgPYE550.jpg

 

 

wKiom1YeC6bzTB-XAAEk7dM8x4U692.jpg

 

 

新增一个组,一个用户

 

 

现在在此查询,新增数据是否成功

[root@localhost ldap]# ldapsearch -LLL -W -x -H ldap://aapingou.com -D "cn=admin,dc=aapingou,dc=com" -b "dc=aapingou,dc=com " "uid=wyb"
Enter LDAP Password: 
dn: uid=wyb,ou=People,dc=aapingou,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/wyb
loginShell: /bin/bash
cn:: IHd5Yg==
uidNumber: 10001
gidNumber: 10001
sn: wyb
givenName: wyb
uid: wyb
userPassword:: e1NTSEF9K1FwdC96dXorSDVqRVNscGhSZ0g1TXVjOWFodG4rUG4=
 

 

通过web结构管理ldap的配置完成!也已经完成了初始化用户组和用户

 

 

1.4.8 导出,备份ldap数据库文件

方法一:
[root@localhost ldap]# ldapsearch -LLL -w 123456 -x -H ldap://aapingou.com -D "cn=admin,dc=aapingou,dc=com" -b "dc=aapingou,dc=com" >/root/bak-ldap.ldif


方法二:
导出数据更常用的是slapcat命令,该命令的格式如下:

最常用的选项就是-l,表示导出为LDIF文件格式。

slapcat -l sladp-back
 

提示:从导出结果可看出,除了使用ldapadd命令添加到目录数据库中的条目数据外,还导出了很多其他信息,包括条目录UUID、时间戳等信息 ,次命令到处的内容比ldapsearch 导出的更为详细

 

 

1.4.9 从LDIF文件添加到目录数据库

 

 

  使用OpenLDAP客户端工具ldapadd命令,可将LDIF文件中的条目添加到目录数据库中,该命令的格式如下:
   ldappadd  选项  LDIF文件 
  在ldappadd命令中常用的选项如下:

 

  • -x:进行简单认证。

  • -D:用来绑定服务器的dn。

  • -h:目录服务的地址。

  • -w:绑定dn的密码。

  • -f:使用LDIF文件进行条目添加的文件。

 

将前面编写的LDIF文件的条目数据添加到目录数据库中。
具体操作步骤如下:

(1)检查dlw.com.ldif文件中的内容,需要注意的是,每个冒号后面都需要空一格,而每行结束处不能留有空格字符。 
(2)使用以下命令将dlw.com.ldif文件中的条目添加到目录中:

写道

前提是现有entry中不能有将要导入的信息,如果有请先删除,再次导入新的

# ldapadd -x -D "cn=admin,dc=aapingou,dc=com" -w 123456 -f bak-ldap.ldif
 

(3)使用ldapdelete 删除整个entry 或者一个cn

#delete one user
 [root]#  ldapdelete -D "cn=admin,dc=ldap.xxx,dc=net" -W -x -H ldap://ldap.xxx "uid=18x,ou=rfkj,dc=ldap.xxx,dc=net"
#delete all (ou)
 [root]#  ldapdelete -D "cn=admin,dc=ldap.xxx,dc=net" -W -r -x -H ldap://ldap.xxx.net "ou=rou,dc=ldap.xxx,dc=net"
-r 表示递归删除
 

 

提示:如果以上命令执行不成功,需要逐个字符检查bak-ldap.ldif文件中的内容,特别注意空格的问题。

 

关于本文中的三处密码做个解答

1,web客户端登陆ldap  server操作时候,LAM configuration---->Edit server profiles----preferences(lam) 此处的密码由

/var/www/html/ldap/config/lam.conf  这个文件管理

 

# password to change these preferences via webfrontend (default: lam)

#Passwd: {SSHA}B6tdhIqMn9WoOBojwzfBEf4MAY/J39Uh

Passwd: {SSHA}D6AaX93kPmck9wAxNlq3GF93S7A= R7gkjQ==   这就是preference的密码,默认lam

 

2,web客户端登陆ldap server操作时候,LAM configuration---->Edit general settings------->general preferences(lam) 此处的密码由

/var/www/html/ldap/config/config.cfg  这个文件管理

# password to add/delete/rename configuration profiles (default: lam)

password: {SSHA}D6AaX93kPmck9wAxNlq3GF93S7A= R7gkjQ==   默认密码为lam


3

 

 

 

########################################################################################

 

  OpenLDAP疑惑解答

下面根据我自己的经验,给出几个安装和配置注意事项,供参考。

 

疑惑1:细心的人会发现有的教程说要配置主机DNS,添加与LDAP相关的域名,而大部分教程都没有提及这个,那么到底要不要配置呢?

解答:当然需要配置。安装好OpenLDAP后首先需要配置slapd.conf这个文件,其中里面有

suffix        "dc=example, dc=com"

这样一句需要自己配置,这两个dc代表什么意思呢?其实dc就是“domainComponent”,也就是域名的组成部分,准确的说是主机域名的 后缀组成部分,如果这里的配置与你的主机域名不对应的话,服务一般是启动不了的。那么怎么配置域名呢?Linux和Windows下的配置文件如下:

Linux下:/etc/hosts

Windows下:C:\Windows\System32\drivers\etc\hosts

需要在hosts文件里添加一条域名(如果没配置的话),格式如下:

127.0.1.1       hostname.example.com    hostname

比如我的主机名是min,并添加的域名配置是:

127.0.1.1       min.alexia.cn    min

那么相应的我就需要在slapd.conf里这样配置suffix:

suffix        "dc=alexia, dc=cn"

当然这里域名后缀不一定只有两级,也可以是hostname.example.com.cn,然后suffix就应该是“dc=example, dc=com, dc=cn”,这随便你怎么设置了,只要对应就行。

 

疑惑2:很多版本的slapd.conf里默认都配置了下面两个变量:

modulepath      /usr/lib/ldap
moduleload      back_@BACKEND@

这是什么意思?需要改动吗?

解答:这是数据库database的backend,一般slapd.conf里配置的database都是 bdb,也就是Berkeley DB,有的也许是hdb,其实也是Berkeley DB,只是两个不同的存储引擎(就像Mysql有MyISAM和InnoDB两个不同的存储引擎一样)。而modulepath和moduleload指 定了动态模块路径及动态装载的后端模块,因为OpenLDAP默认是用Berkeley DB存储数据的,如果你有动态的数据需要装载,那么就需要配置这两个参数,对于一般用户将这两个注释掉即可。

 

疑惑3:OpenLDAP默认采用Berkeley DB存储数据,那么可以换用其它的关系数据库吗?具体如何配置呢?

解答:当然可以。首先需要明确ldap数据模型来自RDBMS(关系数据库模型),而并没有指定一定是哪个 DB,只要是关系数据库都可以作为LDAP的后台,那么你为什么会想用其它的数据库代替自带的Berkeley DB呢?我想可能是性能相关了,对于少量数据你用哪个都可以,但若涉及到稍大点的数据,比如成千上万的用户查询,那么Berkeley DB的性能就不可观了,而且Berkeley DB管理起来也不太方便,毕竟对这个数据库熟悉的人不多,如果能换作我们经常使用的数据库,不仅性能得到提升,管理起来也十分容易,岂不是一举多得。

具体怎么配置了,请参考这篇文章:用postgresql作后台的openldap,以PostgreSQL作为例子进行讲解。

 

疑惑4:新旧版本的OpenLDAP到底有什么差异呢?

解答:简单一句话就是:旧版本的OpenLDAP配置文件一般是slapd.conf(路径可能是/etc/openldap,也可能是/usr/local/openldap,甚至可能是/usr/share/slapd/,不同版本不同安装不同系统都可能不同,可使用locate slapd.conf进行查找正确的路径),而新版本(我测试的新版本是2.4.31)的OpenLDAP服务运行时并不会读取该配置文件,而是从slapd.d目录(一般与slapd.conf在同一目录下)中读取相关信息,我们需要把该目录下的数据删掉,然后利用我们在slapd.conf里配置的信息重新生成配置数据。这也可能是你启动服务后运行ldap相关命令却出现“ldap_bind: Invalid credentials (49)”错误的主要原因。具体怎么重新生成配置数据请看1.4.5配置内容

 

疑惑5:自定义的ldif数据文件中的objectclass后的domain、top、organizationalUnit、inetOrgPerson等等都是什么意思,可以随便写吗?

解答:存储LDAP配置信息及目录内容的标准文本文件格式是LDIF(LDAP Interchange Format),使用文本文件来格式来存储这些信息是为了方便读取和修改,这也是其它大多数服务配置文件所采取的格式。LDIF文件常用来向目录导入或更 改记录信息,这些信息需要按照LDAP中schema的格式进行组织,并会接受schema 的检查,如果不符合其要求的格式将会出现报错信息。因此,ldif文件中的属性都定义在各大schema中,其中objectclass是对象的类属性, 不能随便填写,而应与schema中一致。一般slapd.conf文件的头部都包含了这些schema:

 

include         ../etc/openldap/schema/core.schema
include         ../etc/openldap/schema/cosine.schema
include         ../etc/openldap/schema/inetorgperson.schemainclude         ../etc/openldap/schema/nis.schema
include         ../etc/openldap/schema/krb5-kdc.schema
include         ../etc/openldap/schema/RADIUS-LDAPv3.schema
include         ../etc/openldap/schema/samba.schema

 

其中前三个是比较重要的schema,定义了我们所需要的各个类,比如ldif中一般先定义一个根节点,其相应的objectclass一般是 domain和top,而根节点下的ou属性即定义组节点(group)的objectclass一般是 organizationalUnit,group下可以是group也可以是用户节点,用户节点的objectclass一般是 inetOrgPerson。而各个节点的一系列属性如用户节点的uid、mail、userPassword、sn等等都定义在schema中相关的 objectclass里,可以自己查找看看。

 

疑惑6:OpenLDAP认证用户uid时默认是不区分大小写的,也就是“alexia”与“AleXia”是同一个用户,在有些情况下这并不合理,能配置使得认证时能区分大小写吗?

解答:以我目前的经验来看,旧版本的OpenLDAP是可以配置区分大小写的,而新版本的OpenLDAP却配置不了。为什么这么说呢?

这里就涉及到“matching rules”这个概念了,即匹配规则,就是各个属性按什么样的规则进行匹配,比如是否区分大小写、是否进行数字匹配等等,这里有详细的官方匹配规则描述。比如旧版本的core.schema里有下面这样一段:

attributetype ( 0.9.2342.19200300.100.1.1
   NAME ( 'uid' 'userid' )
   DESC 'RFC1274: user identifier'
   EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )

从字面上也可以看出,其中caseIgnoreMatchcaseIgnoreSubstringsMatch就定义了uid或userid属性匹配时不区分大小写,如果我们将其改为caseExactMatchcaseExactSubstringsMatch就表示用户uid认证时需要区分大小写,也就是“alexia”与“AleXia”同不同的用户,这很简单,在旧版本的OpenLDAP也行得通。

可是在新版本的OpenLDAP中却不行,新版本的core.schema文件中也包含这样一段:

#attributetype (  2.16.840.1.113730.3.1.217#    NAME ( 'uid' 'userid' )
#    DESC 'RFC1274: user identifier'#    EQUALITY caseIgnoreMatch
#    SUBSTR caseIgnoreSubstringsMatch
#    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )

可惜是注释掉的,那我们取消注释然后改属性行不行呢?答案是不行,会报错:Duplicate attributeType: "2.16.840.1.113730.3.1.217”,也就是说该属性已经被定义了,然后我就去包含的所有schema中搜索uid属性的定义,结果却找不到定义,那么为什么还会报这个错误呢?后来一阵搜索,终于在这个帖子“slapd: built-in schema for uidNumber/gidNumber does not have ordering directive”知道了答案,原来新版本的OpenLDAP已经把uid属性定义schema硬编码到了slapd程序中,也就是无法在配置文件中修改了,真是坑!

针对这个问题,我给出两个不太好的解决方案:

  1. 下载OpenLDAP源码,找到定义uid属性匹配规则的地方,修改它然后重新编译。这个工作量不轻松,热爱研究源码的人可以尝试。

  2. 不 要用uid属性进行认证,我们可以自定义一个与用户一一对应的属性如user-id(不要与已有的属性重复就行),其配置与uid一模一样(即模仿 uid),然后用该属性作为认证的因子,建议重新建一个schema,然后配置好后include进slapd.conf中重启服务即可。具体怎么定义和 配置可以参考这篇文章

 

我的主要经验也就这些。OpenLDAP也有客户端,如果你配置成功后,可以用客户端或写Java程序进行验证。