LDAP协议数据库
目录是一组具备相似属性、以必定逻辑和层次组合的信息。常见的例子是通信簿,由以字母顺序排列的名字、地址和电话号码组成。
目录服务是一种在分布式环境中发现目标的方法。目录具备两个主要组成部分:编程
第一部分是数据库,数据库是分布式的,且拥有一个描述数据的规划。服务器
第二部分则是访问和处理数据的各类协议。网络
目录服务其实也是一种数据库系统,只是这种数据库是一种树形结构,而不是一般使用的关系数据库。目录服务与关系数据库之间的主要区别在于:两者都容许对存储数据进行访问,只是目录主要用于读取,其查询的效率很高,而关系数据库则是为读写而设计的。
提示:目录服务不适于进行频繁的更新,属于典型的分布式结构。
LDAP是一个目录服务协议,目前存在众多版本的LDAP,而最多见的则是V2和V3两个版本,它们分别于1995年和1997年首次发布。数据结构
LDAP的基本模型app
LDAP的基本模型是创建在“条目”(Entry)的基础上。一个条目是一个或多个属性的集合,而且具备一个全局惟一的“可区分名称”(用dn表示)。与关系型数据(后面简称数据库)进行类比,一个条目至关于数据库中的一条记录,而dn至关于数据库中记录的关键字,属性至关于数据库中的字段。
提示:dn必须是全局惟一的。
LDAP中,将数据组织成一个树形结构,这与现实生活中的不少数据结构能够对应起来,而不像设计关系型数据库的表,须要进行多种变化。例如,图1-1所示就是一个树形结构的数据。负载均衡
在图1-1所示的树形结构中,树的根结点是一个组织的域名(dlw.com),其下分为3个部分,分别是managers、people和group,可将这3个组看做组织中的3个部门,如managers用来管理全部管理人员,people用来管理登陆系统的用户,group用来管理系统中的用户组。固然,在该图中还可继续增长其余分支。
对于图1-1所示的树形结构,使用关系数据库来保存数据的话,须要设置多个表,一层一层分别保存,当须要查找某个信息时,再逐层进行查询,最终获得结果。
若使用目录来保存该图中的数据,则更直观。图中每一个结点用一个条目来保存,不一样类型的结点须要保存的数据可能不一样,在LDAP中经过一个称为objectClass的类型来控制不一样结点须要的数据(称为属性)。
对于目录中的数据怎样进行引用呢?前面提到过,每个条目都有一个dn,由于dn是惟一的,所以就可找到须要结点的数据。dn的构造方式以下:
首先获得条目本身的名称(rdn,称为相对dn),而后开始向上逐级查找父结点,一直到根项为止。例如,对于图1-1中最右下方的结点,其dn为:dom
dn: cn=ldap, ou=group, o=dlw.com 分布式
经过这样的方式,便可惟一标识每个结点。
在现实生活中,有不少这种树形结构的数据,如计算机文件系统的目录结构、Internet中的域名等。这些类型的数据,只要不须要频繁的更新,都适合用目录来保存。
LDAP的功能
在LDAP的功能模型中定义了一系列利用LDAP协议的操做,主要包含如下4部分:
查询操做 :容许查询目录和取得数据,其查询性能比关系数据库好。
更新操做 :目录的更新操做不要紧数据库方便,更新性能较差,但也一样容许进行添加、删除、修改等操做。
复制操做 :前面也提到过,LDAP是一种典型的分布式结构,提供复制操做,可将主服务器的数据的更新复制到设置的从服务器中。
认证和管理操做 :容许客户端在目录中识别本身,而且可以控制一个会话的性质。
LDAP协议的特色
LDAP是一种目录服务,保存在特殊的数据库中,数据的读取速度远高于写入速度。
LDAP对查询作了优化,读取速度优于普通关系数据库。
LDAP不支持事务、不能进行回滚,须要进行这些操做的应用只有选择关系数据库。
LDAP采用服务器/客户端模式,支持分布式结构。
LDAP中的条目以树形结构组织和存储。
LDAP基于Internet协议,直接运行在简单和通用的TCP/IP或其余可靠的传输协议层上,使链接的创建和包的处理简单、快捷,对于互联网和企业网应用都很方便。
LDAP协议简单,经过使用查找操做实现列表操做和读操做。
LDAP经过引用机制实现分布式访问,经过客户端API实现分布式操做(对于应用透明),平衡了负载。
LDAP实现具备低费用、易配置和易管理的特色,并提供了知足应用程序对目录服务所需求的特性。
安装OpenLDAP
在RHEL 5的安装光盘中提供了OpenLDAP 2.3.27软件包,经过OpenLDAP软件可实现LDAP服务。OpenLDAP程序包括客户端、服务器、开发工具包等软件包,本节将介绍安装这些程序包的具体过程。
能够先经过rpm命令查询系统中是否已安装OpenLDAP服务器程序,若未安装该服务器程序,再使用rpm命令从RHEL光盘中安装该程序。
从RHEL 5安装光盘中找到OpenLDAP服务器程序,并安装到当前系统中。
具体操做步骤以下:
(1)在进行安装之前,首先使用如下命令建立管理OpenLDAP的用户和组。
# groupadd ldap
# useradd -g ldap ldap
# passwd ldap
(2)执行如下命令,查询系统中是否已安装openldap-servers程序。
# rpm -qa openldap-servers
若无任何输出,则表示当前系统中未安装openldap-servers服务器程序。
(3)使用如下命令将RHEL安装光盘挂载到系统中:
# mount /dev/cdrom /mnt/cdrom
(4)执行如下命令安装openldap-servers程序的依赖程序包libtools-ltdl:
# rpm -ivh /mnt/cdrom/Server/libtool-ltdl-1.5.22-6.1.i386.rpm
若不执行上面的命令,直接执行下一步的安装命令,将提示有依赖程序未安装。
(5)执行如下命令安装openldap-servers程序:
# rpm -ivh /mnt/cdrom/Server/openldap-servers-2.3.27-5.i386.rpm
这样就将openldap-servers服务器程序安装到系统中了。整个安装过程以下图所示。
(6)使用如下命令修改保存数据的目录/var/lib/ldap/及其文件的全部者,并修改权限,只有ldap用户才对数据有读写权限:
# chown ldap.ldap /var/lib/ldap
# chmod -R 600 /var/lib/ldap
在光盘中还有如下与openldap有关的软件包,也可以使用相似命令进行安装,这里再也不逐个介绍。
● openldap-clients-2.3.27-5.i386.rpm:客户端操做的相关程序。
● openldap-devel-2.3.27-5.i386.rpm:开发包。
测试安装正确性
安装完成后,将在/var/lib/目录中建立一个子目录ldap来保存数据,同时在/etc/目录中也将建立一个子目录openldap来保存配置文件。而openldap的守护进程slapd则保存在/usr/bin/目录中。
提示:若是是经过源代码进行编译安装的openldap,这些程序文件放置的位置可能不一样。
1.启动服务进程
要检查安装是否正确,可直接运行守护进程,这里将使用默认的配置。
启动OpenLDAP服务器可以使用如下命令之一:
# server ldap start
# /etc/rc.d/init.d/ldap
# /usr/sbin/slapd
使用第1条命令来启动ldap服务进程的过程以下图所示。
提示:使用/usr/sbin/slapd命令启动服务程序是最好的一种方式,若是用前两条命令启动openldap服务程序失败,可以使用最后一条命令试一下。
从上图可看出,启动的是slapd进程,并有一个提示信息,提示没有DB_CONFIG文件。可经过如下命令将DB_CONFIG文件复制到/var/lib/ldap/目录中:
# cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
另外,因为使用的是默认配置文件,提示但愿使用后缀“dc=my-domain, dc=com”。下节将介绍修改配置文件的操做。
2.查看监听端口
OpenLDAP使用的监听端口是389,经过netstat命令查看该端口是否处于监听状态,可了解slapd进程是否在工做。具体命令以下:
# netstat –tnlp | grep 389
执行结果以下图所示,能够看出,389端口处于监听状态,表示slapd进程正在工做。
3.搜索测试
slapd服务进程启动后,可以使用OpenLDAP客户端的一个搜索命令进行一次搜索,以检查服务的配置是否正确。
使用如下命令进行搜索:
# ldapsearch -x -b '' -s base '(objectclass=*)'
注意:-b后面是两个单引号,用来阻止特殊字符被Shell解析。
因为还未向LDAP服务器中添加任何数据,所以,系统中应该只有“根”这个条目,执行以上搜索的结果以下图所示。
从以上测试可看出,OpenLDAP已经正确安装到系统中,接下来就须要修改配置文件,设置LDAP的根目录了。
配置OpenLDAP
在上面的例子中的搜索结果可看出,在配置文件中是以默认的“dc=my-domain, dc=com”做为后缀,须要对其进行修改,固然也还须要修改其余的一些配置。下面将介绍对配置文件的修改操做。
slapd.conf
OpenLDAP的配置文件位于/etc/openldap/目录中,名称为slapd.conf。该文件内容较多,一般只须要修改几个地方便可,包括修改后缀、管理员及其密码。其初始内容以下:
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=my-domain,dc=com"
rootdn "cn=Manager,dc=my-domain,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
# rootpw secret
# rootpw {crypt}ijFYNcSNctBYg
其中各语句的含义以下:
● 以符号“#”开始的行是注释行,第1~3行、第8~12行都是。
● 第5行设置数据库,可以使用ldbm或bdb。
● 第6行设置后缀。
● 第7行设置超级管理员的名称,与Linux系统中的root相似。在配置时用该用户,配置完成后,建议将其删除。
● 第11行设置超级管理员的密码,默认状态是被注释了的。这行的密码是明文状态。
● 第12行也是设置超级管理员的密码,这行是以加密方式设置的(默认状态也是被注释了的)。
根据实际状况,修改第六、七、11行便可,具体以下:
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=dlw,dc=com"
rootdn "cn=root,dc=dlw,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret
# rootpw {crypt}ijFYNcSNctBYg
以上内容中,第6行将后缀修改成“dc=dlw,dc=com”,同时第7行的超级管理员的后缀部分也须要随之修改。将第11行的注释取消,设置超级管理员的密码为MD5密码secret。
修改密码时须要注意rootpw前面不要有空格,以及rootpw与密码之间使用Tab键分割。
通过以上修改,保存后退出,接着使用如下命令重启slapd进程:
# service ldap restart
了解schema
对于LDAP目录中保存的信息,可使用LDIF(LDAP Interchange Format)格式来保存。这是一种标准文本文件格式,使用这种格式保存得的LDAP服务器数据库中的数据可方便读取和修改,这也是其余大多数服务配置文件所采起的格式。
LDIF文件经常使用来向目录导入或更改记录信息,这些信息须要按照LDAP中schema的格式进行组织,并会接受schema的检查,不符合其要求的格式将会出现报错信息。有关LDIF文件的格式和建立将在第4章进行介绍,这里简单介绍一下组织LDAP数据格式的schema文件。
在LDAP中,schema用来指定一个目录中所包含的对象(objects)的类型(objectClass),以及每个类型(objectClass)中必须提供的属性(Atrribute)和可选的属性。可将schema理解为面向对象程序设计中的类,经过类定义一个具体的对象。LDIF中的数据条目可理解为是一个具体的对象,是经过schema来规划建立的。所以,schema是一个数据模型,用来决定数据按什么方式存储,并定义存储在不一样的条目(Entry)下的数据之间的关系。schema须要在主配置文件slapd.conf中指定,以用来决定在目录中可使用哪些objectClass。
在/etc/openldap/schema/目录中提供了许多schema文件,只须要在配置文件slapd.conf中使用include命令将须要使用的schema包含便可。例如,配置文件默认包含了如下schema文件:
写道include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
提示:一般使用系统提供的schema就可解决大部分应用。管理员也能够本身设计制定schema,通常包括属性定义(AttributeDefinition)、类定义(ClassDefinition)以及语法定义(SyntaxDefinition)等部分。这里就不介绍具体的设计方法了。
管理OpenLDAP
启动OpenLDAP服务器程序以后,接下来的操做就是经过客户端程序对目录进行操做,包括添加、修改、删除和搜索数据等操做。能对LDAP进行操做的客户端程序不少,下面简单介绍在Linux命令方式下进行这些操做的方法。
向目录数据库中添加数据
初始状态下,LDAP是一个空目录,即没有任何数据。可经过程序代码向目录数据库中添加数据,也可以使用OpenLDAP客户端工具ldapadd命令来完成添加数据的操做,该命令可将一个LDIF文件中的条目添加到目录。所以,须要首先建立一个LDIF文件,而后再进行添加操做。
1.LDIF文本条目格式
LDIF用文本格式表示目录数据库的信息,以方便用户建立、阅读和修改。在LDIF文件中,一个条目的基本格式以下:
写道# 注释
dn: 条目名
属性描述: 值
属性描述: 值
属性描述: 值
... ...
dn行相似于关系数据库中一条记录的关键字,不能与其余dn重复。一个LDIF文件中能够包含多个条目,每一个条目之间用一个空行分隔。
例如,如下内容组成一个条目:
写道1: dn: dc=dlw, dc=com
2: objectclass: top
3: objectclass: dcobject
4: objectclass: organization
5: dc: dlw
6: o: dlw,Inc.
在以上文本中,各行含义以下:
第1行的dn定义该条目的标识。
第2~4行定义该条目的objectcCass,能够定义多个属性,如上面代码中定义了3个objectClass。条目的属性根据objectClass的不一样而不一样,有的objectClass有必须设置的属性。在2~4行的3个objectClass中,top没有必须定义的属性,dcobject必须定义属性dc,用来表示一个域名的部分,而organization必须定义属性o,用来表示一个组织的名称。
根据objectClass的要求,第五、6行分别定义属性dc和属性o的值。
2.了解objectClass
LDAP中,一个条目必须包含一个objectClass属性,且须要赋予至少一个值。每个值将用做一条LDAP条目进行数据存储的模板;模板中包含了一个条目必须被赋值的属性和可选的属性。
objectClass有着严格的等级之分,最顶层是top和alias。例如,organizationalPerson这个objectClass就隶属于person,而person又隶属于top。
objectClass可分为如下3类:
结构型(Structural) :如person和organizationUnit;
辅助型(Auxiliary) :如extensibeObject;
抽象型(Abstract) :如top,抽象型的objectClass不能直接使用。
在OpenLDAP的schema中定义了不少objectClass,下面列出部分经常使用的objectClass的名称。
● account
● alias
● dcobject
● domain
● ipHost
● organization
● organizationalRole
● organizationalUnit
● person
● organizationalPerson
● inetOrgPerson
● residentialPerson
● posixAccount
● posixGroup
3.了解Attribute
属性(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不一样。
提示:objectClass是一种特殊的Attribute,它包含其余用到的Attribute以及其自身。
对于不一样的objectClass,一般具备一些必设属性值和一些可选属性值。例如,可以使用person这个objectClass来表示系统中一个用户的条目,对于系统中用户一般须要有这样一些信息:姓名、电话、密码、描述等。以下图所示,对于person,经过cn和sn设置用户的名和姓,这是必须设置的,而其余属性则是可选的。
下面列出部分经常使用objectClass要求必设的属性。
● account:userid。
● organization:o。
● person:cn和sn。
● organizationalPerson:与person相同。
● organizationalRole:cn。
● organizationUnit:ou。
● posixGroup:cn、gidNumber。
● posixAccount:cn、gidNumber、homeDirectory、uid、uidNumber。
4.建立LDIF文件
对以上内容有必定了解以后,就能够编写输入LDIF文件,编辑须要向目录数据库添加的条目了。
下面根据以下图所示的结构,建立LDIF文件dlw.com.ldif。
对上图进行分析,该目录结构分为3层,有4个结点。根据上图可建立LDIF文件以下:
提示:每一个结点可用一个dn表示,对于每一个结点,又可继续添加新的结点。如在根结点中可添加其余部门ou,在ou=managers结点也可继续添加其余管理人员的信息。
写道1: dn:dc=dlw,dc=com
2: objectclass:top
3: objectclass:dcobject
4: objectclass:organization
5: dc:dlw
6: o:dlw,Inc.
7:
8: dn:ou=managers, dc=dlw, dc=com
9: ou:managers
10: objectclass:organizationalUnit
11:
12: dn:cn=dlw,ou=managers,dc=dlw,dc=com
13: cn:dlw
14: sn:dongliwei
15: objectclass:person
16:
17: dn:cn=test,ou=managers,dc=dlw,dc=com
18: cn:test
19: sn:Test User
20: objectclass:person
以上文件中各行的含义以下:
第1~6行建立根结点,这部分在前面也有介绍,就再也不重复了。
第七、十一、16行为空行,用来分隔4个dn条目(4个结点)。
第8~10行定义cn=managers结点的条目,该条目的objectClass为organizationalUnit,所以须要用ou属性定义组织名称。
第12~15行定义cn=dlw结点的条目,该条目使用的objectClass为person,所以需设置cn和sn两个属性值。
第17~20行与第12~15行的意义相同。
在以上LDIF文件中,第一、八、十二、17行以dn开头,这部份内容必须惟一,而且在向目录数据库添加这些数据时,也要确保这些数据不能与目录数据库中已有数据相同,不然,添加操做将中断。
5.从LDIF文件添加到目录数据库
使用OpenLDAP客户端工具ldapadd命令,可将LDIF文件中的条目添加到目录数据库中,该命令的格式以下:
ldappadd 选项 LDIF文件
在ldappadd命令中经常使用的选项以下:
-x:进行简单认证。
-D:用来绑定服务器的dn。
-h:目录服务的地址。
-w:绑定dn的密码。
-f:使用LDIF文件进行条目添加的文件。
将前面编写的LDIF文件的条目数据添加到目录数据库中。
具体操做步骤以下:
(1)检查dlw.com.ldif文件中的内容,须要注意的是,每一个冒号后面都须要空一格,而每行结束处不能留有空格字符。
(2)使用如下命令将dlw.com.ldif文件中的条目添加到目录中:
写道# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f dlw.com.ldif
执行以上命令,若是添加操做正常完成,将显示以下图所示的提示信息,表示添加了4个条目到目录数据库中。
提示:若是以上命令执行不成功,须要逐个字符检查dlw.com.ldif文件中的内容,特别注意空格的问题。
查询
添加到目录中的条目被保存在目录数据库,在Linux命令界面下,可以使用OpenLDAP客户端工具ldapsearch命令来进行查询。该命令的格式以下:
ldapsearch 选项 过滤 属性值
经常使用的选项有如下几个:
● -x:进行简单认证。
● -D:用来绑定服务器的dn。
● -w:绑定dn的密码。
● -b:指定要查询的根节点。
● -H:制定要查询的服务器。
使用ldapsearch命令查询“dc=dlw, dc=com”下的全部条目,可以使用如下命令:
# ldapsearch -x -b "dc=dlw,dc=com"
执行结果以下图所示。
而若是使用如下命令,将查询显示sn中以字符wu开头的条目,将获得以下图所示的查询结果,只找到一个条目。
# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'
修改条目
使用OpenLDAP客户端工具ldapmodify命令可对目录数据库中的条目进行修改。该命令的格式以下:
ldapmodify 选项
该命令的选项也不少,经常使用选项与ldapadd相似,这里就再也不列出了。
提示:使用ldapmodify命令不能修改条目的dn,但能够修改其余属性值。
使用ldapmodify命令修改条目信息能够有两种方式:一种是交互式进行修改,另外一种是经过文件进行修改。
1.交互式修改
修改前面建立的条目“cn=test, ou=managers, dc=dlw, dc=com”,将其sn属性修改成“Test User Modify”,并添加一个description属性,设置其值为“add Attribute”。
首先输入如下命令,进行修改状态:
# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret
执行以上命令后,终端将等候用户输入须要修改条目的dn,输入如下内容:
dn: cn=test, ou=managers, dc=dlw, dc=com
changetype: modify
replace: sn
sn: Test User Modify
以上输入内容中,第1行查找须要修改的条目,第2行设置修改模式,第3行设置须要替换的属性sn,第4行给属性sn从新设置一个值,替换该属性原有的值。
输入完以上内容以后再按Enter键,程序将按以上设置更新数据,而后按Ctrl+C键退出修改命令。执行过程以下图所示。
使用以上命令修改条目的数据以后,可以使用如下命令查看是否修改为功:
#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'
执行以上命令查看test条目的数据以下图所示,能够看到sn属性被修改了。
2.经过文件修改
经过前面的方式对条目进行修改时,很不方便,若是在交互方式时输错了某个字符,只能中断命令后从新进行修改。所以,更好的修改方法是首先将修改时输入的文字保存到一个文件中,而后以该文件做为输入进行修改。用这种方式进行操做,首先须要建立一个临时文件,用来保存须要进行的修改操做,下面演示这种方式的修改过程。
【例子】 经过修改命令将前面LDAP数据库中的信息还原,即将sn属性由“Test User Modify”修改成“Test User”。
具体操做步骤以下:
(1)使用vi编辑器建立一个文件modify,在其中输入如下内容:
dn: cn=test,ou=managers,dc=dlw,dc=com
changetype: modify
replace: sn
sn: Test User
从以上输入内容可看到,与在交互式时输入的内容彻底相同。
技巧:使用文件方式修改条目,可方便修改和检查,若某个地方有输入错误,可修改后再调用ldapmodify进行修改,减小输入量。
(2)使用如下命令调用modify的内容进行修改:
# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify
执行结果以下图所示。
删除条目
对于目录数据库中不用的条目,也可以使用ldapdelete命令将其删除。该命令的格式以下:
ldapdelete 选项 删除条目
该命令使用的选项与ldapadd相似,就再也不列出来了。
删除目录数据库中的“cn=test,ou=managers,dc=dlw,dc=com”条目,具体命令以下:
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \
> "cn=test,ou=managers,dc=dlw,dc=com"
顺利执行以上命令后,终端上将不会有任何信息输出,表示完成了删除操做。
使用ldapdelete命令只能删除树形结构中的叶结点条目,若是删除非叶结点条目,将出现错误提示。例如,执行如下命令删除根结点“dc=dlw,dc=com”,因为根结点下面还有结点,将显示以下图所示的错误提示信息:
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"
数据导出
经过ldapadd命令可向目录数据库中添加数据,在某些状况下,可能还须要进行反向操做,即将目录数据库中的数据导出。
使用ldapsearch命令对目录数据库进行搜索,而后经过重定向将搜索结果保存到一个文件中,可达到导出数据的目的。另外,导出数据更经常使用的是slapcat命令,该命令的格式以下:
slapcat 选项
最经常使用的选项就是-l,表示导出为LDIF文件格式。
如将本章前面例子中建立的目录数据库导出为export.ldif文件,可以使用如下命令:
#slapcat -l export.ldif
执行以上命令将在当前工做目录获得文件export.ldif,打开文件将显示以下图所示的内容:
提示:从导出结果可看出,除了使用ldapadd命令添加到目录数据库中的条目数据外,还导出了不少其余信息,包括条目录UUID、时间戳等信息。
设置主从LDAP服务器
在某些时候,为了对LDAP服务器进行负载均衡,可能但愿设置多台LDAP服务器。对于设置多台LDAP服务器的关键问题是数据的同步问题,使用slurpd进程可进行主LDAP服务器向从LDAP服务器复制数据的操做。下面将介绍架设主从LDAP服务器的过程。
多台LDAP服务器工做过程
对于多台LDAP服务器,可设置一台为主服务器,其余的为从服务器。本节介绍一台从服务器的配置,如果多台从服务器也可按此步骤进行操做。
注意:在进行配置以前应首先确保每一个LDAP服务器都已安装好OpenLDAP服务器程序,并能正确工做。
经过本节下面介绍的方法配置好主从LDAP服务器以后,在主服务器运行slurpd进程,该进程使用LDAP协议从主服务器的数据库更新从服务器的数据,具体操做过程以下:
(1)LDAP客户端向从服务器提交一个LDAP修改请求。
(2)从服务器给LDAP客户端返回一个指向主服务器的引用。
(3)LDAP客户端向主服务器提交LDAP修改请求。
(4)主服务器对数据库中的数据进行修改,并将改变写入本机的日志文件。
(5)在主服务器运行的slurpd进程检查到日志中有新内容,经过日志的信息将改变发送给从服务器。
(6)从服务器接收slurpd发来的信息,对本地数据进行修改。
以上过程就是使用slurpd进程进行数据复制的过程。从以上过程可看出,须要在主服务器的配置文件中设置要向哪些从服务器发送复制信息、主服务器还要设置一个记录数据改变的日志文件,而从服务器须要设置一个指向主服务器的连接。
复制数据库
首先,把主从服务器关闭。经过如下三步操做静态同步主从服务器上的数据:
把主服务器上/var/lib/ldap目录下的全部数据库文件所有拷贝到从服务器的同目录中,覆盖原有文件。
把主服务器上的/etc/ldap/schema目录下的全部schema文件拷贝到从服务器的同目录中,覆盖原有文件。
把主服务器上/etc/ldap/slapd.conf文件拷贝到从服务器的同目录中,覆盖原有文件。
设置主服务器
配置主服务器上的slapd.conf文件,取消replogfile指令前的注释符号,取消后的结果以下:
# Replicas of this database
replogfile /var/lib/ldap/replog
增长replica指令,如:
#replace config
replica uri=ldap://192.168.14.21:389 #指定从服务器主机名和端口号
binddn="cn=root,dc=dlw,dc=com" #指定需同步的DN的管理员
bindmethod=simple credentials=111111 #指定验证方式和需同步的DN的管理员密码
设置从服务器
配置从服务器上的slapd.conf文件,增长updatedn指令,如:
updatedn " cn=root,dc=dlw,dc=com" #与主服务器的binddn对应
在从服务器的配置文件中,不要包含replica和replogfile指令。
测试主从LDAP服务器
通过以上步骤的操做,主从LDAP服务器都已准备好,接下来就能够测试相关操做。
1.启动主LDAP服务器
在主LDAP服务器中启动slapd进程和slurpd进程。
2.启动从LDAP服务器
在主LDAP服务器中启动slapd进程。
【例子】测试主从LDAP服务器。
具体操做步骤以下:
(1)在主LDAP服务器中使用如下命令修改一个条目:
#ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret
输入如下内容,修改cn=dlw条目的内容:
dn: cn=dlw,ou=managers,dc=dlw,dc=com
changetype: modify
replace: sn
sn: dongliwei
输入后按Enter键完成修改,操做过程如图5-7所示(将sn修改成dongliwei)。
(2)在从LDAP服务器中进行操做,查看主LDAP服务器中的操做是否被复制到从LDAP服务器中来了。在从LDAP服务器中使用如下命令进行查询:
#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"
执行结果以下图所示,从图中可看到其中的sn也被修改成dongliwei了(数据库中原来的内容为zhangsan.modi,是前面例子中修改的值),即被主LDAP服务器进行了同步复制。
OpenLDAP在用户认证的应用
OpenLDAP常常用在用户登陆认证方面,经过LDAP的数据复制功能,可以让用户使用一个帐户登陆网络中使用LDAP服务的全部服务器。在主LDAP服务器中设置好用户帐户数据,而后经过在网络中的任意客户端均可使用设置的帐号进行登陆操做。下面将简单介绍将用户认证迁移到LDAP的操做方法。
用户认证用到的ojbectClass
在LDAP中用来保存用户认证条目的objectClass主要有如下3个,分别用来保存组、用户、密码等信息到目录的条目中。
posixGroup:可设置属性cn、userPassword、gidNumber等。
posixAccount:可设置属性cn、gidNumber、uid、uidNumber、homeDirectory、loginShell等。
shadowAccount:可设置属性uid、shadowExpire、shadowFlag、shadowInactive、shadowLastChange、shadowMax、shadowMin、shadowWarning、userPassword等。
提示:从上面列出的属性的名称能够很容易地与组、用户的相关信息联系起来。
使用迁移工具
要使用LDAP进行用户认证,首先应该考虑的就是数据迁移的工做量。若是要操做员从/etc/passwd和/etc/group文件中逐个将信息从新录入,工做量将很是大。
OpenLDAP为用户考虑到了这些迁移工做,提供了多个迁移工具的脚本程序,这些程序位于/usr/share/openldap/migration/目录中,在该目录中有不少扩展名为pl和sh的脚本文件,经过这些迁移工具,能够很方便地将系统中的用户迁移到LDAP目录数据库中。下面介绍具体的迁移步骤。
【例子】 将系统中的用户信息迁移到LDAP目录数据库中。
具体操做步骤以下:
(1)修改/usr/share/openldap/migration/migrate_common.ph文件,在其中查找如下内容:
$DEFAULT_BASE="dc=padl,dc=com";
将其修改成目录服务器使用的根,如本章使用的例子要改成如下形式:
$DEFAULT_BASE="dc=dlw,dc=com";
保存后退出。
(2)使用如下命令执行脚本migrate_base.pl,用来建立根项,并为Hosts、Networks、Group和People等建立低一级的组织单元(执行该命令将生成base.ldif文件):
#./migrate_base.pl > base.ldif
(3)因为本章前面已在LDAP服务器中建立了根项“dc=dlw,dc=com”,所以将base.ldif文件中的第1个条目删除,另外,在用户认证中只用到组和用户,也将其余无关条目删除,只保存如下内容(例子):
dn: ou=People,dc=dlw,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit
dn: ou=Group,dc=dlw,dc=com
ou: Group
objectClass: top
objectClass: organizationalUnit
(4)使用如下命令将base.ldif文件中的条目导入目录数据库:
# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f base.ldif
执行结果以下图所示。
(5)开始迁移组信息。使用如下命令将/etc/group中的组信息保存到临时文件group.tmp中:
#cat /etc/group > group.tmp
(6)系统组不导入LDAP目录数据库中,所以需对group.tmp文件中的信息进行编辑,只保留须要导入LDAP目录数据库的组的信息。
(7)使用如下命令将组的数据生成LDIF条目信息:
#./migrate_group.pl group.tmp > group.ldif
(8)使用cat命令查看group.ldif的内容,可看到已按posixGroup这种objectClass将组的数据组织完成,以下图所示。
(9)相似地,使用如下命令导出/etc/passwd中的用户数据,并删除不须要的用户,而后使用migrate_passwd.pl脚本生成LDIF文件:
#cat /etc/passwd > passwd.tmp
#./migrate_passwd.pl passwd.tmp > passwd.ldif
#cat passwd.ldif
提示:从上面列出的属性的名称能够很容易地与组、用户的相关信息联系起来。
(10)使用如下命令将组和用户信息导入目录数据库:
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif
执行以上命令的过程以下图所示。
(11)使用如下命令查看目录数据库中用户root的信息,用“uid=root”做查询条件:
#ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'
查找结果以下图所示。
经过以上的操做,就将须要导入的组和用户的信息导入到了目录数据库中,接下来还须要对客户端进行设置,使用LDAP进行登陆验证操做。
设置客户端登陆
若客户端要使用LDAP进行用户登陆认证,则可以使用本地计算机中不存在的用户名进行登陆操做。
【例子】 修改配置文件,设置客户端使用LDAP进行认证。
具体操做步骤以下:
(1)修改客户端计算机中的/etc/sysconfig/authconfig文件,将如下项都修改成yes:
USELDAP=yes
USELDAPAUTH=yes
USEMD5=no
USESHADOW=yes
USELOCAUTHORIZE=yes
(2)修改客户端计算机中的/etc/openldap/ldap.conf文件,修改内容以下:
host 192.168.14.20
BASE dc=dlw,dc=com
ssl off
(3)修改客户端计算机中的/etc/nsswitch.conf文件,在passwd、shadow、group后面都加上ldap,以下图所示。
通过以上配置之后,在客户端就可使用LDAP目录数据库中的用户信息在客户端进行登陆操做了。登陆操做与使用本地用户帐号相同,这里就再也不演示了。
LDAP Schema
Schema是LDAP的一个重要组成部分,相似于数据库的模式定义,LDAP的Schema定义了LDAP目录所应遵循的结构和规则,好比一个 objectclass会有哪些属性,这些属性又是什么结构等等,schema给LDAP服务器提供了LDAP目录中类别,属性等信息的识别方式,让这些能够被LDAP服务器识别。
在LDAP的schema中,有四个重要的元素:
Objectclass
objectclass定义了一个类别,这个类别会被不一样的目录(在LDAP中就是一个Entry)用到,它说明了该目录应该有哪些属性,哪些属性是必须的,哪些又是可选的。一个objectclass的定义包括名称(NAME),说明(DESC),类型(STRUCTURAL或AUXILARY ,表示是结构型的仍是辅助型的),必须属性(MUST),可选属性(MAY)等信息。
Objectclass格式:
objectclass = ( whsp
numericoid whsp //全局惟一的 OID
[ "NAME" qdescrs ] //类名称
[ "DESC" qdstring ] //类描述
[ "OBSOLETE" whsp ]
[ "SUP" oids ] ; //父类
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
[ "MUST" oids ] ; //必填属性集合
[ "MAY" oids ] //选填属性集合
whsp ")"
例如:
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser'
DESC 'KunMail-LDAP User'
SUP top
STRUCTURAL
MUST(username$cn$vuid$vgid)
MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))
这里kunmailUser这种数据,要包含maildir $ home $ clearpw $ forwardAddr $ quota $ storeHost $ delivery $ mailReplyText $ active等可选项,还要包括username $ cn $ vuid $ vgid 必选项。 可选项用MAY()来包含,必选项用MUST()来包含。DESC是说明项。SUP表示父类(有点像面向对象编程啊)top表示没有父类,他本身是顶级。STRUCTURAL是存储方式。通常来讲每一个节点都要包含一个ABSTRACT类("top" or "alias"), 至少一个STRUCTURAL类,0个或者多个AUXILIARY类。AUXILIARY表示辅助型、STRUCTURAL表示结构型(默认)、ABSTRACT表示摘要型。
下面定义一个容许将myPhoto增长到任何已经存在的条目中的auxiliary对象类:
objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'
DESC 'mixin myPhoto'
AUXILIARY
MAY myPhoto )
若是您的组织须要一个私有的结构化对象类来表示用户,你能够子类化任何一个已经存在的person类,好比inetOrgPerson(RFC2798),而后增长须要的属性:
objectclass =( 1.1.2.2.2 NAME 'myPerson'
DESC 'my person'
SUP inetOrgPerson
MUST ( 'myUniqueName' $ 'givenName' )
MAY 'myPhoto' )
该对象类从inetOrgPerson中继承容许的或者必须的属性,可是,要求myUniqueName和givenName,容许myPhoto。
Attribute
attribute就是一个上面objectclass中可能包含的属性,对其的定义包括名称,数据类型,单值仍是多值以及匹配规则等。后面用具体的例子来讲明。
Attribute格式:
attributeType ( whsp
numericoid whsp //全局惟一的 OID
[ "NAME" qdescrs ] //属性名称
[ "DESC" qdstring ] //属性描述
[ "OBSOLETE" whsp ]
[ "SUP" woid ] //本属性从其它属性中派生出来的
[ "EQUALITY" woid //相等性匹配
[ "ORDERING" woid//顺序匹配
[ "SUBSTR" woid ] //字符串匹配
[ "SYNTAX" whsp noidlen whsp ] //字段的数据类型的OID
[ "SINGLE-VALUE" whsp ] //定义本属性为单值(默认多值)
[ "COLLECTIVE" whsp ] //default not collective
[ "NO-USER-MODIFICATION" whsp ]//default user modifiable
[ "USAGE" whsp AttributeUsage ]//default userApplications
whsp ")"
AttributeUsage =
"userApplications" /
"directoryOperation" /
"distributedOperation" / ; DSA-shared
whsp是空格的意思(' ')。numericoid 是全局惟一的 OID,是带.的十进制形式 (e.g. 1.1.0), qdescrs有一个或几个意思, woid 可使名称或者是 OID 可选择的必定长度的后缀(e.g {10})。
例如,属性类型name和cn在core.schema中以下定义:
attributeType ( 2.5.4.41 NAME 'name'
DESC 'name(s) associated with the object'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )
DESC 'common name(s) assciated with the object'
SUP name )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota'
DESC 'The amount of space the user can use until all further messages get bounced.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
SINGLE-value )
请注意,每个都定义了属性的OID,给出了一个短的名称,以及一个简短的描述。每个名称都是OID的一个别名。Slapd(8)在返回结果的时候,将返回第1个列出的名称。
第1个名称,name,保存了directoryString(UTF-8编码的Unicode)语法。该语法由OID说明。(1.3.6.1.4.1.1466.115.121.1.15标识了目录字符串语法)。还说明了一个推荐长度为32768的选项。服务器应该支持该长度的值,可是,也能够支持更长的值。该域没有指明长度限制,所以,在服务器上被忽略,而且服务器不会限制其大小。另外,相等和子串匹配使用不区分大小写的规则。下面是常用的语法和匹配规则(OpenLDAP支持这些,以及更多)
第2个属性,cn,是name的一个子类型,所以,它继承了语法,匹配规则,而且使用name.commonName做为别名。
两个属性都没有限制到单一值。均可以被用户应用程序所使用,都不存在过时,都不是集合。
不少组织为用户保留惟一的名字(unique name),虽然用户可使用displayName,可是这个属性(name)依旧由用户控制。而不是organization。咱们能够从 inetorgperson.schema 拷贝displayName ,替换OID,name,和描述(description)。
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
DESC 'unique name with my organization'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
可是,若是咱们要使name属性包含一个断言,这个属性能够被定义为name的子属性。
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
DESC 'unique name with my organization'
SUP name )
不少的组织为每个用户保留一个头像。myPhoto属性类型的定义能够用来保存用户的头像。固然用户能够选择jpegPhoto属性类型(RFC2798)(或其子类型)来保存头像。固然你只能在图片符合JPEG File Interchange Format时使用。
固然,一个使用八进制语法的属性类型能够这样的定义:
attributetype ( 1.1.2.1.2 NAME 'myPhoto'
DESC 'a photo (application defined format)'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
SINGLE-VALUE )
在这,语法中并无置顶photo的格式(format),这里假设访问属性的应用能够对其值进行处理。
若是你想支持多种图片格式,你须要为每个格式定义属性类型。为图片添加类型信息的前缀。或者使用ASN.1描述值,和use the ;binary transfer option。
可使图片属性可以保存URI,你能够在labeledURI(RFC2079)后建立一个属性,或者建立一个子类型。
attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
DESC 'URI and optional label referring to a photo'
SUP labeledURI )
Syntax
syntax是LDAP中的“语法”,其实就是LDAP中会用到的数据类型和数据约束,这个语法是听从X.500中数据约束的定义的。其定义须要有一个ID(听从X.500)以及说明(DESP)
Commonly Used Syntaxes |
||
Name |
OID |
Description |
boolean |
1.3.6 .1.4.1.1466.115.121.1.7 |
boolean value |
distinguishedName |
1.3.6.1.4.1.1466.115.121.1.12 |
DN |
directoryString |
1.3.6.1.4.1.1466.115.121.1.15 |
UTF-8 string |
IA5String |
1.3.6.1.4.1.1466.115.121.1.26 |
ASCII string |
Integer |
1.3.6.1.4.1.1466.115.121.1.27 |
integer |
Name and Optional UID |
1.3.6.1.4.1.1466.115.121.1.34 |
DN plus UID |
Numeric String |
1.3.6.1.4.1.1466.115.121.1.36 |
numeric string |
OID |
1.3.6.1.4.1.1466.115.121.1.38 |
object identifier |
Octet String |
1.3.6.1.4.1.1466.115.121.1.40 |
arbitary octets |
Printable String |
1.3.6.1.4.1.1466.115.121.1.44 |
printable string |
Matching Rules
是用来指定某属性的匹配规则,实际上就是定义一个特殊的Syntax的别名,让LDAP服务器能够识别,并对定义的属性进行匹配。
Commonly Used Matching Rules |
||
Name |
Type |
Description |
booleanMatch |
equality |
boolean |
octetStringMatch |
equality |
octet string |
objectIdentiferMatch |
equality |
OID |
distinguishedNameMatch |
equality |
DN |
uniqueMemberMatch |
equality |
Name with optional UID |
numericStringMatch |
equality |
numerical |
numericStringOrderingMatch |
ordering |
numerical |
numericStringSubstringsMatch |
substrings |
numerical |
caseIgnoreMatch |
equality |
case insensitive, space insensitive |
caseIgnoreOrderingMatch |
ordering |
case insensitive, space insensitive |
caseIgnoreSubstringsMatch |
substrings |
case insensitive, space insensitive |
caseExactMatch |
equality |
case sensitive, space insensitive |
caseExactOrderingMatch |
ordering |
case sensitive, space insensitive |
caseExactSubstringsMatch |
substrings |
case sensitive, space insensitive |
caseIgnoreIA5Match |
equality |
case insensitive, space insensitive |
caseIgnoreIA5OrderingMatch |
ordering |
case insensitive, space insensitive |
caseIgnoreIA5SubstringsMatch |
substrings |
case insensitive, space insensitive |
caseExactIA5Match |
equality |
case sensitive, space insensitive |
caseExactIA5OrderingMatch |
ordering |
case sensitive, space insensitive |
caseExactIA5SubstringsMatch |
substrings |
case sensitive, space insensitive |
LDAP的schema的主要元素就是这些了,下面列举出了一些LDAP规定好的或是如今比较通用的schema,通常的LDAP服务器都应该能够识别这些定义。
这就是一个名为subschema的objectclass的定义:
objectclass=(2.5.20.1 NAME 'subschema' AUXILIARY
MAY ( dITStructureRules $ nameForms $ ditContentRules $
objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )
首先是ID,这里是2.5.20.1,接着是NAME,AUXILIARY说明是辅助型,以后是可选属性的定义,subschema中没有定义必须属性,若是须要定义,应该和MAY同样,将属性放在MUST()中并用$隔开
再来看一个属性定义:
attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )
能够看到cn属性的父属性是name,它相等性匹配于caseIgnoreMatch(匹配原则为EQUALITY,还有如SUBSTR是字符串匹配,ORDERING是顺序匹配)
syntax定义通常都比较简单,如:
( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'String' )
这个定义说明,这一串数字1.3.6.1.4.1.1466.115.121.1.5就表明了LDAP中的字符串,这个数字串的定义和X.500相关,包括了它的存储方式,所占空间大小等。
最后看看Matching Rule的例子,前面提到了caseIgnoreMatch,就看他的吧
attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
其实1.3.6.1.4.1.1466.115.121.1.15 就是LDAP数据类型Directory String的ID,说明前面的cn须要等于这个数据类型才有效。 还有不少经常使用schema的定义都在了RFC2252中,LDAP服务器都应该支持这些基本的schema。好了,如今基本对LDAP中的schema有个一个大体的说明,可能有不到位或不妥之处,还望你们指正。