介绍
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安装卸载