摘 要:本文分析了ldap数据同步协议、openldap2.4的实现和配置。
关键词: ldap,openldap2.4,数据同步
LDAP概述
OpenLdap是一个开源的ldap服务实现,当前最高稳定版本为2.4.11。openldap2.4实现了RFC4533规定的数据同步协议,不再使用老版本的slurpd推送方式来同步数据。openldap同步时,采用slapd派生的线程来进行同步操作。新的同步方式比老的方式更加稳定。
Openldap2.4编译时需要添加一些选项,否则不能使用一些同步特性。编译安装过程如下:
./configure –prefix=/usr/local/openldap-2.4.11 –enable-debug –enable-modules –enable-ldap –enable-relay –enable-accesslog –enable-auditlog –enable-syncprov CPPFLAGS=-I/usr/local/JnLdap/db-4.2.52-AES/include/ LDFLAGS=-L/usr/local/JnLdap/db-4.2.52-AES/lib/
make depend
make
make install
在configure阶段–enable-ldap、–enable-accesslog和–enable-syncprov选项不可少。其中–enable-ldap选项用于支持ldap代理,在同步中用来推送数据;–enable-accesslog选项用于记录用户操作,在同步中用于记录服务端的数据修改;–enable-syncprov选项用于支持数据同步引擎。
LDAP数据同步协议
Ldap数据同步协议(RFC4533)由openldap基金会的K. Zeilenga和IBM的J.H. Choi提出,并在openldap2.4中实现。该协议将同步操作定义为ldap协议的一个扩展操作,并规定了两种同步模式:refreshOnly和refreshAndPersist。这两种模式中,同步均由客户端发起,所不同的是同步完成后的操作:refreshOnly模式下,后续操作由客户端轮询完成,refreshAndPersist模式下,在后续操作中,服务端负责发送相应的改变数据而客户端负责接受并处理本地ldap条目。
为了提高性能和减少网络传输,ldap数据同步协议要求客户端发起同步请求时,提供一个cookie(最开始的请求除外)。服务端根据此cookie来决定发送给客户端的数据,客户端根据接收到的数据来处理本地的ldap条目。在同步完成之后,客户端必须更新cookie,用于下次同步。Cookie是服务端计算(查询本地条目)的依据。
在每种模式中,都涉及到如何计算数据的变化,包括:添加的数据、修改的数据以及删除的数据。Ldap的每个条目包含了时间信息,包括生成时间戳(createTimestamp)和修改时间戳(modifyTimestamp)。对于添加和修改的数据,服务端根据客户端传送来的cookie(包含时间信息)计算得到,并将这些数据发送给客户端,每个数据标记是添加的还是修改的。对于已删除的数据,则处理比较复杂。当服务端有修改日志时,服务端可以较容易地根据cookie来计算被删除的条目,并将这些条目的DN或者UUID发送给客户端。客户端收到后删除本地的条目。此种情况下,删除条目的计算在服务端完成。当服务端无记录修改日志时,服务端无法计算哪些条目被删除,它只能提供当前还存在的数据。服务端将这些还存在的条目DN或者UUID[2]发送给客户端,由客户端来计算已删除条目。
Ldap协议主要包含两种模式,如下所示:
1)RefreshOnly模式
如下图所示:
说明:
1)Initial Content Request(初始请求)中,客户端不提供cookie,服务端返回所有符合查询条件的条目,结束时客户端得到一个cookie;
2)Content Refresh Request(内容更新请求)与初始化请求的查询条件必须一致,并且包含一个cookie,
3)内容更新阶段,“Changes Entries”包括新添加的条目和修改的条目(基于cookie计算得出);对于已删除的条目,有两种方式来通知客户端。“Present Messages”用于返回当前还存在的条目;“Deleted Messages”用于明确告知客户端已删除的条目。这两种消息仅包含条目的名称(Directory Name)或者UUID。
4 openldap2.4同步配置
1)Openldap同步的各种情况
如下表所示:
序号 | 同步方式 | 服务端是否有日志 (Yes/No) |
协议模式 (refreshOnly /refreshAndPersist) |
客户端读写属性 |
1 | 推 | No | refreshOnly | 读/写 |
2 | 推 | No | refreshAndPersist | 读/写 |
3 | 推 | Yes | refreshOnly | 读/写 |
4 | 推 | Yes | refreshAndPersist | 读/写 |
5 | 拉 | No | refreshOnly | 只读 |
6 | 拉 | No | refreshAndPersist | 只读 |
7 | 拉 | Yes | refreshOnly | 只读 |
8 | 拉 | Yes | refreshAndPersist | 只读 |
说明:
-
推模式需要通过ldap backend来实现,配置主要在服务端,包括配置ldap backend和syncrepl[3];客户配置主要是添加updatedn选项;
-
服务端修改日志通过slapd accesslog overlay来实现,配置在服务端,需要配置一个对应的bdb backend;
-
协议模式由syncrepl中的type选项标识;
-
拉模式下,客户端数据是只读的,如要进行双向同步,需要采用推模式。
2)配置实例
对于openldap同步的配置,用户可以参考openldap自带的管理员手册。下面给出了一个双向同步的示例(互为主从,仅给出一个服务的配置)。该例中,4401端口的ldap服务将ou=SOA,dc=pmi下的数据推送给4402端口的ldap服务;4402端口的ldap服务将ou=hubei,dc=pmi下的数据推送给4401;各服务端均记录了修改日志。
4401端口的ldap服务配置:
database bdb
suffix “dc=pmi”
rootdn “cn=manager,dc=pmi”
rootpw fucky
directory /usr/local/openldap-2.4.11/var/openldap-data
index objectClass eq
index entryCSN eq
index entryUUID eq
overlay syncprov
syncprov-sessionlog 100
#不可少
updatedn cn=manager,dc=pmi
#用于记录修改日志
database bdb
suffix cn=accesslog
directory /usr/local/openldap-2.4.11/var/accesslog
rootdn cn=accesslog
rootpw fucky
index default eq
index entryCSN,objectClass,reqEnd,reqResult,reqStart
overlay syncprov
syncprov-nopresent TRUE
syncprov-reloadhint TRUE
#配置ldap代理
database ldap
hidden on
suffix “dc=pmi”
rootdn “cn=manager,dc=pmi”
uri ldap://192.168.1.24:4402/dc=pmi
acl-bind bindmethod=simple binddn=”cn=manager,dc=pmi”
credentials=”fucky”
#配置同步
syncrepl
rid=1 provider=ldap://192.168.1.24:4401 binddn=”cn=manager,dc=pmi”
bindmethod=simple
credentials=fucky
searchbase=”ou=SOA,dc=pmi”
filter=”(objectClass=*)”
logbase=”cn=accesslog” logfilter=”(&(objectClass=auditWriteObject)(reqResult=0))”
schemachecking=off
scope=sub type=refreshAndPersist
retry=”5 5 300 5″
另外一个服务的配置与此类似。如果要同步的条目包含汉字,需要将slapd.conf配置文件转换为UTF8编码。
参考文献
[1] The Lightweight Directory Access Protocol (LDAP) Content Synchronization Operation,rfc4533
[2] Lightweight Directory Access Protocol (LDAP) entryUUID Operational Attribute,rfc4530
[3] OpenLDAP Software 2.4 Administrator’s Guide,openldap-2.4.11联机文档