什么是LDAP?
LDAP的英文全称是Lightweight Directory Access Protocol,通常都简称为LDAP。它是基于X.500标准的,
可是简单多了而且能够根据须要定制。与X.500不一样,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP
的核心规范在RFC中都有定义,全部与LDAP相关的RFC均可以在LDAPman RFC网页中找到。如今LDAP技术不只
发展得很快并且也是激动人心的。在企业范围内实现LDAP可让运行在几乎全部计算机平台上的全部的应
用程序从LDAP目录中获取信息。LDAP目录中能够存储各类类型的数据:电子邮件地址、邮件路由信息、人力
资源数据、公用密匙、联系人列表,等等。经过把LDAP目录做为系统集成中的一个重要环节,能够简化员工
在企业内部查询信息的步骤,甚至连主要的数据源均可以放在任何地方。
LDAP目录的优点
若是须要开发一种提供公共信息查询的系统通常的设计方法多是采用基于WEB的数据库设计方式,即前端
使用浏览器然后端使用WEB服务器加上关系数据库。后端在Windows的典型实现多是Windows NT + IIS + Acess
数据库或者是SQL服务器,IIS和数据库之间经过ASP技术使用ODBC进行链接,达到经过填写表单查询数据的功能;
后端在Linux系统的典型实现多是Linux+ Apache + postgresql,Apache和数据库之间经过PHP3提供的函数进
行链接。使用上述方法的缺点是后端关系数据库的引入致使系统总体的性能下降和系统的管理比较繁琐,由于需
要不断的进行数据类型的验证和事务的完整性的确认;而且前端用户对数据的控制不够灵活,用户权限的设置一
般只能是设置在表一级而不是设置在记录一级。
目录服务的推出主要是解决上述数据库中存在的问题。目录与关系数据库类似,是指具备描述性的基于属性的记
录集合,但它的数据类型主要是字符型,为了检索的须要添加了BIN(二进制数据)、CIS(忽略大小写)、CES
(大小写敏感)、TEL(电话型)等语法(Syntax),而不是关系数据库提供的整数、浮点数、日期、货币等类型,
一样也不提供象关系数据库中广泛包含的大量的函数,它主要面向数据的查询服务(查询和修改操做比通常是大于
10:1),不提供事务的回滚(rollback)机制,它的数据修改使用简单的锁定机制实现All-or-Nothing,它的目标
是快速响应和大容量查询而且提供多目录服务器的信息复制功能。
如今该说说LDAP目录到底有些什么优点了。如今LDAP的流行是不少因数共同做用的结果。可能LDAP最大的优点是:
能够在任何计算机平台上,用很容易得到的并且数目不断增长的LDAP的客户端程序访问LDAP目录。并且也很容易
定制应用程序为它加上LDAP的支持。
LDAP协议是跨平台的和标准的协议,所以应用程序就不用为LDAP目录放在什么样的服务器上操心了。实际上,LDAP
获得了业界的普遍承认,由于它是Internet的标准。产商都很愿意在产品中加入对LDAP的支持,由于他们根本不用
考虑另外一端(客户端或服务端)是怎么样的。LDAP服务器能够是任何一个开发源代码或商用的LDAP目录服务器(或
者还多是具备LDAP界面的关系型数据库),由于能够用一样的协议、客户端链接软件包和查询命令与LDAP服务器
进行交互。与LDAP不一样的是,若是软件产商想在软件产品中集成对DBMS的支持,那么一般都要对每个数据库服务
器单独定制。不象不少商用的关系型数据库,你没必要为LDAP的每个客户端链接或许可协议付费 大多数的LDAP服务
器安装起来很简单,也容易维护和优化。
LDAP服务器能够用“推”或“拉”的方法复制部分或所有数据,例如:能够把数据“推”到远程的办公室,以增长
数据的安全性。复制技术是内置在LDAP服务器中的并且很容易配置。若是要在DBMS中使用相同的复制功能,数据库
产商就会要你支付额外的费用,并且也很难管理。
LDAP容许你根据须要使用ACI(通常都称为ACL或者访问控制列表)控制对数据读和写的权限。例如,设备管理员可
以有权改变员工的工做地点和办公室号码,可是不容许改变记录中其它的域。ACI能够根据谁访问数据、访问什么数
据、数据存在什么地方以及其它对数据进行访问控制。由于这些都是由LDAP目录服务器完成的,因此不用担忧在客
户端的应用程序上是否要进行安全检查。
LDAP(Lightweight Directory Acess Protocol)是目录服务在TCP/IP上的实现(RFC 1777 V2版和RFC 2251
V3版)。它是对X500的目录协议的移植,可是简化了实现方法,因此称为轻量级的目录服务。在LDAP中目录是按照
树型结构组织,目录由条目(Entry)组成,条目至关于关系数据库中表的记录;条目是具备区别名DN(Distinguished
Name)的属性(Attribute)集合,DN至关于关系数据库表中的关键字(Primary
Key);属性由类型(Type)和多个值(Values)组成,至关于关系数据库中的域(Field)由域名和数据类型组成,
只是为了方便检索的须要,LDAP中的Type能够有多个Value,而不是关系数据库中为下降数据的冗余性要求实现的各
个域必须是不相关的。LDAP中条目的组织通常按照地理位置和组织关系进行组织,很是的直观。LDAP把数据存放在
文件中,为提升效率可使用基于索引的文件数据库,而不是关系数据库。LDAP协议集还规定了DN的命名方法、存
取控制方法、搜索格式、复制方法、URL格式、开发接口等
LDAP对于这样存储这样的信息最为有用,也就是数据须要从不一样的地点读取,可是不须要常常更新。
例如,这些信息存储在LDAP目录中是十分有效的:
l 公司员工的电话号码簿和组织结构图
l 客户的联系信息
l 计算机管理须要的信息,包括NIS映射、email假名,等等
l 软件包的配置信息
l 公用证书和安全密匙
何时该用LDAP存储数据
大多数的LDAP服务器都为读密集型的操做进行专门的优化。所以,当从LDAP服务器中读取数据的时候会比从专门为
OLTP优化的关系型数据库中读取数据快一个数量级。也是由于专门为读的性能进行优化,大多数的LDAP目录服务器
并不适合存储须要须要常常改变的数据。例如,用LDAP服务器来存储电话号码是一个很好的选择,可是它不能做为
电子商务站点的数据库服务器。
若是下面每个问题的答案都是“是”,那么把数据存在LDAP中就是一个好主意。
l 须要在任何平台上都能读取数据吗?
l 每个单独的记录项是否是每一天都只有不多的改变?
l 能够把数据存在平面数据库(flat database)而不是关系型数据库中吗?换句话来讲,也就是无论什么范式不
范式的,把全部东西都存在一个记录中(差很少只要知足第一范式)。
最后一个问题可能会唬住一些人,其实用平面数据库去存储一些关系型的数据也是很通常的。例如,一条公司员工
的记录就能够包含经理的登陆名。用LDAP来存储这类信息是很方便的。一个简单的判断方法:若是能够把保数据存
在一张张的卡片里,就能够很容易地把它存在LDAP目录里。
安全和访问控制
LDAP提供很复杂的不一样层次的访问控制或者ACI。因这些访问能够在服务器端控制,这比用客户端的软件保证数据的
安全可安全多了。
用LDAP的ACI,能够完成:
l 给予用户改变他们本身的电话号码和家庭地址的权限,可是限制他们对其它数据(如,职务名称,经理的登陆名,
等等)只有“只读”权限。
l 给予“HR-admins"组中的全部人权限以改变下面这些用户的信息:经理、工做名称、员工号、部门名称和部门号。
可是对其它域没有写权限。
l 禁止任何人查询LDAP服务器上的用户口令,可是能够容许用户改变他或她本身的口令。
l 给予经理访问他们上级的家庭电话的只读权限,可是禁止其余人有这个权限。
l 给予“host-admins"组中的任何人建立、删除和编辑全部保存在LDAP服务器中的与计算机主机有关的信息
l 经过Web,容许“foobar-sales"组中的成员有选择地给予或禁止他们本身读取一部分客户联系数据的读权限。这
将容许他们把客户联系信息下载到本地的笔记本电脑或我的数字助理(PDA)上。(若是销售人员的软件都支持LDAP,
这将很是有用)
l 经过Web,容许组的全部者删除或添加他们拥有的组的成员。例如:能够容许销售经理给予或禁止销售人员改变Web
页的权限。也能够容许邮件假名(mail aliase)的全部者不通过IT技术人员就直接从邮件假名中删除或添加用户。
“公用”的邮件列表应该容许用户从邮件假名中添加或删除本身(可是只能是本身)。也能够对IP地址或主机名加以
限制。例如,某些域只容许用户IP地址以192.168.200.*开头的有读的权限,或者用户反向查找DNS获得的主机名必须
为*.foobar.com。
LDAP目录树的结构
LDAP目录以树状的层次结构来存储数据。若是你对自顶向下的DNS树或UNIX文件的目录树比较熟悉,也就很容易掌握
LDAP目录树这个概念了。就象DNS的主机名那样,LDAP目录记录的标识名(Distinguished Name,简称DN)是用来读取
单个记录,以及回溯到树的顶部。后面会作详细地介绍。
为何要用层次结构来组织数据呢?缘由是多方面的。下面是可能遇到的一些状况:
l 若是你想把全部的美国客户的联系信息都“推”到位于到西雅图办公室(负责营销)的LDAP服务器上,可是你不想
把公司的资产管理信息“推”到那里。
l 你可能想根据目录树的结构给予不一样的员工组不一样的权限。在下面的例子里,资产管理组对“asset-mgmt"部分有完
全的访问权限,可是不能访问其它地方。
l 把LDAP存储和复制功能结合起来,能够定制目录树的结构以下降对WAN带宽的要求。位于西雅图的营销办公室须要每
分钟更新的美国销售情况的信息,可是欧洲的销售状况就只要每小时更新一次就好了。
刨根问底:基准DN
LDAP目录树的最顶部就是根,也就是所谓的“基准DN"。基准DN一般使用下面列出的三种格式之一。假定我在名为FooBar
的电子商务公司工做,这家公司在Internet上的名字是foobar.com。
o="FooBar, Inc.", c=US
(以X.500格式表示的基准DN)
在这个例子中,o=FooBar, Inc. 表示组织名,在这里就是公司名的同义词。c=US 表示公司的总部在美国。之前,通常
都用这种方式来表示基准DN。可是事物老是在不断变化的,如今全部的公司都已经(或计划)上Internet上。随着
Internet的全球化,在基准DN中使用国家代码很容易让人产生混淆。如今,X.500格式发展成下面列出的两种格式。
o=foobar.com
(用公司的Internet地址表示的基准DN)
这种格式很直观,用公司的域名做为基准DN。这也是如今最经常使用的格式。
dc=foobar, dc=com
(用DNS域名的不一样部分组成的基准DN)
就象上面那一种格式,这种格式也是以DNS域名为基础的,可是上面那种格式不改变域名(也就更易读),而这种格式
把域名:foobar.com分红两部分 dc=foobar, dc=com。在理论上,这种格式可能会更灵活一点,可是对于最终用户来讲
也更难记忆一点。考虑一下foobar.com这个例子。当foobar.com和gizmo.com合并以后,能够简单的把“dc=com"看成基
准DN。把新的记录放到已经存在的dc=gizmo, dc=com目录下,这样就简化了不少工做(固然,若是foobar.com和wocket.edu
合并,这个方法就不能用了)。若是LDAP服务器是新安装的,我建议你使用这种格式。再请注意一下,若是你打算使用活动
目录(Actrive Directory),Microsoft已经限制你必须使用这种格式。
更上一层楼:在目录树中怎么组织数据
在UNIX文件系统中,最顶层是根目录(root)。在根目录的下面有不少的文件和目录。象上面介绍的那样,LDAP目录也是
用一样的方法组织起来的。
在根目录下,要把数据从逻辑上区分开。由于历史上(X.500)的缘由,大多数LDAP目录用OU从逻辑上把数据分开来。OU
表示“Organization Unit",在X.500协议中是用来表示公司内部的机构:销售部、财务部,等等。如今LDAP还保留ou=这
样的命名规则,可是扩展了分类的范围,能够分类为:ou=people, ou=groups, ou=devices,等等。更低一级的OU有时用
来作更细的归类。例如:LDAP目录树(不包括单独的记录)可能会是这样的:
dc=foobar, dc=com
ou=customers
ou=asia
ou=europe
ou=usa
ou=employees
ou=rooms
ou=groups
ou=assets-mgmt
ou=nisgroups
ou=recipes
单独的LDAP记录
DN是LDAP记录项的名字
在LDAP目录中的全部记录项都有一个惟一的“Distinguished Name",也就是DN。每个LDAP记录项的DN是由两个部分
组成的:相对DN(RDN)和记录在LDAP目录中的位置。
RDN是DN中与目录树的结构无关的部分。在LDAP目录中存储的记录项都要有一个名字,这个名字一般存在cn(Common Name)
这个属性里。由于几乎全部的东西都有一个名字,在LDAP中存储的对象都用它们的cn值做为RDN的基础。若是我把最喜欢的
吃燕麦粥食谱存为一个记录,我就会用cn=Oatmeal Deluxe做为记录项的RDN。
l 个人LDAP目录的基准DN是dc=foobar,dc=com
l 我把本身的食谱做为LDAP的记录项存在ou=recipes
l 个人LDAP记录项的RDN设为cn=Oatmeal Deluxe
上面这些构成了燕麦粥食谱的LDAP记录的完整DN。记住,DN的读法和DNS主机名相似。下面就是完整的DN:
cn=Oatmeal Deluxe,ou=recipes,dc=foobar,dc=com
举一个实际的例子来讲明DN
如今为公司的员工设置一个DN。能够用基于cn或uid(User ID),做为典型的用户账号。例如,FooBar的员工Fran Smith
(登陆名:fsmith)的DN能够为下面两种格式:
uid=fsmith,ou=employees,dc=foobar,dc=com
(基于登陆名)
LDAP(以及X.500)用uid表示“User ID",不要把它和UNIX的uid号混淆了。大多数公司都会给每个员工惟一的登陆名,
所以用这个办法能够很好地保存员工的信息。你不用担忧之后还会有一个叫Fran Smith的加入公司,若是Fran改变了她的
名字(结婚?离婚?或宗教缘由?),也用不着改变LDAP记录项的DN。
cn=Fran Smith,ou=employees,dc=foobar,dc=com
(基于姓名)
能够看到这种格式使用了Common Name(CN)。能够把Common Name当成一我的的全名。这种格式有一个很明显的缺点就是:
若是名字改变了,LDAP的记录就要从一个DN转移到另外一个DN。可是,咱们应该尽量地避免改变一个记录项的DN。
定制目录的对象类型
你能够用LDAP存储各类类型的数据对象,只要这些对象能够用属性来表示,下面这些是能够在LDAP中存储的一些信息:
l 员工信息:员工的姓名、登陆名、口令、员工号、他的经理的登陆名,邮件服务器,等等。
l 物品跟踪信息:计算机名、IP地址、标签、型号、所在位置,等等。
l 客户联系列表:客户的公司名、主要联系人的电话、传真和电子邮件,等等。
l 会议厅信息:会议厅的名字、位置、能够坐多少人、电话号码、是否有投影机。
l 食谱信息:菜的名字、配料、烹调方法以及准备方法。
由于LDAP目录能够定制成存储任何文本或二进制数据,到底存什么要由你本身决定。LDAP目录用对象类型
(object classes)的概念来定义运行哪一类的对象使用什么属性。在几乎全部的LDAP服务器中,你都要根据
本身的须要扩展基本的LDAP目录
的功能,建立新的对象类型或者扩展示存的对象类型。
LDAP目录以一系列“属性对”的形式来存储记录项,每个记录项包括属性类型和属性值(这与关系型数据库
用行和列来存取数据有根本的不一样)。下面是我存在LDAP目录中的一部分食谱记录:
dn: cn=Oatmeal Deluxe, ou=recipes, dc=foobar, dc=com
cn: Instant Oatmeal Deluxe
recipeCuisine: breakfast
recipeIngredient: 1 packet instant oatmeal
recipeIngredient: 1 cup water
recipeIngredient: 1 pinch salt
recipeIngredient: 1 tsp brown sugar
recipeIngredient: 1/4 apple, any type
请注意上面每一种配料都做为属性recipeIngredient值。LDAP目录被设计成象上面那样为一个属性保存多个值的,
而不是在每个属性的后面用逗号把一系列值分开。
由于用这样的方式存储数据,因此数据库就有很大的灵活性,没必要为加入一些新的数据就从新建立表和索引。更
重要的是,LDAP目录没必要花费内存或硬盘空间处理“空”域,也就是说,实际上不使用可选择的域也不会花费你
任何资源。
做为例子的一个单独的数据项
让咱们看看下面这个例子。咱们用Foobar, Inc.的员工Fran Smith的LDAP记录。这个记录项的格式是LDIF,用来
导入和导出LDAP目录的记录项。
dn: uid=fsmith, ou=employees, dc=foobar, dc=com
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: foobarPerson
uid: fsmith
givenname: Fran
sn: Smith
cn: Fran Smith
cn: Frances Smith
telephonenumber: 510-555-1234
roomnumber: 122G
o: Foobar, Inc.
mailRoutingAddress: fsmith@foobar.com
mailhost: mail.foobar.com
userpassword: {crypt}3x1231v76T89N
uidnumber: 1234
gidnumber: 1200
homedirectory: /home/fsmith
loginshell: /usr/local/bin/bash
属性的值在保存的时候是保留大小写的,可是在默认状况下搜索的时候是不区分大小写的。某些特殊的属性
(例如,password)在搜索的时候须要区分大小写。
让咱们一点一点地分析上面的记录项。
dn: uid=fsmith, ou=employees, dc=foobar, dc=com
这是Fran的LDAP记录项的完整DN,包括在目录树中的完整路径。LDAP(和X.500)使用uid(User ID),不要
把它和UNIX的uid号混淆了。
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: foobarPerson
能够为任何一个对象根据须要分配多个对象类型。person对象类型要求cn(common name)和sn(surname)
这两个域不能为空。persion对象类型容许有其它的可选域,包括givenname、telephonenumber,等等。
organizational Person给person加入更多的可选域,inetOrgPerson又加入更多的可选域(包括电子邮件信息)。
最后,foobarPerson是为Foobar定制的对象类型,加入了不少定制的属性。
uid: fsmith
givenname: Fran
sn: Smith
cn: Fran Smith
cn: Frances Smith
telephonenumber: 510-555-1234
roomnumber: 122G
o: Foobar, Inc.
之前说过了,uid表示User ID。当看到uid的时候,就在脑壳里想想“login"。
请注意CN有多个值。就象上面介绍的,LDAP容许某些属性有多个值。为何容许有多个值呢?假定你在用
公司的LDAP服务器查找Fran的电话号码。你可能只知道她的名字叫Fran,可是对人力资源处的人来讲她的
正式名字叫作Frances。由于保存了她的两个名字,因此用任何一个名字检索均可以找到Fran的电话号码、
电子邮件和办公房间号,等等。
mailRoutingAddress: fsmith@foobar.com
mailhost: mail.foobar.com
就象如今大多数的公司都上网了,Foobar用Sendmail发送邮件和处理外部邮件路由信息。Foobar把全部用户
的邮件信息都存在LDAP中。最新版本的Sendmail支持这项功能。
Userpassword: {crypt}3x1231v76T89N
uidnumber: 1234
gidnumber: 1200
gecos: Frances Smith
homedirectory: /home/fsmith
loginshell: /usr/local/bin/bash
注意,Foobar的系统管理员把全部用户的口令映射信息也都存在LDAP中。FoobarPerson类型的对象具备这
种能力。再注意一下,用户口令是用UNIX的口令加密格式存储的。UNIX的uid在这里为uidnumber。提醒你一下,
关于如何在LDAP中保存NIS信息,有完整的一份RFC。在之后的文章中我会谈一谈NIS的集成。
LDAP复制
LDAP服务器可使用基于“推”或者“拉”的技术,用简单或基于安全证书的安全验证,复制一部分或者所
有的数据。
例如,Foobar有一个“公用的”LDAP服务器,地址为ldap.foobar.com,端口为389。Netscape Communicator
的电子邮件查询功能、UNIX的“ph"命令要用到这个服务器,用户也能够在任何地方查询这个服务器上的员工
和客户联系信息。公司的主LDAP服务器运行在相同的计算机上,不过端口号是1389。
你可能即不想让员工查询资产管理或食谱的信息,又不想让信息技术人员看到整个公司的LDAP目录。为了解决
这个问题,Foobar有选择地把子目录树从主LDAP服务器复制到“公用”LDAP服务器上,不复制须要隐藏的信息。
为了保持数据始终是最新的,主目录服务器被设置成即时“推”同步。这些种方法主要是为了方便,而不是安全,
由于若是有权限的用户想查询全部的数据,能够用另外一个LDAP端口。
假定Foobar经过从奥克兰到欧洲的低带宽数据的链接用LDAP管理客户联系信息。能够创建从ldap.foobar.com:1389
到munich-ldap.foobar.com:389的数据复制,象下面这样:
periodic pull: ou=asia,ou=customers,o=sendmail.com
periodic pull: ou=us,ou=customers,o=sendmail.com
immediate push: ou=europe,ou=customers,o=sendmail.com
“拉”链接每15分钟同步一次,在上面假定的状况下足够了。“推”链接保证任何欧洲的联系信息发生了变化就
当即被“推”到Munich。
用上面的复制模式,用户为了访问数据须要链接到哪一台服务器呢?在Munich的用户能够简单地链接到本地服务
器。若是他们改变了数据,本地的LDAP服务器就会把这些变化传到主LDAP服务器。而后,主LDAP服务器把这些变化
“推”回本地的“公用”LDAP服务器保持数据的同步。这对本地的用户有很大的好处,由于全部的查询(大多数是读)都在本地的服务器上进行,速度很是快。当须要改变信息的时候,最终用户不须要从新配置客户端的软件,由于LDAP目录服务器为他们完成了全部的数据交换工做。前端