一、 OpenLdap简介
LDAP的英文全称是Lightweight Directory Access Protocol(轻量级的目录访问协议),它基于X.500标准的,支持TCP/IP。简单地说,LDAP其实就是数据库三种模型中的层次型数据库,按照树型结构组织,由entry(条目)这种相当于关系型数据库中记录的数据结构组成。每个条目由多个属性-值对组成,其中DN(区别名)属性是标识这条记录的关键字,还由一个特殊的属性ObjectClass(对象类别)来实现的决定了该条目必须遵循的一些规则,规定了该条目必须和可选包含哪些属性。每个属性都可以有多个值。LDAP的数据类型不用申明默认都为字符型,除了个别还定义了一些如BIN(二进制数据)、CIS(忽略大小写)、CES(大小写敏感)、TEL(电话型)等。LDAP的一个很大的特点就是适合于大型OLTP的数据查询服务,但不适合需要经常改变数据的情况。
二、 项目描述
本项目目的在于提供用户购买会员卡进行网上信息查询,考虑到LDAP读快写慢的特点,而本项目的特点就在于不频繁地导入更新数据库,决定采用Openldap构建用户信息验证数据库。该数据库有两个子树(相当于两个表),用户信息树和会员帐号树。由于会员卡是事先批量制作流入市场,与用户没有固定的对应关系,只有当用户购买会员卡并注册一个用户名后才能通过网络告知系统用户信息和会员卡号之间的这种关联关系。于是在后台数据库中用户信息树和会员帐号树之间就通过会员卡号作为关联关键字。
三、 数据库结构图
该数据库的构建更能体现逻辑和功能上的模块化。以域名info.net作为树根,有一个系统管理员admin(DN:cn=admin,dc=info,dc=net),该库中包括两大子树:people组(DN:ou=people,dc=info,dc=net),用于存放用户信息;Account组(DN:ou=Account,dc=info,dc=net),用于存放会员卡信息。
四、 平台环境
1. 硬件
SUN sparc主机(主从同步结构)
四层交换机(SLB负载均衡)
2. 软件
OS: solaris 8(sparc)
BerkeleyDB2.7.7(www.sleepycat.com)
Openldap1.2.11(www.openldap.org)
五、 数据库构建的过程
1. 安装OS和应用软件
安装Solaris8,BerkeleyDB2.7.7和Openldap1.2.11
Openldap1.2.11基于BerkeleyDB2.7.7之上
2. 系统配置
修改系统核心参数文件/etc/system:
加入文件句柄的软限制和硬限制:
* set hard limit on file descriptors
set rlim_fd_max = 4096
* set soft limit on file descriptors
set rlim_fd_cur = 1024
修改核心参数需要重启机器
3. 数据库配置
主LDAP服务器:
Slapd.conf
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /opt/openldap/etc/openldap/slapd.at.conf
include /opt/openldap/etc/openldap/slapd.oc.conf
include /opt/openldap/etc/openldap/slapd.info.oc.conf
include /opt/openldap/etc/openldap/slapd.account.oc.conf
schemacheck on
pidfile /opt/openldap/var/slapd.pid
argsfile /opt/openldap/var/slapd.args
loglevel 8
#######################################################################
# ldbm database definitions
#######################################################################
database ldbm
cachesize 3000000
dbcachesize 500000000
#dbcachenowsync
timelimit 30
suffix "dc=info, dc=net"
rootdn "cn=root, dc=info, dc=net"
rootpw root
# cleartext passwords, especially for the rootdn, should
# be avoid. See slapd.conf(5) for details.
replogfile /opt/openldap/log/slapd.replog
directory /opt/openldap/data
index id,card_id,email
index default none
replica host=n.n.n..n binddn="cn=root, dc=info, dc=net" bindmethod=simple credentials=root
defaultaccess none
access to dn=".*,dc=root,dc=net"
by self read
by dn="cn=Admin,dc=root,dc=net" write
by * none
access to *
by self read
by dn="cn=Admin,dc=root,dc=net" write
by * none
该配置指定了两个自定义schema:slapd.info.oc.conf slapd..account.oc.conf,同步的辅助服务器和一些ACL用于安全限制
辅LDAP服务器:
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /opt/openldap/etc/openldap/slapd.at.conf
include /opt/openldap/etc/openldap/slapd.oc.conf
include /opt/openldap/etc/openldap/slapd.info.oc.conf
include /opt/openldap/etc/openldap/slapd.account.oc.conf
schemacheck on
pidfile /opt/openldap/var/slapd.pid
argsfile /opt/openldap/var/slapd.args
loglevel 8
#######################################################################
# ldbm database definitions
#######################################################################
database ldbm
#cachesize 4000000
#dbcachesize 500000000
#dbcachenowsync
timelimit 30
suffix "dc=info, dc=net"
rootdn "cn=root, dc=info, dc=net"
rootpw root
# cleartext passwords, especially for the rootdn, should
# be avoid. See slapd.conf(5) for details.
replogfile /opt/openldap/log/slapd.replog
directory /opt/openldap/data
index id,card_id,email
index default none
updatedn "cn=root,dc=info,dc=net"
defaultaccess none
access to dn=".*,dc=info,dc=net"
by self read
by dn="cn=Admin,dc=info,dc=net" write
by * none
access to *
by self read
by dn="cn=Admin,dc=info,dc=net" write
by * none
该配置指定了主LDAP同步过来修改本机信息的权限
增加slapd.info.oc.conf:(用户信息的配置文件)
objectclass InfoPerson
requires
objectClass,
id
allows
username,
pass,
uid,
addr,
shenfenno,
tel,
card_id
指定id字段是比不可少的,其他都为可选
增加slapd.account.oc.conf:(账号信息配置文件)
objectclass AccountPerson
requires
objectClass,
card_id
allows
card_pass
指定了卡号和卡密码
重新启动LDAP SERVER:
这里主LDAP服务器的启动脚本如下
/etc/rc2.d/S94slapd
#!/bin/sh
#
#ident LDAP Service
case " $1" in
'start')
if [ -f /opt/openldap/etc/openldap/slapd.conf -a -f /opt/openldap/libexec/slapd ]; then
echo "LDAP service starting."
/opt/openldap/libexec/slapd -f /opt/openldap/etc/openldap/slapd.conf 1>/dev/console 2>&1 &
fi
if [ -f /opt/openldap/etc/openldap/slapd.conf -a -f /opt/openldap/libexec/slurpd ]; then
echo "LDAP sync service starting."
/opt/openldap/libexec/slurpd -f /opt/openldap/etc/openldap/slapd.conf -t /opt/openldap/log >/tmp/slurpd.log 2>&1 &
fi
;;
'stop')
[ ! -f /opt/openldap/var/slapd.pid ] && exit 0
slappid=`cat /opt/openldap/var/slapd.pid`
if [ " $slappid" -gt 0 ]; then
echo "Stopping the LDAP service."
kill -15 $slappid 2>&1 | /usr/bin/grep -v "no such process"
fi
slurpdpid=`/usr/bin/ps -e |grep slurpd | awk '{print $1}'`
if [ " $slurpdpid" -gt 0 ]; then
echo "Stopping the LDAP SYNC service."
kill -15 $slurpdpid 2>&1 | /usr/bin/grep -v "no such process"
fi
;;
*)
echo "Usage: /etc/init.d/syslog { start | stop }"
;;
esac
exit 0
注意:主LDAP服务器比辅LDAP服务器多启动了一个slurpd的同步进程,而辅助服务器只需要启动一个slapd的LDAP进程就可以了。
配置syslog:
为了记录LDAP的日志,在slapd.conf中设置了loglevel的级别设置了8,所以可以配合操作系统的syslog做ldap的日志记录。/etc/syslog.conf文件增加:
#log for slapd
local4.emerg;local4.alert;local4.crit;local4.err;local4.warning;local4.notice;local4.info;local4.debug /opt/openldap/log/openldap.log
注意用TAB键做分割,这样重新启动syslog进程就可以了,LDAP的日志文件在/opt/opendlap.log/openldap.log
4. 数据导入
首先用LDIF文件建立一个层次数据库的框架:
global.ldif文件:
dn: dc=info, dc=net
objectClass: top
objectClass: organization
o: info.net
dn: ou=People, dc=info, dc=net
objectClass: top
objectClass: organizationalUnit
ou: People
description: User Info
dn: cn=Admin, dc=info, dc=net
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Admin
sn: Admin
userPassword: Admin
description: Administrator for info.net
dn: ou=Account, dc=info, dc=net
objectClass: top
objectClass: organizationalUnit
ou: Account
description: Card Account
用在线命令(即LDAP服务开启的状态下)
/opt/openldap/bin/ldapadd -D "cn=root,dc=info,dc=net" -w root –f global.ldif
可以建立该数据库的框架。
接下来可以加入数据库的数据:
data.ldif文件:
dn: id=1, ou=people, dc=info, dc=net
objectclass: top
objectclass: InfoPerson
id: 1
username: 张三
tel:021-63138990
card_id:ABC001
dn: card_id=ABC001, ou=Account, dc=info, dc=net
objectclass: top
objectclass: AccountPerson
card_id: ABC001
card_pass ABC123
加入了用户id为1的用户和卡号为ABC001的会员卡,并且该用户和该卡通过卡号ABC001相关联
如果导入的数据量大,并且要求实效性很强,用在线命令导入就会占用很长的时间,为了快速批量导入,可以在LDAP服务关闭的状态下使用非在线命令导入数据:
cp global.ldif /tmp/info.ldif
cat data.ldif >> /tmp/info.ldif //现在info.ldif为全部信息的LDIF文件
/etc/rc2.d/S94slapd stop 应该在LDAP进程关闭的情况下导入:
/opt/openldap/sbin/ldif2ldbm -i /tmp/info.ldif -f /opt/openldap/etc/openldap/slapd.conf //将文本LDIF文件转换成LDBM的二进制文件
/etc/rc2.d/S94slapd start
有时为了在原数据库的基础上继续追加数据,可以:
1./opt/openldap/sbin/ldbmcat -n /opt/openldap/data/id2entry.dbb > n_id2entry(先将LDBM库导出无序号的LDIF文件,LDIF文件是一种有格式的文本文件)
2.追加LDIF文件
3//opt/openldap/sbin/ldif2ldbm -i n_id2entry -f /opt/openldap/etc/openldap/slapd.conf(在LDAP服务关闭的情况下批量导入)
有时可能会发觉索引比较紊乱,以至于在LDAP下无法查询到相关FILTER的记录,为了重建索引,可以:
1./opt/openldap/sbin/ldbmcat /opt/openldap/data/id2entry.dbb > id2entry (导出有序号的LDIF文件)
2./opt/openldap/sbin/ldif2index -i id2entry -f /opt/openldap/etc/openldap/slapd.conf <索引关键字> (重建索引,索引关键字在slapd.conf文件中用index指定)
具体这些二进制数据的存放都在openldap/data下
5. 检查LDAP上的操作和主从同步是否正确:
可用以下命令来测试数据库的增加、删除、修改和查询:
1.查询命令
/opt/openldap/bin/ldapsearch -D "cn=Admin,dc=info,dc=net" -w Admin id=”1”
/opt/openldap/bin/ldapsearch -D "cn=Admin, dc=info, dc=net" -w Admin -b "ou= Account,dc=info,dc=net" "card_id=ABC001"
2.增加命令
/opt/openldap/bin/ldapadd -D "cn=root,dc=info,dc=net" -w root -f add.ldif
3.删除命令
/opt/openldap/bin/ldapdelete -D "cn=root,dc=info,dc=net" -w root "id=1,ou=People,dc=info,dc=net"
4.修改命令
/opt/openldap/bin/ldapmodify -D "cn=Admin,dc=info,dc=net" -w Admin -f modfile
modfile的格式如下:
dn: id=1, ou=People, dc=info, dc=net
add: shenfenno
shenfenno: 3101037108002
dn: card_id=ABC001, ou=Account, dc=info, dc=net
replace: card_pass
card_pass: DEF001
5.同步测试
在主LDAP服务器上做了增加、删除或修改的操作,用查询命令查看主从LDAP服务器的信息是否一致(自动同步)
同步日志在/opt/openldap/log/replica下,不同步的出错日志在/opt/openldap/log/replica下的以辅助IP地址开头的.rej文件。而/opt/openldap/log/replica下的slurpd.status反应的是同步时间戳,如果你有多台辅助LDAP服务器,通过查看该文件的时间戳是否一致也可以判断哪台服务器没有同步成功