介绍

LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。简单说来,LDAP是一个得到关于人或者资源的集中、静态数据的快速方式。 LDAP是一个用来发布目录信息到许多不同资源的协议。通常它都作为一个集中的地址本使用,不过根据组织者的需要,它可以做得更加强大。

现在市场上有关LDAP的产品已有很多,各大软件公司都在他们的产品中集成了LDAP服务,如Microsoft的ActiveDirectory、Lotus的Domino Directory、IBM的WebSphere中也集成了LDAP服务。LDAP的开源实现是OpenLDAP,它比商业产品一点也不差,而且源码开放。

OpenLDAP 是最常用的目录服务之一,它是一个由开源社区及志愿者开发和管理的一个开源项目,提供了目录服务的所有功能,包括目录搜索、身份认证、安全通道、过滤器等等。大多数的 Linux 发行版里面都带有 OpenLDAP 的安装包。OpenLDAP 服务默认使用非加密的 TCP/IP 协议来接收服务的请求,并将查询结果传回到客户端。由于大多数目录服务都是用于系统的安全认证部分比如:用户登录和身份验证,所以它也支持使用基于 SSL/TLS 的加密协议来保证数据传送的保密性和完整性。OpenLDAP 是使用 OpenSSL 来实现 SSL/TLS 加密通信的。

LDAP的信息模型是建立在"条目"(entries)的基础上。一个条目是一些属性的集合,并且具有一个全局唯一的"可区分名称"DN,一个条目可以通过DN来引用。每一个条目的属性具有一个类型和一个或者多个值。类型通常是容易记忆的名称,比如"cn"是通用名称(common name) ,或者"mail"是电子邮件地址。条目的值的语法取决于属性类型。比如,cn属性可能具有一个值"Babs Jensen" 。一个mail属性可能包含"bbs@kevin.com" 。一个jpegphoto属性可能包含一幅JPEG(二进制)格式的图片。

常见关键字缩写

关键字

英文全称

含义

dc

Domain Component

域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com

uid

User ID

用户ID,如“tom”

ou

Organization Unit

组织单位,类似于Linux文件系统中的子目录,它是一个容器对象,组织单位可以包含其他各种对象(包括其他组织单元),如“market”

cn

Common Name

公共名称,如“Ming Yao”

sn

Surname

姓,如“Yao”

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.”

ldif

LDAP Data Interchange Format

是LDAP中数据交换的一种文件格式。文件内容采用的是key-value形式,注意冒号后面有一个空格,value后面不能有空格。如:cn: Ming Yao

olc

Online Configuration

写入LDAP后不需要重启,立即生效

命令简介

  • ldapsearch 命令
    ldapsearch 命令可根据用户定义的查询条件,对 OpenLDAP 目录树进行查找以及检索目录树相关条目。后期维护 OpenLDAP 服务器,会经常用到此命令获取详细信息。
-b <searchbase>:指定查找的节点,目录树的基准目录树信息。
-D <binddn>:指定查找的 DN,DN 是整个 OpenLDAP 树的唯一识别名称,类似于系统中根的概念。
-v:输出详细信息。
-x:使用简单的认证,不使用任何加密的算法,例如,TLS、SASL 等相关加密算法,默认使用SASL 认证方式。
-W:在查询时,会提示输入密码,如果不想输入密码,使用 -w password 即可。
-h(OpenLDAP 主机):使用指定的 ldaphost,可以使用 FQDN 或 IP 地址。
-H(LDAP-URL):使用 LDAP 服务器的 URL 地址进行操作。
-p(port):指定 OpenLDAP 监听的端口(默认端口为 389,加速端口为 636)。
-LLL:禁止输出与过滤条件不匹配的信息。

查看当前 OpenLDAP 目录树关于 12345678 用户的信息(cn)

ldapsearch -x -LLL -b "dc=foobar,dc=com" uid=12345678 cn
  • ldapadd 命令
    ldapadd 命令用于通过 LDIF 格式添加目录树条目。通过 man 文件查看帮助文档可发现,ldapadd 实际上是 ldapmodify 的软连接,两条命令的相关参数几乎没有多大区别,ldapadd 在功能上等同于 ldapmodify -a 命令。
    添加用户条目,具体操作,请看下文
ldapadd -x -D "cn=manager,dc=foobar,dc=com" -W -H ldap://localhost -f staff.ldif
  • ldapdelete 命令
    ldapdelete 命令用于从目录树中删除指定条目,并根据 DN 条目删除一个或多个条目,但必须提供所要删除指定条目的权限所绑定的 DN(整个目录树的唯一标识名称)。
-c:持续操作模式,例如,在操作过程中出现错误,也会进行后续相关操作。
-D <binddn>:指定查找的 DN,DN 是整个 OpenLDAP 树的唯一识别名称。
-n:显示正在进行的相关操作,但不实际修改数据,一般用于测试。
-x:使用简单的认证,不使用任何加密的算法,例如,TLS、SASL 等相关加密算法。
-f:使用目标文件名作为命令的输入。
-W:显示输入密码。
-y passwdifile:可以通过将密码写入文件进行验证。
-r:递归删除,这个操作会从目录树删除指定的 DN 的所有子条目。
-h(OpenLDAP 主机):使用指定的 ldaphost,可以使用 FQDN 或 IP 地址。
-H(LDAP-URL):使用 LDAP 服务器的 URL 地址进行操作。
-p(port):指定 OpenLDAP 监听的端口(默认端口为 389,加速端口为 636)。

从当前目录树中删除uid为12345678的用户,删除前需要使用ldapsearch查看12345678的DN名称。

ldapdelete -x -D "cn=manager,dc=foobar,dc=com" -W -H ldap://localhost "uid=12345678,ou=persons,dc=foobar,dc=com"
  • ldapmodify 命令
    ldapmodify 命令可以对 OpenLDAP 数据库中的条目进行删除操作,它可以理解为编辑器。也可以通过设置 chanagetype 属性的值为 delete 关键字来进行条目的删除。

修改uid为12345678的密码

[root@localhost ldap]# vim modpwd.ldif
dn: uid=12345678,ou=persons,dc=foobar,dc=com
changetype: modify
replace: userPassword
userPassword: 12345678
[root@localhost ldap]# ldapmodify -x -D cn=manager,dc=foobar,dc=com -W -H ldap://localhost -f modpwd.ldif
Enter LDAP Password: 
modifying entry "uid=12345678,ou=persons,dc=foobar,dc=com"
  • ldappasswd 命令
    修改uid为12345678的密码的以一种命令,先重置密码,再输入管理员密码认证。
[root@localhost ldap]# ldappasswd -x -D cn=manager,dc=foobar,dc=com -W -H ldap://localhost  "uid=12345678,ou=persons,dc=foobar,dc=com" -S
New password: 
Re-enter new password: 
Enter LDAP Password:

安装使用

系统环境

虚拟机CentOS7

外网访问需要打开389端口或者关闭selinux

[root@localhost ldap]# firewall-cmd --permanent --add-port=389/tcp
success
[root@localhost ldap]# firewall-cmd --reload
success

禁用selinux

setenforce 0

vi /etc/selinux/config
SELINUX=disabled

安装OpenLDAP

如果不可以连接外网,需要先配置yum软件仓库,并配置挂载。

  • yum安装
[root@localhost ~]# yum install openldap openldap-servers openldap-clients
...
Total                                                                                                                                                            8.4 MB/s | 2.3 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : openldap-servers-2.4.40-13.el7.x86_64                                                                                                                                         1/2 
  Installing : openldap-clients-2.4.40-13.el7.x86_64                                                                                                                                         2/2 
  Verifying  : openldap-clients-2.4.40-13.el7.x86_64                                                                                                                                         1/2 
  Verifying  : openldap-servers-2.4.40-13.el7.x86_64                                                                                                                                         2/2 

Installed:
  openldap-clients.x86_64 0:2.4.40-13.el7                                                         openldap-servers.x86_64 0:2.4.40-13.el7                                                        

Complete!
  • 拷贝数据库配置文件
# DB_CONIFG中主要是关于Berkeley DB的相关的一些配置
[root@localhost ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@localhost ~]# chown ldap:ldap /var/lib/ldap/DB_CONFIG
  • 启动OpenLDAP Server
[root@localhost ~]# systemctl start slapd && systemctl enable slapd
Created symlink from /etc/systemd/system/multi-user.target.wants/slapd.service to /usr/lib/systemd/system/slapd.service.
  • 查看服务及端口
systemctl status slapd
netstat -lnput | grep -i :389

设置root用户密码

  • 先用slappasswd命令生成一个LDAP管理用户root密码。
[root@localhost ~]# slappasswd
New password: 123456
Re-enter new password: 
{SSHA}q3MUSptPBdtfdiwlMFGj3oXoRbzZc1t2
  • 新建一个rootpwd.ldif(名称是自定义的)的文件
[root@localhost ~]# mkdir ldap
[root@localhost ~]# cd ldap
[root@localhost ldap]# vim rootpwd.ldif
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}q3MUSptPBdtfdiwlMFGj3oXoRbzZc1t2
  • 下面使用ldapadd命令将上面的rootpwd.ldif文件写入LDAP:
[root@localhost ldap]# ldapadd -Y EXTERNAL -H ldapi:/// -f rootpwd.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={0}config,cn=config"

导入schema

  • schema包含为了支持特殊场景相关的属性,可根据选择导入,这里全部导入
[root@localhost ldap]#  ls /etc/openldap/schema/*.ldif | while read f; do ldapadd -Y EXTERNAL -H ldapi:/// -f $f; done
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=collective,cn=schema,cn=config"

SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=corba,cn=schema,cn=config"
...

设定默认域

  • 设置管理员密码
[root@localhost ldap]# slappasswd
New password: 
Re-enter new password: 
{SSHA}az9S33sL94Qz5O/Z3x07+VVX+9aqyJFL
  • 新增domain.ldif
[root@localhost ldap]# vim domain.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=foobar,dc=com" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=foobar,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=manager,dc=foobar,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}az9S33sL94Qz5O/Z3x07+VVX+9aqyJFL

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
  dn="cn=manager,dc=foobar,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=manager,dc=foobar,dc=com" write by * read
  • 写入
[root@localhost ldap]# ldapmodify -Y EXTERNAL -H ldapi:/// -f domain.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={1}monitor,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

添加基本目录

  • 新建basedomain.ldif
vim basedomain.ldif

dn: dc=foobar,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: foobar,com
dc: foobar

dn: cn=manager,dc=foobar,dc=com
objectClass: organizationalRole
cn: manager
description: Directory root

dn: ou=People,dc=foobar,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=persons,dc=foobar,dc=com
objectClass: organizationalUnit
ou: persons

dn: ou=Group,dc=foobar,dc=com
objectClass: organizationalUnit
ou: Group
  • 写入
[root@localhost ldap]# ldapadd -x -D cn=manager,dc=foobar,dc=com -w admin -f basedomain.ldif
adding new entry "dc=foobar,dc=com"

adding new entry "cn=manager,dc=foobar,dc=com"

adding new entry "ou=People,dc=foobar,dc=com"

adding new entry "ou=persons,dc=foobar,dc=com"

adding new entry "ou=Group,dc=foobar,dc=com"

测试

[root@localhost ldap]# ldapsearch -LLL -W -x -D "cn=manager,dc=foobar,dc=com" -H ldap://localhost -b "dc=foobar,dc=com"
Enter LDAP Password: 
dn: dc=foobar,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: foobar,com
dc: foobar

dn: cn=manager,dc=foobar,dc=com
objectClass: organizationalRole
cn: manager
description: Directory root

dn: ou=People,dc=foobar,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=persons,dc=foobar,dc=com
objectClass: organizationalUnit
ou: persons

dn: ou=Group,dc=foobar,dc=com
objectClass: organizationalUnit
ou: Group

添加用户条目

常见的两种dn设置

常见dn方式

样例

基于cn(姓名)

cn=Jack,ou=persons,dc=foobar,dc=com

最常见的cn是/etc/group转来的条目

基于uid(User ID)

uid=Tom,ou=persons,dc=foobar,dc=com

最常见的uid事/etc/passwd 和 /etc/shadow转来的条目

[root@localhost ldap]# vim staff.ldif
dn: cn=12345678,ou=persons,dc=foobar,dc=com
objectClass: inetOrgPerson
sn: yao
cn: ming yao
mail: 123@163.com
userPassword: 12345678

dn: cn=12345679,ou=persons,dc=foobar,dc=com
objectClass: inetOrgPerson
sn: 12345679
cn: 12345679
mail: 456@163.com
userPassword: 12345679
[root@localhost ldap]# ldapadd -x -D "cn=manager,dc=foobar,dc=com" -W -H ldap://localhost -f staff.ldif
Enter LDAP Password: 
adding new entry "cn=12345678,ou=persons,dc=foobar,dc=com"

adding new entry "cn=12345679,ou=persons,dc=foobar,dc=com"

修改管理员密码

  • 查看openldap管理员密码字段存放在哪个配置文件中
[root@localhost ldap]# ldapsearch -H ldapi:// -LLL -Q -Y EXTERNAL -b "cn=config" "(olcRootDN=*)" dn olcRootDN olcRootPW
dn: olcDatabase={2}hdb,cn=config
olcRootDN: cn=manager,dc=foobar,dc=com
olcRootPW: {SSHA}az9S33sL94Qz5O/Z3x07+VVX+9aqyJFL
  • 通过slappasswd生成新密码
[root@localhost ldap]# slappasswd
New password: np123
Re-enter new password: 
{SSHA}JBRqDHyLMfMuLlGmnF/6iDM/2VhB3K7j
  • 新建密码文件modpwd.ldif
vim modpwd.ldif

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}JBRqDHyLMfMuLlGmnF/6iDM/2VhB3K7j
  • 修改
[root@localhost ldap]# ldapmodify -H ldapi:// -Y EXTERNAL -f modpwd.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={2}hdb,cn=config"

ldap卸载

停止openldap服务

[root@localhost ldap]# systemctl stop slapd && systemctl disable slapd
Removed symlink /etc/systemd/system/multi-user.target.wants/slapd.service.

卸载ldap

[root@localhost ldap]# yum -y remove openldap-servers openldap-clients

删除残留文件

[root@localhost ldap]# rm -rf /var/lib/ldap

删除ldap用户

[root@localhost ldap]# userdel ldap

删除openldap目录

[root@localhost ldap]# rm -rf /etc/openldap

参考资料

OpenLDAP 2.4部署记录LDAP学习笔记总结OpenLDAP installldap安装卸载