LDAP模式设计
LDAP 手册入门 ,1. LDAP 概念与概览如果你已经知道了LDAP 是什么,它有什么好处,并且也知道了Schemas, objectClasses, 以及所有诸如此
LDAP 手册
入门
,1. LDAP 概念与概览
如果你已经知道了LDAP 是什么,它有什么好处,并且也知道了Schemas, objectClasses, 以及所有诸如此类的概念——那就可以跳过本章。但是如果你不想盲目按照“HOWTOs 这样的指南”去做事情,那么你必须理解本章材料中的绝大数内容。
LDAP 和X.500在术语上渊源颇深。一些术语很重要,另一些术语则无足轻重。为了便于记忆,我们创建了一个词汇表,我们所介绍的术语要么很重,要么它们在各类文档中经常出现。
LDAP 中大小写敏感问题的简单说明:这个问题很混乱,- 是的,我们发现这事确实很混乱。事实告诉我们这方面存在很多混乱的认识。在LDAP 中,只有密码(passwords )和某些受限于匹配规则(matchingRule )的特定属性(极其少见)要求区分大小写。在本文和其他文档中你会看到 objectclasses 或objectClasses 甚至ObjectClasses 这样的词汇,但它们都能工作。你有足够的理由担心大小写的问题,如果真的存在大小写敏感的问题,那在开始学习LDAP 的六年时间中(开个玩笑,只需要四年)每次按下键盘时都会出一身汗,生怕输错某些东西的名称。
,1.1 LDPA简史(A Brief Historyof LDAP)
曾经,在模糊和久远的过去(上世纪70年代末到80年代初),ITU (国际电信联盟- International Telecommunication Union)开始了X.400系列的email 邮件标准的制定工作。Email 标准需要一个名称(names ,以及其他信息)的目录,这个目录可以通过网络以一种层级(hierarchical fashion )的方式进行访问,这种方式与所熟悉的DNS 架构有所不同。
这种基于全球网络的目录需求导致ITU 开发X.500系列标准,以及尤为特别的X.519标准,这个标准定义了DAP (目录访问协议Directory Access Protocol),该协议用于访问网络目录服务。
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 )一直是IETF LDAP RFCs系列标准的组成部分。
注: IETF 国际互联网工程任务组(The Internet Engineering Task Force,简称IETF )
在LDAP 规范中,很多非常纠结的问题主来自于目录根 (directory root )的命名规约,这个问题可以追溯到X.500的交互工作以及全球目录的需求。
,
LDAP –大体上–与DPA 的不同之处如下:
1. TCP/IP用于LDAP-DAP 使用OSI 作为传输/网络层协议。
2. 在功能上的一些缩减 – 在X.519中一些模糊的、重复的和很少使用的功能被以安静
(quietly )和仁慈(mercifully )的方式删除。
,3. 在LDAP 中用文本表达方式(用于LDAP URLs和查找过滤器)替换了部分ASN.1(X.519)的表达方式。对于这一点,IETF 受到了很多赞扬,但遗憾的是,很多ASN.1标记仍然被保留。
1.2 LDAP 概述(Overview )
技术上讲,LDAP 只是一个定义目录数据访问方法的协议。必然地,LDAP 就需要定义和描述目录服务中数据如何表达(数据(信息)模型)。最后,它还需要定义目录服务如何加载(导入)和备份(导出)数据(使用LDIF )。LDAP 没有定义如何存储和操作数据。数据的存储和访问方法是尽可能标准化的自动处理过程,并且通常由所有特定LDAP 实现的后台模块(通常会使用某种形式的事务数据库)处理。
LDAP 定义了4个模型,下面将会有简短描述——你可以很快就忘了这些模型,因为它们对理解LDAP 没有太多帮助。
1. 信息模型(Information Model):我们更倾向于使用术语数据模型,我们的观点是数据模型这个术语更加直观和易于理解。数据(或信息)模型定义如何在LDAP 系统中表达信息或数据。它也可能包括数据的实际存储方法,但这个问题已经超出了上述LDAP 标准的范围。
2. 命名模型(Naming Model):命名模型定义所有诸如 'dc=example,dc=com'这样你在LDAP 系统中偶然发现的名称. 这里,我们特别坚持的命名规范,因为这些术语被广泛使用。
3. 功能模型(Functional Model):当你在读取、查找、写或者修改LDAP ,那么你就在使用功能模型。
4. 安全模型(Security Model): 你能够以合适的粒度来控制谁能对哪些数据做什么。这是一件复杂且强大的事情. 我们将以循序渐进的方式来引入相关的概念并有专门的一章来阐述它。在开始的时候——请先忘记安全。
LDAP 标准的范围如下图所示,红色(1,2,3,4)表示东西是在协议中定义范围之内(定义LDAP 的各个RFC )。而在黑色框(或者绿色,黄色和紫色框)和连接到Databases 的黑色线是“天然存在的(automagical )”,并且不在标准的范围之内。
,
这里先简短介绍一下每个组件,后续章节中会有详细的阐述,而这里首先介绍4个要点:
1. LDAP 没有定义数据如何被存储,只是定义数据如何被访问。但是大多数LDAP 实现使用一个标准的数据库作为后端,而OpenLDAP 这样的LDAP 实现还提供了选择后端数据库支持。
2. 当你与LDAP 服务器进行对话时,你不知道数据来自哪里:其实关于标准的整点(whole point )就是隐藏这种细节。在理论上,数据可以来自于一个或者多个本地数据库,也可能来自于一个或者多个X.500服务(尽管这种情况近来越来越罕见)。在哪以及如何访问数据是实现细节,而且只有在定义LDAP 服务器配置选项时这些问题才显得重要。
3. 记住两个概念——访问LDAP 服务和运转LDAP 服务——在头脑中要将两个概念清晰地分开。当你设计基于目录的系统时,要明确你想要目录做什么(数据的组织)并忘记如何实现。然后在第二阶段才会明确数据在哪,以及在什么地方存储这些数据——LDAP 配置过程。
4. 很多商业数据库产品提供了关系型或其他数据库类型的LDAP 视图(一种LDAP 的包装或抽象)。
1.3 LDAP 与Database 的比较
LDAP 服务的特点是“一次写入,多次读取”。也就是说,在LDAP 服务中存储的数据通常不希望每次访问时都被更改。为了说明这一点:LDAP 不适合维护银行交易记录,因为,从业务本质上看,这些交易记录几乎每次访问都会被更改。但LDAP 非常适合维护银行分支机构,开业时间,员工等这样的数据。这些数据很少变化。
,读优化
我们还没有弄清楚在“一次写入,多次读取”这个短句中,什么情况才算多次?
使用LDAP 还是使用经典的面向事务的关系型数据库,比如SQLite,MYSQL ,PostGreSQL 的界线是什么呢?如果我们每个瞬间的访问都进行了更新操作,这是一个合理的LDAP 应用吗?还是说每1000或者100万次访问才进行一次更新才是合理的LDAP 应用?
关于这话题,上面的文字论述略显单薄,并且主要是为了引起读者的重视,像地址本这样的LDAP 应用也会变更数据,也许,会经常变化。
这个问题没有简单的答案,下面的观点可能会有用:
1. 写数据时的性能问题取决于对索引的更新。索引(为了更快的读)设置的越多,就希望目录被更新的时候越少。“读:写”至少是1000:1,对于重度读取优化的LDAP 目录,这一比率还会更高。
2. 在每次更新的时候,LDAP 的复制将会产生倍增的事务,因此你要使实际更新的负荷降至最低(1000:1或者更高)。
3. 如果一次要更新的数据量很庞大(比方说大于100,000条),尽管索引设置的数量很少,也会导致严重的性能问题,因此你应尽可能地减少这种更新(10,000:1)。
4. 如果数据量相对较少(比方使用说小于1000条),索引数量适中,而且也没有使用目录复制(replication ),我们看不出有哪些足够的理由不使用LDAP ,这种情况下,对LDAP 的使用非常接近一个基于事务的系统,也就是说,每5-10次读访问伴随一个“写闭环(write cycle)”(LDAP 中对更新(modify)的专门术语)。
5. 我们对这个问题的确定性的答案表示怀疑:读写比率是42!
数据结构的可见性
支持LDAP 的目录系统使用基本元素(Primitives :LDAP协议中的元素) 来访问数据目录,基本元素使用一种通用的数据模型,这种数据模型来自对各种数据物理结构的抽象。基本元素假定了一个对象的数据模型而不关心该对象的实际数据结构。实际上,LDAP 的简单性也是来自于这个特性。特定的LDAP 实现将在其后端(back-end )功能中以一种完全“全能自动化(automagical )”的方式来完成LDAP 基本元素与数据的物理结构之间的映射。
与此形成鲜明的对照就是SQL ,在SQL 查询中可用于询问数据是否完整,以及表(table )或连接(joins )等数据结构的细节。
数据同步和复制
关系型和事务型数据库针对写/更新闭环过程中如何保证数据一致性做到了极致,它们采用类似事务,锁,回滚以及其他的一些手段。对于这种类型的数据库而言,这些需求非常重要而且必须满足。这种极致的数据同步在数据向多个主机或服务复制时也得以延续和保证,因此,在任何时候,所有数据视图都会保持一致。
在LDAP 主(master )服务器和LDAP 从(slave )服务器(或多主环境下的对等(peer )服务器)中的数据使用一种简单的异步(asynchronous )数据复制处理。这种方式的副作用就是使主服务器和从服务器(或对等服务器)在数据复制闭环过程中失去了数据的同步性。在这个过程中(通常时间很短),对主服务器和从服务器的查询可能会得到不同的结果。如
,果这种差异会导致系统无法正常运作,那么LDAP 不适合这种应用。但是如果在财务部门的LDAP 服务器中看到了BOB Smith,而在销售部门的另一台LDAP 服务其中延迟了几秒钟才看到BOB Smith,又有什么打紧呢?其实,很多应用都可以归于此类。
注意: 现代的LDAP 实现,尤其是支持多主服务器(Multi-master )配置的LDAP 实现,在复制更新方面变得日益精致。另外,高速通信网络也使复制操作的速度得以很大提高,但这些只是缩短了两个系统之间进行数据同步的时间窗口,并没有消除LDAP 的数据同步行为——尽管大多数现代化的LDAP 实现已经将数据同步的时间缩短为亚秒级(sub-second )。
1.3.1 LDAP用途总结
那么LDAP (目录)的优点是什么呢?而且为什么一个理性思考的人要用目录呢?
在试图回答这个问题之前,让我们先消除性能方面的战术性问题。通常,关系数据库系统(RDBMS )的性能仍然显著高于LDAP 实现。随着第二代目录服务器的发展,二者之间的性能差距显著缩短,但关系型数据库的性能仍然高于LDAP 。假如你只作同种类型的比较(量测网络发起的交易),这种差异就会变得更加微不足道。当然,除非你每次操作都更新一个高度索引化的属性——这种情况下,你会得到你想要(或不想要)的结果。
因此,我们为什么要使用LDAP ?这里我们列出了一些关键特性,这些特性值得付出更高代价。
1. LDAP 能够以标准的方式访问远程及本地数据。因而就可能做到替换LDAP 的实现而不影响数据的外部访问接口。关系型数据库提供了标准的本地化数据访问方法,比如SQL ,但是远程数据访问接口则不同数据库产品各有不同。
2. 因为LDAP 使用了标准化的数据访问方法,这样客户端和服务器可以有不同的供应商来源。在这一点上的扩展,LDAP 可以用于为面向事务的数据库建立抽象的数据视图,也就是说,出于运行用户查询的目的,允许用户透明地(通过LDAP 查询)变化后台的事务型数据库供应商。
3. LDAP 提供一种将数据移动到多个位置而不影响任何外部数据访问的方法。通过使用“引用”这种方法,只需要改变配置参数,LDAP 的数据可以被移动到其他的LDAP 服务器上。
4. LDAP 系统能够以可选的方式配置为向一个或者多个应用复制数据,而无需增加代码或变更外部访问的数据。
这些特性专门聚焦于LDAP 数据访问标准化的内涵,而且没有考虑读写比率,正如前面所提到的,读写比率依赖于所维护的操作型索引的数量。上面的这些特性暗示出不建议用LDAP 系统进行事务处理——尽管已有一些迹象表明有些LDAP 实现具备事务的能力。
1.4 LDAP数据(对象)模型
支持LDAP 的目录系统使用一个数据模型来表示层级的数据对象。但这意味着LDAP 是一个面向对象的数据库。正如上面所指出的那样,LDAP 本身是一个协议,它只规定如何访
,问LDAP 服务,而没有定义数据如何存储——而是由操作型的基本元素(读,删除,修改)按照模型(描述/表示)对“类似对象”(大多数时候)的数据进行操作
1.4.1 对象树结构
本节定义LDAP 的要素。如果你理解了本节内容和各种不同的术语以及术语之间的相互关系,那么你就真的理解来了LDAP 。
数据在LDAP 系统中以层级对象的方式表达,层级中的每个数据都被称作条目。整个树结构被称作目录信息树(DIT-。树的顶端通常被称为根(root ,也被称为基(base )或者后缀(suffix ))。
树中的每个条目(entry )都有一个父条目(对象)以及0或多个子条目(对象)。每个子条目(对象)与其父条目的其他子条目是同级关系。
每个条目都由一个或者多个构成(是一个或者多个的实例)。Objectclasses 包含0或者多个属性()属性有名字(而且有时有缩写或者别名)以及通常会包含数据(至少!)。
objectClasses 及其属性的特性以ASN.1(抽象语法标记1)定义方式进行描述。
现在你知道了关于LDAP 的每件事情。剩下的就是一些细节了——LDAP 有很多细节,但是这里只介绍核心部分。
下图表明了这些概念之间的关系:

LDAP DIT Information (Data) Model
,总结:
1. 每个条目(Entry )都由一个或者多个对象类构成(objectClasses )。
2. 每个对象类都有一个名字(name )。
3. 每个属性(Attribute )都有一个名字,属性通常都含有数据,并且属性是对象类(object class )的组成成员。
1.4.2 属性(Attributes )
每个属性都有一个名字并且正常情况下会含有数据。属性通常与一个或者多个对象类(ObjectClasses )相关联。属性有很多有趣的特性:
1. 所有的属性都是一个或者多个的对象类(objectclass )的成员。
2. 每个属性都定义了它所包含数据的数据类型(data type).
3. 按照ASN.1的描述方式,作为对象类objectclass 的成员,属性可以定义为可选(修饰关键词为MAY )还是必须(修饰关键词为MUST )。一个属性在某个类对象中是可选属性,但在其他对象类中可能是必须属性,这件事情主要由类对象来决定。
有人显然已经看出,在本文中,属性可以被从所有地方自由地选择——这种困惑首先来自于大多数属性的可选特性。LDAP 允许以“拼接”的方式来构成一个条目。找到你想要的属性,包括该属性的类对象,以及希望所有其他不想在类对象中使用的属性都是可以设置的。
4. 属性可以有单值或者多值(正如ASN.1定义所描述的那样)。单值意味着只有一个数据值可以用来表示那个属性。多值意味着属性可以有一个或者多个数据值。比如说,如果某个属性表示的是email 地址,那么就可能有一个,两个或者500个值——这只是目录设计中处理email 别名的多种方法中的一种方法而已。属性默认设置是多值(允许有多个值)。
5. Attributes 属性都有名称,并且有时后会有别名或者缩略名(正如ASN.1定义所描述的那样),比如,commonName 是称为person 的对象类(也可以是许多其他对象类)的一个成员属性,同时该属性有一个缩略名cn 。无论commonName 还是cn 都被用于指向同一个属性。
6. 在树状层级中的每个具体层次,条目属性中包含的数据都可以用于唯一标识该条目。可以用条目的一个属性来标识条目的唯一性,也可以用两个以上属性的组合来表示条目的唯一性。
假如你有一个传统纸质的名册目录,包含了名字,电话号码,地址,喜欢的饮料(对,是一个标准属性)等等。为了唯一识别一个特定的条目,你可能选择使用人的名字(commonName 或cn 属性)。如果人名在LDAP 目录中不是唯一的,比如'Bob Smith',那么查找'Bob Smith'将会返回目录中所有包含名字为'Bob Smith'的条目,而且用户必须要选择他所要查找的人。对于读取或者查询的操作,这种情况可能会可以接受,甚至值得称道。因为在面向人类的界面中使用了易读的信息——人名。