LDAP是什么?
LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写,其实是一种目录服务,类似于我们在文件系统中所使用的目录,类似于我们查询电话号码使用的电话号码簿,类似于我们所使用诸如 NIS(Network Information Service)、DNS (Domain Name Service)等网络目录,也类似于你在花园中所看到的树木。
LDAP是一种特殊的数据库。但是LDAP和一般的数据库不同,明白这一点是很重要的。 LDAP对查询进行了优化,与写性能相比LDAP的读性能要优秀很多。
一般地,目录服务提供什么样的服务呢?通常是根据查询的标准返回一定的信息。
实例
文件系统目录
ls /etc 返回/etc目录下所有的文件和子目录。
ls /etc/p* 返回/etc下所有以p开头的文件和子目录。
find /usr/local/apache -name index.html 这将在"/usr/local/apache"目录下搜索名为index.html的文件/子目录。
NIS目录
ypcat passwd 这将从NIS数据库返回用户名、密码、用户id等信息。
ypmatch atif passwd 返回用户atif的密码。
DNS目录
nslookup
www.linuxfocus.org 返回
www.linuxfocus.org的ip地址。
nslookup -type MX linuxfocus.org 返回主机名符合linuxfocus.org的MX记录信息。
LDAP目录
(我们将在下面详细阐述)
ldapsearch uid=aghaffar 返回关于用户aghaffar的所有公开信息。
这和find / -uid aghaffar unix命令很类似。
ldapsearch uid=aghaffar mail 返回用户ughaffar的邮件信息
目录基础或根
在上面我们所提到的任何一种目录服务中都有一个我们开始浏览或搜索的开始点。 这个开始点就是通常所谓的根。 这和一棵数的根也很类似。每棵都有一个根,以及很多的树枝树叶。
* 文件系统的根是 /
* NIS 的根是域名,比如 "linuxfocus.org"
* DNS 根是Internic(译者注:Internet网络信息中心, Internet的管理组织)
* LDAP同样有一个可定义的根,比如 "o=linuxfocus.org" ,这里o表示组织
每个根都可以衍生出好多枝叶(正如同你邻居的花园中的树木一样), 对于文件系统来说,它的枝叶就是一个个文件及子目录。每一个枝叶都有一些属性。比如文件系统的枝叶(文件及子目录)有以下的属*:
* 名称
* 修改时间
* 所有者
* 组(译者注:所有者所在的组)
* 等等
* 修改时间
* 所有者
* 组(译者注:所有者所在的组)
* 等等
下图显示了一个文件系统目录。
属性由unix命令ls -ld /usr得到。
下面是一个LDAP目录的图示:
我们将在下面讨论这张图。
区分名(DN,Distinguished Name)
和自然界中的树不同,文件系统/LDAP/电话号码簿目录的每一片枝叶都至少有一个独一无二的属*,这一属性可以帮助我们来区别这些枝叶。
在文件系统中, 这些独一无二的属性就是带有完整路径的文件名。比如/etc/passwd,该文件名在该路径下是独一无二的。当然我们可以有/usr/passwd, /opt/passwd,但是根据它们的完整路径,它们仍然是唯一的。
类似于DNS系统的FQDN正式域名,FQDN也是唯一的。
在LDAP中,一个条目的区分名称叫做“dn”或者叫做区分名。在一个目录中这个名称总是唯一的。比如,我的dn是"uid=aghaffar, ou=People, o=developer.ch"。不可能有相同的dn,但是我们可以有诸如"uid=aghaffar, ou=Administrators, o=developer.ch"的dn。这同上面文件系统中/etc/passwd 和 /usr/passwd的例子很类似。
我们有独一无二的属*,在"ou=Administrators, o=developer.ch" 中uid和在"ou=People, o=developer.ch"中的uid。这并不矛盾。
LDAP服务器
现在市场上有很多LDAP服务器,大多数都可以在linux上运行。本文将介绍openLDAP的使用。
我为什么选择openLDAP? 为什么你应该选择openLDAP?
* openLDAP是开放源码的
openLDAP的官方网站是
http://www.openldap.org。你可以下载其源代码包自己编译,或者看看你的linux发行版是否已经包含了该软件包。如果已经包含了就可以安装预先编译好的版本从而少花费些力气。
我已经成功地在SuSE6.x 和 RedHat6.x上测试过openLDAP。
构建LDAP目录
下面我们将介绍设置一个LDAP服务器的步骤。
步骤:
* 下载并安装openLDAP
* 配置 LDAP server
* 配置本地环境指向LDAP 安装
* 初始化LDAP 数据库
* 查询 LDAP
* 添加/修改 LDAP 条目
* 配置 LDAP server
* 配置本地环境指向LDAP 安装
* 初始化LDAP 数据库
* 查询 LDAP
* 添加/修改 LDAP 条目
下载并安装openLDAP
配置LDAP服务器
配置LDAP服务器
在我们的例子中,我将为linuxfocus.org构建LDAP服务器。你可以用你喜欢的编辑器编辑slapd.conf和ldap.comf配置文件来更改名称等参数以适应你的具体需求。
在我的服务器上配置文件在/etc/openldap目录下,你的配置文件可能在/usr/local/etc/openldap或者别的地方,这要根据你的linux发行版本或者编译openldap的具体情况而定。
######### /etc/openldap/slapd.conf ###################################
# 下面的部分是我的suse 6.4 linux 发行版本预先定义的
# 我们设置的部分在本文的第二和第三部分
include /etc/openldap/slapd.at.conf
include /etc/openldap/slapd.oc.conf
schemacheck off
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
#######################################################################
# ldbm database definitions
#######################################################################
# 定义使用的数据库类型。 缺省是ldbm
database ldbm
# 后缀或者根. 这是你LDAP目录的顶节点
=======================================================================================suffix "o=linuxfocus.org"
# LDAP的dbs 保存的位置
directory /var/lib/ldap
# 目录管理员的区分名
rootdn "cn=Manager, o=linuxfocus.org"
# 保存ldap目录管理员的明文密码是很糟糕的,但是我们将在刚刚开始使用ldap时这样做
rootpw secret
# 这就是所有的一切
# 我们设置的部分在本文的第二和第三部分
include /etc/openldap/slapd.at.conf
include /etc/openldap/slapd.oc.conf
schemacheck off
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
#######################################################################
# ldbm database definitions
#######################################################################
# 定义使用的数据库类型。 缺省是ldbm
database ldbm
# 后缀或者根. 这是你LDAP目录的顶节点
=======================================================================================suffix "o=linuxfocus.org"
# LDAP的dbs 保存的位置
directory /var/lib/ldap
# 目录管理员的区分名
rootdn "cn=Manager, o=linuxfocus.org"
# 保存ldap目录管理员的明文密码是很糟糕的,但是我们将在刚刚开始使用ldap时这样做
rootpw secret
# 这就是所有的一切
编辑你的 /etc/openldap/ldap.conf配置文件
该文件位于ldap客户端(我们将使用同一计算机作为服务器和客户端,当然这可以在同一计算机或不同的计算机上)
通常诸如ldapdelete 、ldapadd等等的ldap客户端会读该文件的内容。
##########/etc/openldap/ldap.conf#########
# LDAP 的缺省设置
#
# 查看 ldap.conf(5) 可以获取更多的信息
# 本文件应该设置为对所有人可读
# 定义ldap服务器,可以用主机名或ip地址
host 127.0.0.1
# 定义我们要查询的目录的根
# 我们将要使用的顶节点,这不一定是目录的根,比如我们可以使用
# base = ou=users, o=linuxfocus.ch
# 这时我们的一切查询都将从树根o=linuxfocus.org的分支开始
现在启动ldap服务器。
如果你使用SuSE预先编译好的openldap服务器,你可以通过下面的命令启动ldap服务
/etc/rc.d/ldap start
在RedHat,该命令为
/etc/rc.d/init.d/ldap start
如果你是使用缺省设置自己编译并安装的,你可以用/usr/local/libexec/slapd &启动ldap服务器。如果没有使用缺省设置,请找到slapd文件并运行它。
在新安装的LDAP服务器上添加数据
到现在为止,你的ldap服务器已经运行起来了,可以准备添加数据了。最标准的往ldap服务器中添加数据的方法是建立一个LDIF(LDAP目录交换格式)文件。你可以通过阅读man ldif来获得更多关于ldif的信息。
简单说来,ldif是ldap条目的文本表示。这些条目是很好读懂的,并且可以在来自两个不同的厂家的LDAP服务器间交换数据,哪怕使用的是不同的数据库后台或者是运行在不同的操作系统上。
是的,还有其他方法。我对为什么不使用XML替代LDIF感到很惊讶。
就让我们一起来建立ldif文件,而不要感到任何的忙乱。一些应该记住的要点:ldif 文件中的每一记录/条目都应用一个空行分开。空格是很重要的,"Atif Ghaffar" 和"Atif Ghaffar " 是完全不同的
下面是一个ldif文件linuxfocus.org.ldif
1、dn: o=linuxfocus.org #定义顶级记录的区分名,目录的根
2、o: linuxfocus.org #定义组织,并赋值
3、objectclass: top #定义对象类
4、objectclass: organization #定义对象类型
5、
6、dn: ou=editors, o=linuxfocus.org #定义组editors
7、ou: editors #定义组织单元的属*
8、objectclass: organizationalUnit #定义对象类
9、
10、dn: uid=aghaffar, ou=editors, o=linuxfocus.org #定义属于组editors的用户
11、uid: aghafar #定义该用户的UID
12、cn: Atif Ghaffar #定义该用户的普通名
13、sn: Ghaffar #姓
14、givenname: Atif #名
15、objectclass: person #对象类
16、userpassword: yIvSBWSuLs2N2 #用户密码
17、mailacceptinggeneralid: aghaffar@linuxfocus.org #定义邮箱地址
18、ou: editors #定义所属的组织单元
19、
20、dn: uid=mkempe, ou=editors, o=linuxfocus.org #定义另外一个用户
21、uid: mkempe #定义该用户的UID
22、cn: Magnus Kempe #普通名
23、sn: Kempe #姓
24、givenname: Magnus #名
25、objectclass: person #对象类
26、userpassword: clearpass #密码
27、mailacceptinggeneralid: mkempe@linuxfocus.org #邮箱地址
28、maildrop: mkempe@developer.ch #邮箱的真实地址
29、preferredlanguage: fr #母语
30、ou: editors #组织单元
2、o: linuxfocus.org #定义组织,并赋值
3、objectclass: top #定义对象类
4、objectclass: organization #定义对象类型
5、
6、dn: ou=editors, o=linuxfocus.org #定义组editors
7、ou: editors #定义组织单元的属*
8、objectclass: organizationalUnit #定义对象类
9、
10、dn: uid=aghaffar, ou=editors, o=linuxfocus.org #定义属于组editors的用户
11、uid: aghafar #定义该用户的UID
12、cn: Atif Ghaffar #定义该用户的普通名
13、sn: Ghaffar #姓
14、givenname: Atif #名
15、objectclass: person #对象类
16、userpassword: yIvSBWSuLs2N2 #用户密码
17、mailacceptinggeneralid: aghaffar@linuxfocus.org #定义邮箱地址
18、ou: editors #定义所属的组织单元
19、
20、dn: uid=mkempe, ou=editors, o=linuxfocus.org #定义另外一个用户
21、uid: mkempe #定义该用户的UID
22、cn: Magnus Kempe #普通名
23、sn: Kempe #姓
24、givenname: Magnus #名
25、objectclass: person #对象类
26、userpassword: clearpass #密码
27、mailacceptinggeneralid: mkempe@linuxfocus.org #邮箱地址
28、maildrop: mkempe@developer.ch #邮箱的真实地址
29、preferredlanguage: fr #母语
30、ou: editors #组织单元
下面我们将这些数据加入ldap目录。我们使用命令行程序ldapadd
ldapadd -D "cn=Manager, o=linuxfocus.org" -w secret < linuxfocus.org.ldif
该命令使用“cn=Manager, o=linuxfocus.org”作为管理员的区分名(dn),使用secret作为密码,然后从linuxfocus.org.ldif文件中读取数据并写入ldap目录。
如果一切正常的话你可以准备开始查询你的ldap目录了,否则如果其间出了差错的话,你或许可以准备往我的邮箱灌水了;)
为我的邮件服务器考虑,我希望一切正常。
在继续之前,让我们一行一行的来检查一下这个ldif文件。
1. 这一行定义顶级记录的区分名(dn),这将是目录树的根,这是必须定义的。
2. 这一行我们定义组织(o),并赋值为“linuxfocus.org”。
3. 这一行定义这个对象的对象类,我们定义为top。
4. 定义对象的类型(这里是组织对象)。
5. 空行为分割符。
6. 定义组editors(这是linuxfocus editors分支),举一反三,我们也可以根据不同的目的来定义其他的分支,比如hosts和data分支。
7.明确定义组织单元(ou)editors的属性。属性是可以被用来查询的条目,比如,如果你想要查询所有属于editors的用户,你可以这样查询 “show all dn where ou=editors”。如果我们没有定义属*,则这条记录将不符合查询条件。
8. 定义对象类(组织单元)。
9. 空行为分割符。
10. 定义属于组editors的用户aghaffar的区分名。
11. 定义该用户的uid(要保证其是唯一的)。
12. 定义该用户的cn(普通名字),比如,我喜欢将我的名字写成“Firstname Lastname”,而有的人可能喜欢“Lastname Firstname”.
13. 姓
14. 名
15. 对象类(人)
16. 用户密码(这里是加密的密码)。这串字符表示密码是用加密算法加密过的。剩下的部分是用“yI”加密的密码"yIvSBWSuLs2N"。
17. 定义我的邮件地址。
18. 定义我所属于的组织单元(组editors)
19. 空行为分割符。
20. 定义另一个用户mkempe
21. 普通名字
22. 姓
23. 名
24. 对象类
25. 用户密码:注意这里我们使用明文密码。你可以为不同的用户使用不同的方案。这是根据每一条目定义的,而不是基于数据库定义的。因此一个用户可能使用明文密码,第二个可能使用加密密码,另一个则可能使用SHA认证方式。
26. 邮件地址。
27. maildrop:定义用户邮箱的真实位置。在这个例子中,这个服务器接受收件人为 mkempe@linuxfocus.org的邮件,然后邮件服务器会查询ldap服务器“有接受收件人为 mkempe@linuxfocus.org的邮箱吗?”ldap服务器就会返回maildrop属性值。接着邮件服务器就会将该邮件发给那个邮箱。
28.母语:这是我们一个额外的属*,这个属性定义了用户的母语。我们可以利用存储在中央ldap服务器的信息来为改用户提供更好的服务。比如,直接向该用户显示本页的法语版本。请注意前面一条记录没有母语、maildrop等属*,这也是ldap强大的一个方面——不必象一个数据库中的表格那样拥有固定的结构。你可以在一条记录中定义3条属*,而在另一个中定义30条属性。
29. 组织单元。
2. 这一行我们定义组织(o),并赋值为“linuxfocus.org”。
3. 这一行定义这个对象的对象类,我们定义为top。
4. 定义对象的类型(这里是组织对象)。
5. 空行为分割符。
6. 定义组editors(这是linuxfocus editors分支),举一反三,我们也可以根据不同的目的来定义其他的分支,比如hosts和data分支。
7.明确定义组织单元(ou)editors的属性。属性是可以被用来查询的条目,比如,如果你想要查询所有属于editors的用户,你可以这样查询 “show all dn where ou=editors”。如果我们没有定义属*,则这条记录将不符合查询条件。
8. 定义对象类(组织单元)。
9. 空行为分割符。
10. 定义属于组editors的用户aghaffar的区分名。
11. 定义该用户的uid(要保证其是唯一的)。
12. 定义该用户的cn(普通名字),比如,我喜欢将我的名字写成“Firstname Lastname”,而有的人可能喜欢“Lastname Firstname”.
13. 姓
14. 名
15. 对象类(人)
16. 用户密码(这里是加密的密码)。这串字符表示密码是用加密算法加密过的。剩下的部分是用“yI”加密的密码"yIvSBWSuLs2N"。
17. 定义我的邮件地址。
18. 定义我所属于的组织单元(组editors)
19. 空行为分割符。
20. 定义另一个用户mkempe
21. 普通名字
22. 姓
23. 名
24. 对象类
25. 用户密码:注意这里我们使用明文密码。你可以为不同的用户使用不同的方案。这是根据每一条目定义的,而不是基于数据库定义的。因此一个用户可能使用明文密码,第二个可能使用加密密码,另一个则可能使用SHA认证方式。
26. 邮件地址。
27. maildrop:定义用户邮箱的真实位置。在这个例子中,这个服务器接受收件人为 mkempe@linuxfocus.org的邮件,然后邮件服务器会查询ldap服务器“有接受收件人为 mkempe@linuxfocus.org的邮箱吗?”ldap服务器就会返回maildrop属性值。接着邮件服务器就会将该邮件发给那个邮箱。
28.母语:这是我们一个额外的属*,这个属性定义了用户的母语。我们可以利用存储在中央ldap服务器的信息来为改用户提供更好的服务。比如,直接向该用户显示本页的法语版本。请注意前面一条记录没有母语、maildrop等属*,这也是ldap强大的一个方面——不必象一个数据库中的表格那样拥有固定的结构。你可以在一条记录中定义3条属*,而在另一个中定义30条属性。
29. 组织单元。
查询ldap数据库
让我们找出关于用户mkempe的所有数据 ldapsearch uid=mkempe
找出editors的所有区分名 ldapsearch (&(objectclass=person)(ou=editors)) dn
更多的例子可以参考ldapsearch的man手册。
LDAP的好处
让我们来看一看迁移到LDAP所带来的好处。
LDAP是一个开放的标准。你将使用的大多数的新的应用程序都能够查询ldap数据库,甚至windows2000使用LDAP作为他的目录服务。信息的集中化将会带来巨大的利益,单点管理,减少错误,减少数据复制等等。
====================================================
====================================================