Linux 安装并配置 OpenLDAP 新编(2)客户端工具
Linux 安装并配置 OpenLDAP 新编(2)客户端工具
OpenLDAP的官网上,并没有使用方面专题介绍,所以这部分的学习也只能一半参考一半摸索的进行。OpenLDAP的使用与管理,可以通过内置工具、第三方工具以及其他具体场景来进行,这里仅介绍系统内置工具的日常使用。
工具概述
在前一篇安装篇中所说,默认情况下LDAP的客户端管理工具被安装在: /usr/local/bin/ 目录中。我们可以通过 man 命令,或者 --help 参数来查看工具的具体使用方法。不过前者的返回实在是太多了,用后者即可。
查询操作
ldapsearch
回忆一下上一节中的两个查询命令,同时对照帮助文档:
# 刚启动后
ldapsearch -x -LLL -b '' -s base '(objectclass=*)' namingContexts
# 添加了根条目后
ldapsearch -x -LLL -b 'dc=example,dc=com' '(objectclass=*)'
# 帮助文档
ldapsearch --help
# 返回模板
usage: ldapsearch [options] [filter [attributes...]]
可以看到参数主要包含选项、过滤方式及显示属性。其中,过滤方式遵循 RFC 4515 规范,我也没再深入研究,以后再说吧。
其中属性是由空格分隔的多个名称列表,或者使用 * 显示所有用户属性,用 + 显示所有可选属性,例如:
ldapsearch -x -LLL -b 'dc=example,dc=com' '(objectclass=*)' +
对于简单的查询来说,以下几个选项基本就够用了:
- -x : 简单身份验证
- -LLL : 简化输出,不输出注释
- -b : 表示搜索的起始节点
- -s : 搜索范围,base, one, sub or children的一个
- -H : 用于指定链接的服务器,如果不指定默认为本机地址及ldap协议
ldapwhoami
我是谁?这个命令用于请求用户身份验证。
# 简单身份验证
ldapwhoami -x
# 返回表示为匿名用户
anonymous
# 简单身份验证,指定绑定DN
ldapwhoami -x -w 123456 -D cn=Manager,dc=example,dc=com
# 返回绑定的DN身份信息
dn:cn=Manager,dc=example,dc=com
# 密码错误或者DN错误,则返回下面的错误信息
ldap_bind: Invalid credentials (49)
查询选项中的 -w 是指明文提供相应的密码明文;-W 为交互式密码输入方式。
编辑操作
添加操作
回想一下上一节的最后,通常在 LDAP 中添加条目,分为两步:1.编辑LDIF文件;2.添加文件到LDAP节点中。
再次编辑一个文件,名为 add_group.ldif,添加如下内容:
dn: ou=group,dc=example,dc=com
objectclass: organizationalUnit
ou: group
然后添加到上一节创建的根节点中:
ldapadd -x -W -D "cn=Manager,dc=example,dc=com" -f add_group.ldif
# 返回下面的结果表示添加成功
adding new entry "ou=group,dc=example,dc=com"
# 查询
ldapsearch -x -LLL -b 'dc=example,dc=com' '(objectclass=*)'
复盘一下前面的文件,这是一个最简单的LDAP管理文件,其中至少包括:
- dn: 为条目的名字,必须全局唯一,对于添加操作来说,会根据路径进行搜索,如果上级不存在,会返回No Object错误;
- objectclass : 必须包含的内容,表示该条目是什么类型,一个文件中可以包含多个指令;
- ou : ou 是 organizationalUnit 对象的必要属性,如果不填写必要属性,会返回错误。
phpLDAPadmin提供了一个工具,可以查看到所有的 objectclass , 以及所有属性。打开文末的参考资料,选择左侧的 C6:OpenLDAP 2.4.40: config 下拉后,点击 schema 图标。
修改操作
修改操作略微复杂一些,又可以进一步区分为添加修改(为条目添加属性)、更新修改(为条目更新属性)、删除修改(删除属性)。但是要注意的是,这些操作应该只能针对于可选属性。想要修改类似于: ou 属性,会直接返回错误。
添加修改
我们继续编辑一个文件,名为: edit_group.ldif ,添加下面的内容:
dn: ou=group,dc=example,dc=com
changetype: modify
add: description
description: I'm first description!
然后执行 ldapmodify 命令:
ldapmodify -x -W -D "cn=Manager,dc=example,dc=com" -f edit_group.ldif
# 返回下面的结果表示修改成功
modifying entry "ou=group,dc=example,dc=com"
# 查询,此处已经可以看到修改添加的结果
ldapsearch -x -LLL -b 'ou=group,dc=example,dc=com'
更新修改
再次编辑前面的 edit_group.ldif 文件,修改下面的内容:
dn: ou=group,dc=example,dc=com
changetype: modify
replace: description
description: I'm second description!
再次执行 ldapmodify 命令:
ldapmodify -x -W -D "cn=Manager,dc=example,dc=com" -f edit_group.ldif
# 返回下面的结果表示修改成功
modifying entry "ou=group,dc=example,dc=com"
# 查询,此处已经可以看到修改添加的结果
ldapsearch -x -LLL -b 'ou=group,dc=example,dc=com'
删除修改
再次编辑前面的 edit_group.ldif 文件,修改下面的内容:
dn: ou=group,dc=example,dc=com
changetype: modify
delete: description
再次执行 ldapmodify 命令:
ldapmodify -x -W -D "cn=Manager,dc=example,dc=com" -f edit_group.ldif
# 返回下面的结果表示修改成功
modifying entry "ou=group,dc=example,dc=com"
# 查询,此处可以看到 description 属性已经被删除
ldapsearch -x -LLL -b 'ou=group,dc=example,dc=com'
总结
总结下来,修改操作需要通过 DN 来指定一个待修改的条目对象,changetype 的值固定为 modify 。通过动作指令来声明需要进行的操作,例如:add、replace和delete,同时指定要执行该动作的属性。最后指定该属性的值(对于删除动作来说并不需要)。
删除操作
上面的删除修改,实际上只是删除某个条目的具体值,那么如何彻底删除一个条目呢?这里需要用到 ldapdelete 命令,在此之前,我们创建一个新的条目用于测试删除。
# add_sub_group.ldif
dn: ou=tsd,ou=group,dc=example,dc=com
objectclass: organizationalUnit
ou: tsd
执行操作命令:
ldapadd -x -W -D "cn=Manager,dc=example,dc=com" -f add_sub_group.ldif
# 返回下面的操作
adding new entry "ou=tsd,ou=group,dc=example,dc=com"
# 查询,此处可以看到子级分组已经添加
ldapsearch -x -LLL -b 'ou=group,dc=example,dc=com'
最后,我们执行删除操作:
ldapdelete -x -W -D "cn=Manager,dc=example,dc=com" -r ou=tsd,ou=group,dc=example,dc=com
# 查询,此处可以看到子级分组已经添加
ldapsearch -x -LLL -b 'ou=group,dc=example,dc=com'
从上面的操作可以看到,节点删除并不会返回明确的结果。如果不指定具体的DN,则在输入密码后已交互式方式,要求用户输入DN来进行删除操作。其中的 -r 选项,用于指定递归删除。
多协议支持
可以说经过上面的实操,已经算是掌握了LDAP的操作。但是可能心细的人会注意到一个差异,我所有的命令操作,使用的身份验证都是: -x -W 或者 -x -w 123456 这种形式,而网上绝大多数的教程都是: -Q -Y EXTERNAL -H ldapi:// ,这是为什么呢?
首先我们尝试一下依样画瓢是否可行,简单改写下上面的命令,结果…………。Oops,返回错误:
ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:// -b 'ou=group,dc=example,dc=com'
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
考虑到再做一下简化,看看可能的问题在哪里:
ldapsearch -x -LLL -H ldapi:// -b 'ou=group,dc=example,dc=com'
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
WTF!!!
遇到这个问题,很多人去搜帖子,不外乎解决方案不外乎:添加 sudo 执行、不该用 ldapi:/// 要用 ldapi:// 、不该用 ldapi:// 要用 ldapi:/// 等等……
然而正如前面所讲的那样,这全部都是 设定先行 的想当然。 这里的本质原因在于2点:
- 不给定参数的前提下,slapd只启动ldap的监听!
- 下回再说!
第一点原因的解决方法也很简单,kill 掉之前的启动命令,添加参数后再次启动 slapd:
/usr/local/libexec/slapd -F /usr/local/etc/slapd.d -h "ldap:/// ldapi:///"
# 简单授权方式
ldapsearch -x -LLL -H ldapi:// -b 'ou=group,dc=example,dc=com'
# SASL 机制
ldapsearch -Q -Y EXTERNAL -LLL -H ldapi:// -b 'ou=group,dc=example,dc=com'
总结
以为这样就完了么?当根据网上的资料,尝试使用 SASL 机制添加前面创建的条目时:
ldapadd -Q -Y EXTERNAL -H ldapi:// -f add_sub_group.ldif
WTF!!!这又是为什么???
# 返回结果
adding new entry "ou=tsd,ou=group,dc=example,dc=com"
ldap_add: Insufficient access (50)
additional info: no write access to parent
这依旧是一个 设定先行 的问题,带着这个问题进入下一章内容!
文中所涉及的相关配置,请点击链接下载。