OpenLDAP 2.4版本 快速入门
本文内容是自己通过官网文档、网络和相关书籍学习和理解并整理成文档,其中有错误或者疑问请在文章下方留言。
一、Introduction to OpenLDAP Directory Services
1、What is a directory service?
目录是一个专门的数据库,专门用于搜索和浏览,另外也支持基本的查询和更新功能。
Note:目录被一些人视为仅仅是一个优化了读取操作的数据库。这一定义,往最好了说,是过于简单化了。
目录往往包含描述性的,基于属性的信息和支持先进的过滤功能。目录一般不支持被设计用于处理大批量复杂更新的数据库管理系统的复杂交易或回滚计划。目录的更新通常是简单的全有或全无的变更,如果变更被允许的话。目录一般都调整为快速反应大批量查找或搜索操作. 它们可能有能力复制广泛的信息,以提高可用性和可靠性,同时降低响应时间. 当复制目录信息时,临时的复制品之间的不一致性可能可以接受,只要矛盾及时得到解决。
有许多不同的方式提供一个目录服务。不同的方法允许不同种类的信息存储在目录中,对于信息可以如何转发,查询和更新,以及如何保护未经授权的访问,等有不同的要求。一些目录服务是本地的,提供服务给一个限制的范围内(例如,一台机器的finger服务)。其他服务是全球性的,提供服务给更广泛的范围内(例如,整个互联网。全球服务通常是分散的,也就是说,它们包含的数据是分散在许多机器,所有这些合作来提供目录服务。通常情况下一个全球性的服务定义了一个统一的名字空间,提供同一视图的数据,无论您身在何处和数据本身有何关系。
一个网站目录,如开放式目录管理项目http://dmoz.org提供。就是一个很好的目录服务例子。这些服务把网页目录化,并专门设计用于支持浏览和搜索。
虽然有人认为Internet Domain Name System(DNS)是一个全球分布式目录服务的例子,但是DNS是不能浏览或搜寻的。它更准确的描述是一个全球型的分布查找服务。
2、What is LDAP?
LDAP (Lightweight Directory Access Protocol ,LDAP) 表示轻量级目录访问协议。顾名思义,它是一个轻量级协议,用于访问目录服务,特别是基于X.500的目录服务。LDAP运行在TCP/IP或其他面向连接的传输服务。LDAP是一个IETF标准传输协议,在轻量级目录访问协议(Lightweight Directory Access Protocol ,LDAP) RFC4510中被指定。
What kind of information can be stored in the directory? 那么,什么类型的信息能被存储在目录里? LDAP的information model是基于entries(后面我们叫条目)。一个条目是一个属性的集合,它有一个全球唯一的标识名(DN)。DN用于明确条目。每个条目的属性有一个类型和一个或多个值。该类型通常是助记忆的字符串,像 "cn" 是通用名称(我理解为人的名字),或“mail”就是电子邮件地址。它值的语法依赖于属性类型。例如,cn 这个属性,我们一般表示人的名字,比如 "Bab Jensen"。mail 属性可以包含值"[email protected]"。jpegPhoto 属性可以包含一张以JPEG (binary)格式的照片。
How is the information arranged? 在LDAP,目录的条目被排列在一个层次树状结构。Openldap(ldap开源集中帐号管理架构的实现,被广大互联网公司采用,是我要主要讲的产品module)目录架构分为2种:一种为LDAP directory tree (traditional naming);另一种为LDAP directory tree (Internet naming)。习惯上,我们在树根一般定义国家(c=CN)或者域名(dc=com),其次往往定义一个或多个组织(organization, o) 或组织单元(organization unit, ou)。一个组织单元可以包含people, printers, documents, or just about anything else you can think of。
Figure 2.1 shows an example LDAP directory tree using traditional naming
Figure 2.1 LDAP directory tree (traditional naming)
★ Figure 1.2 shows an example LDAP directory tree using domain-based naming
PS:目录树也可以基于Internet domain names的命名方式,而且这种方式正越来越受欢迎,因为它允许使用DNS为目录服务定位,后面我们目录树的架构主要拿这个来讲。
Figure 2.2: LDAP directory tree (Internet naming)
另外,我们可以通过使用一种特殊属性objectClass(后面高级章节会跟这个attribute打交道),它可让你的LDAP控制在一个条目中哪个属性是必需或是允许的。objectClass 属性的值决定了schema 规则条目必须遵从。
How is the information referenced? 一个条目(相当于关系数据库中表的记录)引用的是它的DN(Distinguished Name)(相当于关系数据库表中的关键字Primary Key,DN可以看做是到目录树中某一对象的路径),每个对象都有完全唯一的DN。DN是由对象本体开始(called the Relative Distinguished Name or RDN)再串连其祖先条目名字的一条路径。 例如, 在上面Internet命名例子里的条目 Barbara Jensen 有一个 RDN 为 uid=babs 和一个 DN 为 uid=babs,ou=People,dc=example,dc=com。全 DN 格式在 RFC4514 中的 "LDAP: String Representation of Distinguished Names."有描述。
How is the information accessed? LDAP的功能模型中定义了一系列利用LDAP协议的操作,主要包括以下4个部分:
- 查询操作(ldapsearch): 允许查询目录并取得条目,其查询性能要比关系数据库好。
- 更新操作(ldapsearch): 目录树条目支持条目的添加、删除、修改等操作。
- 同步操作: OpenLDAP是一种典型的分布式结构,提供复制同步,可将主服务器上的数据通过推或拉的机制实现在从服务器上更新,完成数据的同步,从而避免OpenLDAP服务器出现单点故障,影响用户验证。
- 认证和管理操作: 允许客户端在目录中识别自己,并且能够控制一个会话的性质。
3、When should I use LDAP?
这是个非常好的问题。 通常,当你需要通过标准化的方法访问集中化管理和存储的数据时,你应该使用一个目录服务器。一些常见(但不限于此)的例子如下:
- 机器验证
- 用户验证
- 用户/系统 组
- 地址簿
- 组织机构表
- 资产跟踪
- 电话信息存储
- 用户资源管理
- E-mail地址查找
- 应用配置存储
- PBX配置存储
- 其他.....
除了上面官网提到的,还适用于不同平发行版的UNIX、Windows系统以及各种应用平台的用户管理,如Apache、Nginx、Zabbix、Postfix、Samba、FTP、SVN、GIT、Openvpn、Hadoop、OpenStack 以及存储设备控制台等。OpenLDAP适用于一台到数千台机器的系统,可实现帐号集中式统一管理。
4、When should I not use LDAP?
当你开始发现自己用目录来做你需要做的事情的时候很别扭,就可能需要重新设计了。或者你只是需要一个应用来使用和操作你的数据。当LDAP对某项工作很合适的时候,很明显就能看出来。(官方的说法)
5、How does LDAP work?
OpenLDAP目前是一款开源的帐号集中管理软件,且属于C/S架构。通过配置服务器和客户端,实现帐号的管理,并通过余第三方应用相结合,实现客户端所有帐号均可通过服务端进行验证授权。
OpenLDAP的工作模型,如Love cat图所示:
OpenLDAP工作模型解释如下:
- 客户端向OpenLDAP服务器发起验证请求;
- 服务器接受用户请求后,并通过slapd进程向后端的数据库进行查询;
- slapd将查询的结果返回给客户端即可。如果有缓存机制,服务端会先将查询的条目进行缓存,然后再发给客户端。
6、What is the difference between LDAPv2 and LDAPv3?(这里直接贴官网的,基本就是schema,sasl,tls,unicode,ldap的uri格式,ldap数据导入导出的文件接口的ldif等的不同)
LDAPv3 was developed in the late 1990's to replace LDAPv2. LDAPv3 adds the following features to LDAP:
Strong authentication and data security services via SASL.
Certificate authentication and data security services via TLS (SSL)
Internationalization through the use of Unicode
Referrals and Continuations
Schema Discovery
Extensibility (controls, extended operations, and more)
LDAPv2 is historic (RFC3494). As most so-called LDAPv2 implementations (including slapd(8)) do not conform to the LDAPv2 technical specification, interoperability amongst implementations claiming LDAPv2 support is limited. As LDAPv2 differs significantly from LDAPv3, deploying both LDAPv2 and LDAPv3 simultaneously is quite problematic. LDAPv2 should be avoided. LDAPv2 is disabled by default.
7、OpenLDAP schema 概念
1、schema 介绍及用途
schema 是OpenLDAP 软件的重要组成部分,主要用于控制目录树中各种条目所拥有的对象类以及各种属性的定义,并通过自身内部规范机制限定目录树条目所遵循的逻辑结构以及定义规范,保证整个目录树没有非法条目数据,避免不合法的条目存在目录树中,从而保障整个目录树信息的完整性、唯一性。
在OpenLDAP 目录树中,schema 用来指定一个条目所包含的对象类(objectClass)以及每一个对象类所包含的属性值(attribute value)。其属性又分为必要属性和可选属性两种,一般必要属性是指添加条目时必须指定的属性,可选属性是可以选择或不选择的。schema 定义对象类对象类包含属性的定义,对象类和属性组合成条目。
目录树中条目可理解为是一个具体的对象,它们均是通过schema 创建的,并符合schema 的标准规范,如对你所添加的数据条目中所包含的对象类级属性进行检测,检测通过完成添加,否则打印错误信息。因此,schema 是一个数据模型,数据模型可以理解为关系数据库的存储引擎,如MyISAM、InnoDB,主要用来决定数据按照什么方式进行存储,并定义存储在目录树不同条目中数据类型之间的关系。
schema 是一个标准,定义了OpenLDAP 目录树对象和属性存取方式,这也是OpenLDAP 能够存储什么数据类型的取决因素。因此数据有什么属性等均根据schema 来实现。OpenLDAP 默认的schema 文件一般存放在/etc/openldap/schema/目录下,此目录下每个文件定义了不同的对象类和属性。如果想引用额外的schema,只需要在配置文件中通过include 包含所指定的schema 即可。
以下代码可用于获取当前系统OpenLDAP 所使用的schema 规范,了解当前所使用的schema文件,这有助于添加目录树中的条目信息,如对象类以及包含哪些属性及值,减少添加条目提示的各种语法错误。
[root@test schema]# cat /etc/openldap/slapd.conf | grep '^incl*'
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/duaconf.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema #定义网络信息服务
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema #定义用户密码规则
include /etc/openldap/schema/collective.schema
include /etc/openldap/schema/sudo.schema #自己添加提权的
include /etc/openldap/schema/openssh-lpk-openldap.schema
2、获取schema 的途径
默认安装OpenLDAP 组件后,系统的配置定义一组常用的schema 文件,这组文件一般存放在/etc/openldap/schema 目录内,可通过include 引用。当所定义的objectClass 不存在时,该如何获取objectClass?下面就介绍如何获取schema 来包含objectClass。
通过服务器自身软件包的安装来生成schema 文件,本节以sudo 为例演示其过程。
查看软件包生成的文件列表
1 2 3 4 | [root@ test ~] # rpm -ql sudo|grep schema /usr/share/doc/sudo-1 .8.6p3 /schema .ActiveDirectory /usr/share/doc/sudo-1 .8.6p3 /schema .OpenLDAP /usr/share/doc/sudo-1 .8.6p3 /schema .iPlanet |
通过配置文件引入schema
1 2 | cp /usr/share/doc/sudo-1 .8.6p3 /schema .OpenLDAP /etc/openldap/schema/sudo .schema echo "include /etc/openldap/schema/sudo.schema" > /etc/openldap/slapd .conf |
通过schema 产生ldif 文件
1 2 3 | slapcat -f ~ /sudo/sudoSchema .conf -F /tmp/ -n0 -s "cn={0}sudo,cn=schema,cn=config" > ~ /sudo/sudo .ldif sed -i "s/{0}sudo/{12}sudo/g" ~ /sudo/sudo .ldif head -n-8 ~ /sudo/sudo .ldif > ~ /sudo/sudo-config .ldif |
通过OpenLDAP 指令导入目录树
1 | ldapadd -Y EXTERNAL -H ldapi: /// -f ~ /sudo/sudo-config .ldif |
此时就可以通过sudo schema 文件定义各种sudo 规则从而实现用户权限的控制。
7、objectClass 详解
在OpenLDAP 目录树中,每个条目必须包含一个属于自身条件的对象类,然后再定义其条目属性及对应的值。
OpenLDAP 条目的属性能否添加取决于条目所继承的objectClass 是否包含此属性。objectClass具有继承关系,也就是说,条目添加的属性最终取决于自身所继承的所有objectClass 的集合。如果所添加的属性不在objectClass 范围内,此时目录服务器不允许添加此属性。如果要添加,就必须添加schema 文件产生objectClass 所对应的属性。objectClass 和Attribute 由schema 文件来规定,存放在/etc/openldap/schema 目录下,schema 文件规范objectClass 的构成以及属性和值在目录树中的对应关系。后面章节会介绍如何通过定义schema 文件来产生objectClass,从而生成所需要的属性。
每一个属性和值将用作每个条目在目录树中存储信息的标准,例如能包含哪些属性信息。对于objectClass 的理解,读者可以将objectClass 的属性值理解为一种模板。模板定义哪些信息可以存取,哪些信息不可以存储在目录树中。
1、objectClass 案例分析
下面给出两个对象类案例分析示例。
objectClass 案例分析示例1
所有的objectClass 定义都存放在/etc/openldap/schema/*.schema 文件中。例如,person 属性的定义就存放在core.schema 文件中。
1 2 3 4 5 | objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) M AY ( userPassword $ telephoneNumber $ seeAlso $ description ) ) |
分析:
如果要定义person 类型,需要定义顶级为top,并且必须定义sn 和cn 两个属性,还可以附加userPassword、telephoneNumber、seeAlso、description 4 个属性值。邮件地址、国家等属性不可以定义,除非读者添加相关的objectClass 条目,否则提示相关属性不允许添加。
objectClass 案例分析示例2
1 2 3 4 5 6 7 8 9 | objectclass: (2.5.6.0 NAME 'top' ABSTRACT MUST (objectClass)) objectclass: ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST (sn $ cn ) MAY (userPassword $ telephoneNumber $ seeAlso $ description )) |
分析:
对于此案例,如果要定义top 属性,必须定义一个objectClass 属性。因为此案例中还定义了person 属性,所以要必须定义sn 和cn 属性,以及可以附加的属性(userPassword、telephoneNumber、seeAlso、description)。此案例中必须要定义的有3 个属性分别是objectClass、sn 以及cn。通过此案例下一级的objectClass 可以继承上一级objectClass 的属性信息。
2、属性概述
属性(Attribute)在目录树中主要用于描述条目相关信息,例如用户条目的用途、联系方式、邮件、uid、gid、公司地址等辅助信息。属性由objectClass 所控制,一个objectClass 的节点具有一系列Attribute,Attribute 可以理解为Linux 系统当中的变量,每个变量都有对应的值,OpenLDAPAttribute 也是有对应的值。这些属性的对应值表示每个对象的特点,但有些属性在添加时是必须指定的,有些属性是非必要的(类似于条目更详细的描述)。在目录树中常用的Attribute 有uid、sn、giveName、I、objectClass、dc、ou、cn、mail、telephoneNumber、c 等。
属性(Attribute)类似于程序设计中的变量,可以被赋值。在OpenLDAP中声明了许多常用的Attribute(用户也可自己定义Attribute)。常见的Attribute含义如下:
c:国家。
cn:common name,指一个对象的名字。如果指人,需要使用其全名。
dc:domain Component,常用来指一个域名的一部分。
givenName:指一个人的名字,不能用来指姓。
l:指一个地名,如一个城市或者其他地理区域的名字。
mail:电子信箱地址。
o:organizationName,指一个组织的名字。
ou:organizationalUnitName,指一个组织单元的名字。
sn:surname,指一个人的姓。
telephoneNumber:电话号码,应该带有所在的国家的代码。
uid:userid,通常指某个用户的登录名,与Linux系统中用户的uid不同。
8、LDIF 详解
1、LDIF 用途
LDIF(LDAP Data Interchanged Format)的轻量级目录访问协议数据交换格式的简称,是存储LDAP 配置信息及目录内容的标准文本文件格式,之所以使用文本文件来存储这些信息是为了方便读取和修改,这也是其他大多数服务配置文件所采取的格式。通常用来交换数据并在OpenLDAP服务器之间互相交换数据,并且可以通过LDIF 实现数据文件的导入、导出以及数据文件的添加、修改、重命名等操作,这些信息需要按照LDAP 中schema 的规范进行操作,并会接受schema 的检查,如果不符合OpenLDAP schema 规范要求,则会提示相关语法错误。
2、LDIF 文件特点
LDIF 文件每行的结尾不允许有空格或者制表符。
LDIF 文件允许相关属性可以重复赋值并使用。
LDIF 文件以.ldif 结尾命名。
LDIF 文件中以#号开头的一行为注释,可以作为解释使用。
LDIF 文件所有的赋值方式为:属性:[空格]属性值。
LDIF 文件通过空行来定义一个条目,空格前为一个条目,空格后为另一个条目的开始。
3、LDIF 格式语法
LDIF 文件存取OpenLDAP 条目标准格式:
1 2 3 4 | # 注释,用于对条目进行解释 dn:条目名称 objectClass(对象类): 属性值 objectClass(对象类): 属性值 …… |
LDIF 格式样例如下:
1 2 3 4 5 6 7 8 9 10 11 | dn: uid=water,ou=people, dc =wzlinux, dc =com #DN 描述项,在整个目录树上为唯一的 objectClass: top objectClass: posixAccount objectClass: shadowAccount objectClass: person objectClass: inetOrgPerson objectClass: hostObject sn: zuo cn: zuoyang telephoneNumber:xxxxxxxxxxx mail: [email protected] |
注:冒号后面有一个空格,然后才是属性的值,schema 规范定义要求很严格。