LDAP入门手册1.LDAP概念与概览如果你已经知道了LDAP是什么,它有什么好处,并且也知道了Schemas,objectClasses,Attributes,matchingRules,Operationalobjects以及所有诸如此类的概念——那就可以跳过本章。但是如果你不想盲目按照“HOWTOs这样的指南”去做事情,那么你必须理解本章材料中的绝大数内容。LDAP和X.500在术语上渊源颇深。一些术语很重要,另一些术语则无足轻重。为了便于记忆,我们创建了一个词汇表,我们所介绍的术语要么很重,要么它们在各类文档中经常出现。1.1LDPA简史(ABrieHistoryofLDAP)1.2LDAP概述(LDAPOverview)1.3LDAP与RDBMS比较(LDAPvs.RDBMS)1.3.1LDPA用途总结(LDAPUsageSummary)1.4LDAP数据(对象)模型(LDAPData(Object)Model)1.4.1对象树结构(ObjectTreeStructure)1.4.2属性(Attributes)1.4.3对象类(ObjectClasses)1.4.4记述条目树并添加数据(DescribingtheTreeandAddingData)1.4.5遍历目录信息树(NavigatingtheTree)1.5LDAP复制和引用(LDAPReplicationandReferrals)1.5.1引用(Referrals)1.5.2复制(Replication)LDAP中大小写敏感问题的简单说明:这个问题很混乱,-是的,我们发现这事确实很混乱。事实告诉我们这方面存在很多混乱的认识。在LDAP中,只有密码(passwords)和某些受限于匹配规则(matchingRule)的特定属性(极其少见)要求区分大小写。在本文和其他文档中你会看到objectclasses或objectClasses甚至ObjectClasses这样的词汇,但它们都能工作。你有足够的理由担心大小写的问题,如果真的存在大小写敏感的问题,那在开始学习LDAP的六年时间中(开个玩笑,只需要四年)每次按下键盘时都会出一身汗,生怕输错某些东西的名称。1.1LDPA简史(ABriefHistoryofLDAP)曾经,在模糊和久远的过去(上世纪70年代末到80年代初),ITU(国际电信联盟-InternationalTelecommunicationUnion)开始了X.400系列的email邮件标准的制定工作。Email标准需要一个名称(names,以及其他信息)的目录,这个目录可以通过网络以一种层级(hierarchicalfashion)的方式进行访问,这种方式与所熟悉的DNS架构有所不同。这种基于全球网络的目录需求导致ITU开发X.500系列标准,以及尤为特别的X.519标准,这个标准定义了DAP(目录访问协议DirectoryAccessProtocol),该协议用于访问网络目录服务。X.400和X.500系列标准被打包在整个OSI中,非常庞大、臃肿并严重消耗资源,这就是ITU标准的现实。时间很快到了上世纪90年代初期,IETF看到了访问全球目录服务的需求(最初也是和ITU制定email标准需要目录服务一样的原因),但是没有全部采用让人感觉头大的OSI协议,而是开启轻量级目录服务访问协议(LDAP)的制定工作。LDAP被设计为提供与X.519标准一样的功能,但使用TCP/IP协议——同时仍然允许与基于X.500协议的目录进行交互工作(inter-working)。实际上,与X.500(DAP)的交互工作(inter-working)和映射(Maping)一直是IETFLDAPRFCs系列标准的组成部分。注:IETF国际互联网工程任务组(TheInternetEngineeringTaskForce,简称IETF)在LDAP规范中,很多非常纠结的问题主来自于目录根(directoryroot)的命名规约,这个问题可以追溯到X.500的交互工作以及全球目录的需求。LDAP–大体上–与DPA的不同之处如下:1.TCP/IP用于LDAP-DAP使用OSI作为传输/网络层协议。2.在功能上的一些缩减–在X.519中一些模糊的、重复的和很少使用的功能被以安静(quietly)和仁慈(mercifully)的方式删除。在LDAP世界中,LDAP目录信息树(DIT-DirectoryInformationTree)的顶层条目(topentry)被称为根(root),基(base)或后缀(suffix),不同文档中叫法不同,主要取决于文档的作者,文档编写的时代以及其他我们所不知道的原因。术语目录服务器根条目(RootDSE-RootDirectoryServerEntry)定义了一种超级根(superroot),该超级根包括所有由LDAP服务器所支持的目录信息树以及操作型对象(operationalobjects,主要用于提供目录服务器自身信息,或用于控制目录服务自身行为的对象,通常不对外暴露)。在本文中,关于根(root,suffix或base)看法可以采取两种方式中的一种。有人把根看作一种超然存在的事物,已经超出了一般人需要理解的范围,并且以一种固有的方式来看待它,如同代代相传的处理方式而无需解释。相反,其他人采用了另一种极端的方式来看待它,通常伴随着对ITU和IETF这一对权威组织的失望、愤怒和诅咒。我们的建议-除非你需要使目录全球可用而将根(root)定为官方名称的ou,否则没有必要在这方面花费更多时间。现在来看看这个严重的问题。这种纠结来自于ITU制定X.500时最初设定,并值得称赞的目标—这一点很明显也被IETF所继承—有一个全球层级的目录,而且还不会与DNS系统相异。在这种情况下,全球性对外暴露的根(root,suffix或base)发挥着一个非常重要的作用—它应该是全球唯一的。回到我们的建议,除非在将来的某个阶段要将目录全球对外——那就忘记这事,按照你的需要进行根的命名——有某种含义或者只要你愿意也可以很幽默。如果你现在或者未来有全球化的志向,那么请继续阅读下面段落。X.500以ou=organisationname,c=countrycode方式作为root的标准,比如ou=ExampleInc.,c=us,对于为何这样通过——或许——是在星期四或者某个时间冒出这样的一个好主意。IETF选择使用像dc=example,dc=com这样的域名结构的部分原因是由于DNS域名已经全球唯一,部分原因是基于一个华而不实的论调——给定一个DNSSRV记录或者一个LDAP服务器名——你就能够判断出后缀。因而,如果LDAP服务器的名字是ldap.example.com(直接得到,或者通过SRVRR得到),那么就可以推断出后缀可能是dc=example,dc=com。不是十分靠谱。而如果你还没有一个域名——那就非常糟糕了。如果你有多个域名,那么选择哪一个域名——这个问题无关紧要(你甚至可以使用所有的域名),因为每个域名都是唯一的。总之,选择一种最适合你的方式来确定root。如果你确实想让多个目录信息树(DIT)部署在同一个服务器上,你需要定义DIT格式并使用在DIT之间使用引用(referral)。下图列出了全部三种合法的root条目。其中的两种可以全球唯一的,剩下的一种不是全球唯一的。3.在LDAP中用文本表达方式(用于LDAPURLs和查找过滤器)替换了部分ASN.1(X.519)的表达方式。对于这一点,IETF受到了很多赞扬,但遗憾的是,很多ASN.1标记仍然被保留。1.2LDAP概述(Overview)技术上讲,LDAP只是一个定义目录数据访问方法的协议。必然地,LDAP就需要定义和描述目录服务中数据如何表达(数据(信息)模型)。最后,它还需要定义目录服务如何加载(导入)和备份(导出)数据(使用LDIF)。LDAP没有定义如何存储和操作数据。数据的存储和访问方法是尽可能标准化的自动处理过程,并且通常由所有特定LDAP实现的后台模块(通常会使用某种形式的事务数据库)处理。LDAP定义了4个模型,下面将会有简短描述——你可以很快就忘了这些模型,因为它们对理解LDAP没有太多帮助。1.信息模型(InformationModel):我们更倾向于使用术语数据模型,我们的观点是数据模型这个术语更加直观和易于理解。数据(或信息)模型定义如何在LDAP系统中表达信息或数据。它也可能包括数据的实际存储方法,但这个问题已经超出了上述LDAP标准的范围。2.命名模型(NamingModel):命名模型定义所有诸如'dc=example,dc=com'这样你在LDAP系统中偶然发现的名称.这里,我们特别坚持的命名规范,因为这些术语被广泛使用。3.功能模型(FunctionalModel):当你在读取、查找、写或者修改LDAP,那么你就在使用功能模型。4.安全模型(SecurityModel):你能够以合适的粒度来控制谁能对哪些数据做什么。这是一件复杂且强大的事情.我们将以循序渐进的方式来引入相关的概念并有专门的一章来阐述它。在开始的时候——请先忘记安全。LDAP标准的范围如下图所示,红色(1,2,3,4)表示东西是在协议中定义范围之内(定义LDAP的各个RFC)。而在黑色框(或者绿色,黄色和紫色框)和连接到Databases的黑色线是“天然存在的(automagical)”,并且不在标准的范围之内。这里先简短介绍一下每个组件,后续章节中会有详细的阐述,而这里首先介绍4个要点:1.LDAP没有定义数据如何被存储,只是定义数据如何被访问。但是大多数LDAP实现使用一个标准的数据库作为后端,而OpenLDAP这样的LDAP实现还提供了选择后端数据库支持。2.当你与LDAP服务器进行对话时,你不知道数据来自哪里:其实关于标准的整点(wholepoint)就是隐藏这种细节。在理论上,数据可以来自于一个或者多个本地数据库,也可能来自于一个或者多个X.500服务(尽管这种情况近来越来越罕见)。在哪以及如何访问数据是实现细节,而且只有在定义LDAP服务器配置选项时这些问题才显得重要。3.记住两个概念——访问LDAP服务和运转LDAP服务——在头脑中要将两个概念清晰地分开。当你设计基于目录的系统时,要明确你想要目录做什么(数据的组织)并忘记如何实现。然后在第二阶段才会明确数据在哪,以及在什么地方存储这些数据——LDAP配置过程。4.很多商业数据库产品提供了关系型或其他数据库类型的LDAP视图(一种LDAP的包装或抽象)。1.3LDAP与Database的比较LDAP服务的特点是“一次写入,多次读取”。也就是说,在LDAP服务中存储的数据通常不希望每次访问时都被更改。为了说明这一点:LDAP不适合维护银行交易记录,因为,从业务本质上看,这些交易记录几乎每次访问都会被更改。但LDAP非常适合维护银行分支机构,开业时间,员工等这样的数据。这些数据很少变化。读优化我们还没有弄清楚在“一次写入,多次读取”这个短句中,什么情况才算多次?使用LDAP还是使用经典的面向事务的关系型数据库,比如SQLite,MYSQL,PostGreSQL的界线是什么呢?如果我们每个瞬间的访问都进行了更新操作,这是一个合理的LDAP应用吗?还是说每1000或者100万次访问才进行一次更新才是合理的LDAP应用?关于这话题,上面的文字论述略显单薄,并且主要是为了引起读者的重视,像地址本这样的LDAP应用也会变更数据,也许,会经常变化。这个问题没有简单的答案,下面的观点可能会有用:1.写数据时的性能问题取决于对索引的更新。索引(为了更快的读)设置的越多,就希望目录被更新的时候越少。“读:写”至少是1000:1,对于重度读取优化的LDAP目录,这一比率还会更高。2.在每次更新的时候,LDAP的复制将会产生倍增的事务,因此你要使实际更新的负荷降至最低(1000:1或者更高)。3.如果一次要更新的数据量很庞大(比方说大于10