LDAP(Lightweight Directory Access Protocol)代表轻型目录访问协议,是用来访问目录服务(如基于X.500的目录服务)的轻型协议,它运行在TCP/IP或其他面向连接的传输服务之上。LDAP目录基于客户/服务器方式实现。
LDAP的信息模型是建立在“条目”(entries)的基础上。一个条目是一些属性的集合,并且具有一个全局唯一的“可区分名称”DN,一个条目可以通过DN来引用。每一个条目的属性具有一个类型和一个或者多个值。类型通常是容易记忆的名称,比如“cn”是通用名称(common name) ,或者“mail”是电子邮件地址。条目的值的语法取决于属性类型。比如,cn属性可能具有一个值“Babs Jensen” 。一个mail属性可能包含“[email protected]” 。一个jpegphoto属性可能包含一幅JPEG(二进制)格式的图片。 各个元素之间的关系如图一所示:
LDAP通过属性objectClass来控制哪一个属性必须出现或允许出现在一个条目中,它的值决定了该条目必须遵守的模式规则。
关键字 |
英文全称 |
含义 |
dc |
Domain Component |
域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com |
uid |
User Id |
用户ID,如“tom” |
ou |
Organization Unit |
组织单位,类似于Linux文件系统中的子目录,它是一个容器对象,组织单位可以包含其他各种对象(包括其他组织单元),如“market” |
cn |
Common Name |
公共名称,如“Thomas Johansson” |
sn |
Surname |
姓,如“Johansson” |
dn |
Distinguished Name |
惟一辨别名,类似于Linux文件系统中的绝对路径,每个对象都有一个惟一的名称,如“uid= tom,ou=market,dc=example,dc=com”,在一个目录树中DN总是惟一的 |
rdn |
Relative dn |
相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson” |
c |
Country |
国家,如“CN”或“US”等。 |
o |
Organization |
组织名,如“Example, Inc.” |
包括:查询目录、更新目录、增加条目、删除条目、改变条目名称,搜索信息,最常用的LDAP操作是搜索信息操作。LDAP搜索操作允许搜索目录的一部分,查找匹配某个搜索过滤器规则的条目,搜索在 dc=example,dc=com 条目之中或者之下的整个目录子树,查找一个名字叫做 Barbara Jensen 的个人,并且获取每一个找到的条目的电子邮件地址。
(1) Berkeley DB安装
因为OpenLDAP将数据存放在数据库中,因此安装部署OpenLDAP之前首先要安装BerkeleyDB。该数据库可以在Oracle的官方网站上下载到,下载地址为:http://www.oracle.com/technetwork/database/berkeleydb/downloads/index-082944.html
安装数据库步骤:
1) # tar zxvfdb-5.2.36.tar.gz 或者 # unzip db-5.2.36.NC.zip
2) # cd db-5.2.36/build_unix
3) # ../dist/configure //默认安装在/usr/local目录下可以通过../dist/configure–prefix=你的路径
4) # make //开始安装
5) # make install
(2) Berkeley DB配置
安装OpenLDAP过程中,在./configure时,遇到错误checking if Berkeley DB version supported by BDB/HDB backends… no configure: error: BerkeleyDB version incompatible with BDB/HDBbackends,这是因为没有安装Berkeley DB或是安装了Berkeley DB,但是系统找不到他的头文件和lib的库,这时需要添加一些环境变量,步骤如下:
1) # export CPPFLAGS=”-I/usr/local/BerkeleyDB.5.2/include”
2) # export LDFLAGS=”-L/usr/local/lib -L/usr/local/BerkeleyDB.5.2/lib-R/usr/local/BerkeleyDB.5.2/lib”
3) # export LD_LIBRARY_PATH=”/usr/local/BerkeleyDB.5.2/lib”
4) # env LDFLAGS=-L/usr/local/lib -L/usr/local/BerkeleyDB.5.2/lib-R/usr/local/BerkeleyDB.5.2/lib
HOSTNAME=mylinux
TERM=vt100
SHELL=/bin/bash
HISTSIZE=1000
CPPFLAGS=-I/usr/local/BerkeleyDB.4.8/include
SSH_CLIENT=::ffff:192.168.0.10 3336 22
OLDPWD=/apps/openldap
SSH_TTY=/dev/pts/2
USER=root
LD_LIBRARY_PATH=/usr/local/BerkeleyDB.4.8/lib
安装之前首先要下载OpenLDAP,下载地址http://www.openldap.org/software/download/
1) [root@localhost tmp]# tar zxvf openldap-stable-20120311.tgz
2) [root@localhost tmp]# cd openldap-2.4.30
3) [[email protected]]# ./configure --prefix=/usr/local/openldap --enable-bdb
注:--prefix用于更改安装目录,默认安装在/usr/local下
Making servers/slapd/backends.c
Add config ...
Add ldif ...
Add monitor ...
Add bdb ...
Add hdb ...
Add relay ...
Making servers/slapd/overlays/statover.c
Add seqmod ...
Add syncprov ...
Please run "make depend" to builddependencies
看到这些信息时,说明已经configure完毕。
4) [[email protected]]# make depend
Making depend in/apps/openldap/openldap-2.4.30
Entering subdirectory include
make[1]: Entering directory`/apps/openldap/openldap-2.4.30/include’
Making ldap_config.h
make[1]: Leaving directory`/apps/openldap/openldap-2.4.30/include’
….
Entering subdirectory man5
make[3]: Entering directory`/apps/openldap/openldap-2.4.30/doc/man/man5′
make[3]: Nothing to be done for `depend’.
make[3]: Leaving directory`/apps/openldap/openldap-2.4.30/doc/man/man5′
Entering subdirectory man8
make[3]: Entering directory`/apps/openldap/openldap-2.4.30/doc/man/man8′
make[3]: Nothing to be done for `depend’.
make[3]: Leaving directory`/apps/openldap/openldap-2.4.30/doc/man/man8′
make[2]: Leaving directory`/apps/openldap/openldap-2.4.30/doc/man’
make[1]: Leaving directory`/apps/openldap/openldap-2.4.30/doc’
5) [[email protected]]# make
……………………….
done
make[3]: Leaving directory`/apps/openldap/openldap-2.4.30/doc/man/man8′
make[2]: Leaving directory`/apps/openldap/openldap-2.4.30/doc/man’
make[1]: Leaving directory`/apps/openldap/openldap-2.4.30/doc’
注:make depend比较快,但是,make可能要花点时间
6) [[email protected]]# make test
该操作查看是否build成功,(整个过程会花上几分钟),如果成功,会显示如下信息:
>>>>> Test succeeded
>>>>>./scripts/test000-rootdse completed OK.
>>>>> Startingtest001-slapadd ...
running defines.sh
7) [[email protected]]# make install
注:运行make install开始安装,建议以源码安装的软件都放到独立的目录下,不要放在默认的路径下,要不然卸载的时候会很麻烦。安装到一个目录下,只要删除目录就可以卸载了。
OpenLDAP主配置文件slapd.conf,该配置文件一般保存在安装目录下的etc/openldap/目录下。它的初始内容如下
[root@localhost openldap]# cat slapd.conf
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/schema/core.schema
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /usr/local/var/run/slapd.pid
argsfile /usr/local/var/run/slapd.args
# Load dynamic backend modules:
# modulepath /usr/local/libexec/openldap
# moduleload back_bdb.la
# moduleload back_hdb.la
# moduleload back_ldap.la
# Sample security restrictions
# Require integrityprotection (prevent hijacking)
# Require 112-bit (3DESor better) encryption for updates
# Require 63-bitencryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyoneto read it
# Subschema (sub)entryDSE: allow anyone to read it
# Other DSEs:
# Allow selfwrite access
# Allowauthenticated users read access
# Allowanonymous users to authenticate
# Directives needed toimplement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g.,"access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#######################################################################
# 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 avoid. See slappasswd(8)and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /usr/local/var/openldap-data
# Indices to maintain
index objectClass eq
1) 设置LDAP使用的Schema
[root@localhost openldap]# vi slapd.conf
找到语句:
include /usr/local/etc/openldap/schema/core.schema
在该语句的后面添加以下语句:
include /usr/local/etc/openldap/schema/corba.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/dyngroup.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/java.schema
include /usr/local/etc/openldap/schema/misc.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/openldap.schema
2) 设置目录树的后缀
找到语句:
suffix "dc=my-domain,dc=com"
将其改为:
suffix "dc=example,dc=com"
3) 设置LDAP管理员的DN
找到语句:
rootdn "cn=Manager,dc=my-domain,dc=com"
将其改为:
rootdn "cn=root,dc=example,dc=com"
4) 设置LDAP管理员的口令
找到语句:
rootpw secret
将其改为:
rootpw 123456
注:修改密码的时候需要注意rootpw前面不能有空格,以及rootpw与密码之间用TAB键隔开。
5) #设置数据库的存放路径
# Indices to maintain
index objectClass eq
注:蓝色部分可以根据需要进行修改!!!
启动OpenLDAP服务需要执行以下命令:
#/usr/local/libexec/slapd
注:如果没有出错信息,直接返回shell,就说明服务器正常启动了。如果启动不成功,他会提示一些出错信息,多数是slapd.conf配置出错引起的。
执行命令:# pstree|grep"slapd"
如果出现 |-slapd---{slapd} 则说明slapd进程已经成功启动
测试访问目录的能力:
[root@localhost openldap]# ldapsearch -x-b '' -s base '(objectclass=*)' namingContexts
如果正确配置了服务器,应该看到类似于下面的输出(当然,有不同的 dc):
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: namingContexts
#
#
dn:
namingContexts: dc=example,dc=com
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
数据导入的方式主要有四种:1. 手工输入;2. .ldif文件格式录入;3. 脚本自动录入;4. 客户端工具录入。
(1) 手工输入
1) 创建DN
[root@localhost~]# ldapadd -x -D'cn=root,dc=topsec,dc=com' -W
Enter LDAP Password:
dn:dc=topsec,dc=com
objectclass:top
objectclass:domain
dc:topsec
o:Topsec,Inc 此处回车后按Ctrl+D将数据发送给服务器,并隐式取消与服务器的绑定
adding new entry "dc=topsec,dc=com"
2) 创建OU
[root@localhost~]# ldapadd -x -D 'cn=root,dc=topsec,dc=com' -W
Enter LDAP Password:
dn:ou=headerquarters,dc=topsec,dc=com
ou:headerquarters
objectclass:organizationalUnit 此处表明ou是必需的属性
adding new entry "ou=headerquarters,dc=topsec,dc=com"
3) 建立RDN
[root@localhost ~]# ldapadd -x -D 'cn=root,dc=topsec,dc=com' -W
Enter LDAP Password:
dn:cn=Ava Green,ou=test,dc=topsec,dc=com
cn:Ava
sn:Green
objectclass:inetOrgPerson
adding new entry "cn=Ava Green,ou=test,dc=topsec,dc=com"
ldap_add: No such object (32)
matched DN: dc=topsec,dc=com
注:出现此错误的原因是它的父节点还没有创建,需要先创建节点ou=test,dc=topsec,dc=com。
创建过程如下:
[root@localhost~]# ldapadd -x -D 'cn=root,dc=topsec,dc=com' -W
Enter LDAP Password:
dn:ou=test,dc=topsec,dc=com
ou:test
objectclass:organizationalUnit
adding new entry "ou=test,dc=topsec,dc=com"
接下来继续上述过程:
[root@localhost~]# ldapadd -x -D 'cn=root,dc=topsec,dc=com' -W
Enter LDAP Password:
dn:cn=Ava Green,ou=test,dc=topsec,dc=com
cn:Ava
sn:Green
objectclass:inetOrgPerson
adding new entry "cn=Ava Green,ou=test,dc=topsec,dc=com"
成功~\(≧▽≦)/~啦啦啦!!!!
注:上面概述的过程使用三个基本的 LDAP 操作:绑定操作、更新操作和隐式取消绑定操作。
(2) 文件输入
将数据插入 LDAP 目录的第二种方法是使用 LDIF 文件。LDIF 文件只是包含想要插入的以特定语法编排的数据的纯文本文档。上面我们已经熟悉了语法:dn: 后跟树中存储项的位置,然后跟一个或多个 RDN 项(包含数据的类型/值对),后跟必需的对象类。要创建 LDIF,使用纯文本编辑器,然后输入想要添加到目录中的数据。
以下是示例文件example.ldif文件的内容:
dn:dc=topsec,dc=com
objectclass:top
objectclass:domain
dc:topsec
o:Topsec,Inc
dn:ou=managers,dc=topsec,dc=com
ou:managers
objectclass:organizationalUnit
dn:cn=Kevin,ou=managers,dc=topsec,dc=com
cn:Kevin
sn:Black
objectclass:person
dn:ou=employees,dc=topsec,dc=com
ou:employees
objectclass:organizationalUnit
dn:cn=Mary,ou=employees,dc=topsec,dc=com
cn:Mary
sn:Brown
objectclass:person
[root@localhost ~]#ldapadd -x -D 'cn=root,dc=topsec,dc=com' -W -f example.ldif
Enter LDAPPassword:
adding newentry "ou=managers,dc=topsec,dc=com"
adding newentry "cn=Kevin,ou=managers,dc=topsec,dc=com"
adding newentry "ou=employees,dc=topsec,dc=com"
adding newentry "cn=Mary,ou=employees,dc=topsec,dc=com"
此方法的优点:
1) 在将文件导入数据库之前,可以检查拼写和语法;
2) 可以创建带有许多项的 LDIF 文件,然后用一个操作将它们添加到目录中;
3) 如果导入失败,只要打开 LDIF文件,查找错误,并尝试重新导入即可;
4) LDIF 文件是一种开放标准,几乎可以将它们导入到任何目录服务器中。
此方法的缺点:
1) 该过程仍需要较大的工作量------必须输入LDIF 中的所有项,并遵循正确的语法;
2) 当 LDAP 服务器遇到导入文件中的错误时,它并不总是能方便地处理。虽然您可能会得到一条“syntax error(语法错误)”消息,但它不会给出,在一个相当大的 LDIF 文件中,错误在哪里。
(3) 脚本自动录入
可以使用通常用 Perl 或 PHP 编写的脚本,它们的目的是接收数据并将它“自动”放到 LDAP 目录中。
这种方法存在的问题。首先,也是最重要的,我亲自尝试过的任何脚本都有许多可恶的错误,在某些最坏的情形下,会在导入期间毁坏您的数据或者破坏目录树本身。其次,使用脚本导入数据假设数据已经以某种形式存在。当分别从 /etc/passwd 和 /etc/groups 导入用户密码和组信息时,这当然很好,但您的联系人信息可能不是通常可识别的格式。毕竟,本教程的主要目的是使联系人信息不受专用格式的支配。
如果将联系信息数据导出成纯文本、用逗号分隔的文件,并找到能够将数据导入 LDAP 目录的脚本,会怎么样呢?如果可以找到这种脚本,并且如果它运行得如它所宣称的那样,则您会得到所有的功能。请记住,电子邮件客户机对“用逗号分隔的文件”有其自己精确的解释。要在每行结束的地方添加回车吗?导出程序如何处理嵌入字段中的空格?某些人通常窃用 LDAP 导入脚本来将他们的数据从应用程序 A(已经以格式 X 导出)传送到 LDAP 目录。如果他们的应用程序和导出格式与您的相合,则尝试它。不过要确保先备份您的目录数据库,这样,如果导入失败,就可以返回到“已知的好”状态。
(4) 客户端工具录入
ldap客户端的工具很多,linux平台有一个基于php编写的phpldapadmin、windows平台也有一个比较好的工具ldapadmin。下图是LDAP数据库管理工具——ADS(Apache Directory Studio)它的下载地址是http://directory.apache.org/studio/downloads.html。
输入以下命令,可查询已经输入的信息:
[root@localhost ~]# ldapsearch -x -b'ou=test,dc=topsec,dc=com'
查询结果如下所示:
# extended LDIF
#
# LDAPv3
# base
# filter:(objectclass=*)
# requesting:ALL
#
# test,topsec.com
dn:ou=test,dc=topsec,dc=com
ou: test
objectClass:organizationalUnit
# Ava Green,test, topsec.com
dn: cn=AvaGreen,ou=test,dc=topsec,dc=com
cn: Ava
cn: Ava Green
sn: Green
objectClass: inetOrgPerson
# search result
search: 2
result: 0Success
# numResponses:3
# numEntries: 2
[root@localhost ~]# ldapsearch -x -b'dc=topsec,dc=com'
# extended LDIF
#
# LDAPv3
# base
# filter:(objectclass=*)
# requesting:ALL
#
# topsec.com
dn:dc=topsec,dc=com
objectClass: top
objectClass:domain
dc: topsec
o: Topsec,Inc
#headerquarters, topsec.com
dn:ou=headerquarters,dc=topsec,dc=com
ou:headerquarters
objectClass:organizationalUnit
# test,topsec.com
dn:ou=test,dc=topsec,dc=com
ou: test
objectClass:organizationalUnit
# Ava Green,test, topsec.com
dn: cn=AvaGreen,ou=test,dc=topsec,dc=com
cn: Ava
cn: Ava Green
sn: Green
objectClass:inetOrgPerson
# managers,topsec.com
dn: ou=managers,dc=topsec,dc=com
ou: managers
objectClass:organizationalUnit
# Kevin,managers, topsec.com
dn:cn=Kevin,ou=managers,dc=topsec,dc=com
cn: Kevin
sn: Black
objectClass:person
# employees,topsec.com
dn:ou=employees,dc=topsec,dc=com
ou: employees
objectClass:organizationalUnit
# search result
search: 2
result: 0Success
# numResponses:8
# numEntries: 7