一、目录服务
目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。
目录服务是由目录数据库和一套访问协议组成的系统。类似以下的信息适合储存在目录中:
企业员工信息,如姓名、电话、邮箱等;
公用证书和安全密钥;
公司的物理设备信息,如服务器,它的IP地址、存放位置、厂商、购买时间等;
LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写,LDAP是从X.500目录访问协议的基础上发展过来的,目前的版本是v3.0。与LDAP一样提供类似的目录服务软件还有ApacheDS、Active Directory、Red Hat Directory Service 。
二、OpenLDAP 是什么
OpenLDAP 是一款轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP),属于开源集中账号管理架构的实现,且支持众多系统版本,被广大互联网公司所采用。
LDAP 具有两个国家标准,分别是X.500 和LDAP。OpenLDAP 是基于X.500 标准的,而且去除了X.500 复杂的功能并且可以根据自我需求定制额外扩展功能,但与X.500 也有不同之处,例如OpenLDAP 支持TCP/IP 协议等,目前TCP/IP 是Internet 上访问互联网的协议。
OpenLDAP 则直接运行在更简单和更通用的TCP/IP 或其他可靠的传输协议层上,避免了在OSI会话层和表示层的开销,使连接的建立和包的处理更简单、更快,对于互联网和企业网应用更理想。LDAP 提供并实现目录服务的信息服务,目录服务是一种特殊的数据库系统,对于数据的读取、浏览、搜索有很好的效果。目录服务一般用来包含基于属性的描述性信息并支持精细复杂的过滤功能,但OpenLDAP 目录服务不支持通用数据库的大量更新操作所需要的复杂的事务管理或回滚策略等。
OpenLDAP 默认以Berkeley DB 作为后端数据库,Berkeley DB 数据库主要以散列的数据类型进行数据存储,如以键值对的方式进行存储。Berkeley DB 是一类特殊的数据库,主要用于搜索、浏览、更新查询操作,一般对于一次写入数据、多次查询和搜索有很好的效果。Berkeley DB 数据库是面向查询进行优化,面向读取进行优化的数据库。Berkeley DB 不支持事务型数据库(MySQL、MariDB、Oracle 等)所支持的高并发的吞吐量以及复杂的事务操作。
OpenLDAP 目录中的信息是按照树形结构进行组织的,具体信息存储在条目(entry)中,条目可以看成关系数据库中的表记录,条目是具有区别名(Distinguished Name,DN)的属性(attribute),DN 是用来引用条目,DN 相当于关系数据库(Oracle/MySQL)中的主键(primary key),是唯一的。属性由类型(type)和一个或者多个值(value)组成,相当于关系数据库中字段的概念。
三、为什么选择OpenLDAP 产品
我们知道,账号是登录系统的唯一入口。要登录系统,首先系统要存在登录所使用的账号(/etc/passwd)及密码信息(/etc/shadow),然后经过系统查找顺序(/etc/nsswith.conf)及认证模块(/etc/pam.d/*)验证,得到授权后方可登录系统。如果多个用户登录系统,就需要在每个系统上创建用户名和密码;否则,就无法登录系统。
对于账号管理人员而言,维护10 台、100 台机器的账号,或许勉强可以维护、管理。如果机器数量达到1000 以上时,对于账号的创建、回收、权限的分配、密码策略、账号安全审计等一系列操作,账号管理人员就心有余而力不足了。此时OpenLDAP 账号集中管理软件就应用而生,它可以实现账号集中维护、管理,只需要将被管理的机器加入到服务器端即可,此后所有与账号相关的策略均在服务端实现,从而解决了运维案例所产生的众多管理问题。
关于账号的添加、删除、修改、权限的赋予等一系列操作只需要在服务端操作即可,无须在客户端机器进行单独操作。客户端账号及密码均通过OpenLDAP 服务器进行验证,从而实现账号集中认证管理,此时账号管理员只须维护OpenLDAP 服务器条目即可。
OpenLDAP 属于开源软件,且OpenLDAP 支持LDAP 最新标准、更多模块扩展功能、自定义schema 满足需求、权限管理、密码策略及审计管理、主机控制策略管理、第三方应用平台管理以及与第三方开源软件结合实现高可用负载均衡平台等诸多功能,这也是商业化管理软件无可比拟的。所以关于账号的管理OpenLDAP 是企业唯一的选择。目前各大著名公司都在使用OpenLDAP实现账号的集中管理,如PPTv、金山、Google、Facebook 等,这也是选择OpenLDAP 实现账号统一管理的原因之一。
四、OpenLDAP 目录服务优点
OpenLDAP 目录服务有以下10 个优点。
OpenLDAP 是一个跨平台的标准互联网协议,它基于X.500 标准协议。
OpenLDAP 提供静态数据查询搜索,不需要像在关系数据中那样通过SQL 语句维护数据库信息。
OpenLDAP 基于推和拉的机制实现节点间数据同步,简称复制(replication)并提供基于TLS、SASL 的安全认证机制,实现数据加密传输以及Kerberos 密码验证功能。
OpenLDAP 可以基于第三方开源软件实现负载(LVS、HAProxy)及高可用性解决方案,24 小时提供验证服务,如Headbeat、Corosync、Keepalived 等。
OpenLDAP 数据元素使用简单的文本字符串(简称LDIF 文件)而非一些特殊字符,便于维护管理目录树条目。 章
OpenLDAP 可以实现用户的集中认证管理,所有关于账号的变更,只须在OpenLDAP 服务器端直接操作,无须到每台客户端进行操作,影响范围为全局。
OpenLDAP 默认使用协议简单如支持TCP/ZP 协议传输条目数据,通过使用查找操作实现对目录树条目信息的读写操作,同样可以通过加密的方式进行获取目录树条目信息。
OpenLDAP 产品应用于各大应用平台(Nginx、HTTP、vsftpd、Samba、SVN、Postfix、OpenStack、Hadoop 等)、服务器(HP、IBM、Dell 等)以及存储(EMC、NetApp 等)控制台,负责管理账号验证功能,实现账号统一管理。
OpenLDAP 实现具有费用低、配置简单、功能强大、管理容易及开源的特点。
OpenLDAP 通过ACL(Access Control List)灵活控制用户访问数据的权限,从而保证数据的安全性。
五、OpenLDAP 功能
在LDAP 的功能模型中定义了一系列利用LDAP 协议的操作,主要包含以下4 部分。
查询操作(ldapsearch):允许查询目录并取得条目,其查询性能比关系数据库好。
更新操作(ldapupdate):目录树条目支持条目的添加、删除、修改等操作。
同步操作:OpenLDAP 是一种典型的分布式结构,提供复制同步,可将主服务器上的数据通过推或拉的机制实现在从服务器上更新,完成数据的同步,从而避免OpenLDAP 服务器出现单点故障,影响用户验证。
认证和管理操作:允许客户端在目录中识别自己,并且能够控制一个会话的性质。
六、OpenLDAP 目录架构介绍
目前OpenLDAP 目录架构分为两种:一种为互联网命名组织架构;另一种为企业级命名组织架构。本节分别为介绍两种架构的用途,但本书主要以企业级命名组织架构为核心进行阐述OpenLDAP 内部逻辑结构、工作原理以及企业实践等相关知识。
1、互联网命名组织架构
LDAP 的目录信息是以树形结构进行存储的,在树根一般定义国家(c=CN)或者域名(dc=com),其次往往定义一个或多个组织(organization,o)或组织单元(organization unit,ou)。一个组织单元可以包含员工、设备信息(计算机/打印机等)相关信息。例如uid=babs,ou=People,dc=example,dc=com。
备注:图片来源http://www.openldap.org/doc/admin24/intro.html#What is LDAP
2、企业级命名组织架构
企业级命名(传统命名)组织架构的示例
七、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文件,这有助于添加目录树中的条目信息,如对象类以及包含哪些属性及值,减少添加条目提示的各种语法错误。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[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 规则从而实现用户权限的控制。
八、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不同。
九、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: Wang
cn: WangZan
telephoneNumber:xxxxxxxxxxx
mail: xxxx@126.com
|
注:冒号后面有一个空格,然后才是属性的值,schema 规范定义要求很严格。