LDAP 基础学习笔记(概念 & 快速安装)

一、前言

在我刚接触 Windows Server 的时候,就老看到“目录”这个东西。

当时由于懒,而且没有使用的需求,就一直没了解它,后来用 Linux 之后就完全忘了有“目录”这个东西。

直到前些天在一本书上了解到,原来目录服务能干很多事情,我才想起来,然后开始学习……

我觉得,目录服务的基本概念不是也别容易理解,不是一篇文章就能把它了解透彻的。

本文纯属个人学习经验分享,仅供参考。如有错误请及时提出,谢谢!

二、目录服务简介

目录简单来说就是一种树状结构的数据库。

而目录服务是一种以树状结构的目录数据库为基础,外加各种访问协议的信息查询服务。

顾名思义,目录天生就是用来查询的。

与关系型数据库(如 MariaDB)相比,目录服务最大的优点就是读取性能极高。

但是,目录服务的写入性能就非常差了,而且不支持事务处理等容错功能,因此不适合频繁修改数据。

在现实世界中,资源的分布形式很多都是树状的、有层次的。因此,目录服务有着非常广泛的用途。

像企业员工信息、企业设备信息、证书公钥等具有层次性、且不需要频繁改写的数据都适合使用目录服务来存储。

X.500 是 ISO 制定的一套目录服务的标准,它是一个协议族,定义了一个机构如何在全局范围内共享名称和与名称相关联的对象。通过它,可以将局部的目录服务连接起来,构建基于 Internet 的分布在全球的目录服务系统……而目录访问协议(DAP)是 X.500 的核心组成之一。

三、LDAP 简介

DAP 非常复杂,所以人们都不喜欢使用它。

所以,轻量级目录访问协议(LDAP)应运而生!LDAP 是基于 X.500 的 DAP 发展而来的,目前最新版本是第 3 版。

LDAP 协议的主要特点如下:

  • 基于 TCP/IP。
  • 以树状结构存储数据。
  • 读取速度快,写入速度慢。
  • 服务器用于存放数据,客户端用于操作数据。
  • 跨平台、维护简单。
  • 支持 SSL/TLS 加密。
  • 协议是开放的。

LDAP 的四大模型:

  • 信息模型:规定了 LDAP 目录信息的表示方式以及数据的存储结构。
  • 命名模型:规定了 LDAP 目录中数据如何进行组织和区分。
  • 功能模型:规定了可以对 LDAP 目录进行的操作(如查询、更新、认证等)。
  • 安全模型:规定了保护 LDAP 目录中的数据的安全措施。

基于 LDAP 协议的产品有很多,最有名两个的是开源的 OpenDirectory 以及微软开发的 ActiveDirectory。

四、LDAP 基本结构和相关术语

4.1 基本结构


上图表示的就是一颗 LDAP 目录树。

4.2 条目(Entry)

4.1 的图中的每一个方框就是一个条目。

一个条目有若干个属性和若干个值。有些条目还能包含子条目。

4.3 识别名(Distinguished Name, DN)

它表示条目在目录树中从根出发的绝对路径,是条目的唯一标识。

可以跟 UNIX 文件系统中文件或目录的完整路径做类比。

例如:4.1 的图中右下角的条目的 DN 是 cn=group1,dc=zenandidi,dc=com

4.4 相对识别名(Relative Distinguished Name, RDN)

相对识别名就是识别名第一个逗号左侧的内容。

可以跟 UNIX 文件系统中文件或目录名做类比。

例如:4.1 的图中右下角的条目的 RDN 是 cn=group1

在一般情况下,RDN 以 dc=ou=c=o= 开头的条目为容器。也就是说,它们可以包含子条目。

4.5 基准识别名(Base Distinguished Name, Base DN)

一般指整个目录树的根。

例如,4.1 的图的 Base DN 是 dc=zenandidi,dc=com

4.6 模式(Schema)

模式是对象类(ObjectClass)、属性类型(AttributeType)、属性语法(Syntax)和匹配规则(MatchingRules)的集合。

可以跟关系型数据库的数据表结构做类比。

LDAP 协议定义了一些标准的模式,一般直接使用即可。用户也可以根据自己的需求自行定义模式。

4.6.1 对象类(ObjectClass)

学过面向对象编程语言的人都知道,类是属性的封装。

对象类封装了必选的属性和可选的属性,同时对象类也是支持继承的。

通过对象类可以很方便地指定条目的类型。一个条目也可以绑定多个对象类。

对象类又分为了结构类型(Structural)、抽象类型(Abstract)、辅助类型(Auxiliary)这三类。

下图是一个对象类所包含的内容。

4.6.2 属性类型(AttributeType)

属性类型定义了属性值的设定规则(属性语法),以及同一个属性的各个数据相互比较的规则等。

下图是一个属性类型包含的内容。

4.6.3 属性语法(Syntax)

下图是 LDAP 协议预定义的一些属性语法,例如二进制、字符串、电话号码类型等。

4.6.4 匹配规则(MatchingRule)

这个我把它理解为各种类型属性的集合。

下图是 LDAP 协议预定义的一些匹配规则。

4.7 LDIF(LDAP Data Interchange Format) 文件

LDAP 数据交换格式文件,它以文本形式存储,用于在服务器之间交换数据。

添加数据以及修改数据都需要通过 LDIF 文件来进行。

可以跟关系型数据库的 SQL 文件做类比。

LDIF 文件的格式一般如下:

dn: <识别名>
<属性 1>: <值 1>
<属性 2>: <值 2>
...

五、在 CentOS 7 上安装并使用 OpenLDAP

注意
  1. 不同版本的 Linux 安装方法差别非常大!
  2. 此次安装目的是快速搭建一个 LDAP 学习和测试环境,没有进行其他高级配置。建议使用虚拟机和全新安装的系统进行操作。

5.1 所需软件 & 环境

  • 操作系统:CentOS 7.4.1708 最小安装(已关闭 SELinux 和防火墙)
  • 应用软件:openldap 2.4.44 、phpldapadmin 1.2.3

5.2 安装 OpenLDAP

yum install -y openldap-clients openldap-servers 

5.3 创建数据库配置文件

直接套用模版即可。

cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG && chown ldap:ldap /var/lib/ldap/DB_CONFIG 

5.4 启动 OpenLDAP 服务

systemctl start slapd 

如需开机启动,请执行以下命令。

systemctl enable slapd 

如果没有出现错误,那么 OpenLDAP 的安装就算完成了,不过当前的目录数据库还是空的,下面我们要对数据库进行初始化。

5.5 设置 OpenLDAP 管理员密码

5.5.1 生成密码

slappasswd 

执行完该命令之后,请输入您要设定的密码。然后会生成 {SSHA}xxxxx 这样一行东西,请把它记下来。

5.5.2 生成 LDIF 文件

cat << EOF > chrootpw.ldif 

请按实际情况以及注释提示修改以下内容,完成去除 # 号和后面的注释,然后粘贴到命令行窗口中按回车即可。

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}xxxxx  #{SSHA}xxxxx 修改为上一步记下来的值
EOF 

5.5.3 执行 LDIF 文件

ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif 

5.6 导入预设的模式

find /etc/openldap/schema/ -name "*.ldif" -exec ldapadd -Y EXTERNAL -H ldapi:/// -D "cn=config" -f {} \; 

5.7 新建一个根节点

5.7.1 生成根节点管理员密码

注意
  • 根节点管理员密码与 OpenLDAP 管理员密码不是同一回事!一个 LDAP 数据库可以包含多个目录树。
slappasswd 

执行完该命令之后,请输入您要设定的密码。然后会生成 {SSHA}xxxxx 这样一行东西,请把它记下来。

5.7.2 生成 LDIF 文件

首先请想好一个域名。比如我使用的是 zenandidi.com

zenandidi.com 为例,下面根节点的 DN 应该这样写:dc=zenandidi,dc=com

cat << EOF > chdomain.ldif 

请按实际情况以及注释提示修改以下内容,完成去除 # 号和后面的注释,然后粘贴到命令行窗口中按回车即可。

dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
  read by dn.base="cn=Manager,dc=xxx,dc=xxx" read by * none #修改 dc=xxx,dc=xxx 为自己的域名

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=xxx,dc=xxx    #修改 dc=xxx,dc=xxx 为自己的域名

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=xxx,dc=xxx #修改 dc=xxx,dc=xxx 为自己的域名

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}xxxxx  #{SSHA}xxxxx 修改为上一步记下来的值

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
  dn="cn=Manager,dc=xxx,dc=xxx" write by anonymous auth by self write by * none #修改 dc=xxx,dc=xxx 为自己的域名
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,dc=xxx,dc=xxx" write by * read #修改 dc=xxx,dc=xxx 为自己的域名
EOF 

5.7.3 执行 LDIF 文件

ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif 

5.8 添加用户、组节点

5.8.1 生成 LDIF 文件

cat << EOF > basedomain.ldif 

请按实际情况以及注释提示修改以下内容,完成去除 # 号和后面的注释,然后粘贴到命令行窗口中按回车即可。

dn: dc=xxx,dc=xxx   #修改 dc=xxx,dc=xxx 为自己的域名
objectClass: top
objectClass: dcObject
objectclass: organization
o: root_ldap
dc: xxx #修改 xxx 为自己域名第一个点左边的内容

dn: cn=Manager,dc=xxx,dc=xxx    #修改 dc=xxx,dc=xxx 为自己的域名
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=xxx,dc=xxx #修改 dc=xxx,dc=xxx 为自己的域名
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=xxx,dc=xxx  #修改 dc=xxx,dc=xxx 为自己的域名
objectClass: organizationalUnit
ou: Group
EOF 

5.8.2 执行 LDIF 文件

请先修改下面命令的 dc=xxx,dc=xxx 为自己的域名然后再执行。

ldapadd -x -D cn=Manager,dc=xxx,dc=xxx -W -f basedomain.ldif 

然后需要输入 5.7.1 设定的根节点管理员密码。

5.9 清理 LDIF 文件

rm basedomain.ldif chdomain.ldif chrootpw.ldif 

至此,一个 LDAP 目录树就构建完毕了。

但是 LDAP 的命令行管理工具非常难用,尤其是对于新手来说。

所以,下面我们来安装 phpLDAPadmin 这个图形化管理工具,方便新手学习。

5.10 安装 phpLDAPadmin

5.10.1 安装主程序

yum -y install phpldapadmin 

5.10.2 修改配置文件

vi /etc/phpldapadmin/config.php 

请按实际情况以及注释提示修改以下内容,完成去除 # 号和后面的注释,在命令行窗口中按下 G(大写),然后按下 O(大写),将上面修改的内容直接粘贴到命令行窗口中,再按下 ESC ,最后输入 :wq按回车。

$servers = new Datastore();
$servers->newServer('ldap_pla');
$servers->setValue('server','name','My LDAP Server');
$servers->setValue('server','host','127.0.0.1');
$servers->setValue('server','port',389);
$servers->setValue('server','base',array('dc=xxx,dc=xxx')); #修改 dc=xxx,dc=xxx 为自己的域名
$servers->setValue('login','auth_type','session');
$servers->setValue('login','bind_id','cn=Manager,dc=xxx,dc=xxx');   #修改 dc=xxx,dc=xxx 为自己的域名
$servers->setValue('login','bind_pass','<密码>'); #填入 5.7.1 设定的根节点管理员密码
$servers->setValue('server','tls',false); 

5.10.3 启动 httpd 服务

systemctl start httpd 

如需开机启动,请执行以下命令。

systemctl enable httpd 

5.10.4 登录 phpLDAPadmin & 完成

注意
  • 默认情况下 phpLDAPadmin 只允许 127.0.0.1 本地访问。由于我不熟悉 apache 的配置文件,所以我是直接使用 SSH 端口转发来访问的。

打开浏览器,访问 127.0.0.1/phpldapadmin ,然后按图片中的提示登录即可。

配置完成后的效果如下:

六、参考文献

  1. SegmentFault - LDAP服务器的概念和原理简单介绍
  2. ITeye.com - LDAP基础
  3. 开源中国 - openldap+phpldapadmin
  4. CSDN - Linux下LDAP Server/Client配置 --OpenLDAP
  5. Virginia Jean - OpenLDAP 在 CentOS 7 上的极速搭建步骤
  6. dzhorov.com - Installing and configuring OpenLDAP on CentOS 7
  7. CSDN - 搭建ldap,samba和nfs 统一认证服务
编辑于 2019-05-20

文章被以下专栏收录