一、前言
在我刚接触 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
注意
- 不同版本的 Linux 安装方法差别非常大!
- 此次安装目的是快速搭建一个 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 端口转发来访问的。
打开浏览器,访问 http://127.0.0.1/phpldapadmin ,然后按图片中的提示登录即可。
配置完成后的效果如下:
六、参考文献
- SegmentFault - LDAP服务器的概念和原理简单介绍
- ITeye.com - LDAP基础
- 开源中国 - openldap+phpldapadmin
- CSDN - Linux下LDAP Server/Client配置 --OpenLDAP
- Virginia Jean - OpenLDAP 在 CentOS 7 上的极速搭建步骤
- dzhorov.com - Installing and configuring OpenLDAP on CentOS 7
- CSDN - 搭建ldap,samba和nfs 统一认证服务