编辑
2025-07-30
容器
00

目录

1. OpenLDAP 命令行数据管理实践
1.1 基本连接测试
1.2 用户账户创建
1.3 用户组创建与管理
1.4 用户信息更新
2. OpenLDAP 命令行工具速查
2.1 客户端工具 (用于管理 LDAP 数据)
2.2 服务器端工具 (用于管理 OpenLDAP 服务器)
3. OpenLDAP 核心守护进程 Slapd 及其配置
3.1 Slapd的作用
3.2 传统配置方式:slapd.conf (已弃用)
3.3 动态运行时配置:cn=config (推荐)

openldapcli.jpg

本文详细介绍了 OpenLDAP 的命令行操作,涵盖了从基础的用户和组管理(包括用户创建、组分配及成员关系检查)到高级的服务器配置(如 slapd 守护进程的工作原理及其配置方式)。通过具体的 LDIF 文件示例和 ldapaddldapmodifyldapsearch 等常用工具的演示,帮助读者全面理解和掌握 OpenLDAP 的数据管理与服务器维护。特别强调了从传统 slapd.conf 到动态 cn=config 配置的演进,并提供了 cn=config 的实际修改案例。

1. OpenLDAP 命令行数据管理实践

OpenLDAP可以使用WEBUI来管理,也可以使用命令行来管理。OpenLDAP的部署请参考 OpenLDAP 部署与基本原理解析(含 Docker Compose 与 Nginx 代理配置)

我们今天使用命令行来进行LDAP的操作,一步一步演示怎么添加用户和组并将用户添加到组中。

1.1 基本连接测试

先测试账号密码是否能登录Openldap,再尝试显示DN下所有的对象。

bash
ldapwhoami -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W Enter LDAP Password: dn:cn=admin,dc=example,dc=com ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -b "dc=example,dc=com" "(objectClass=*)" Enter LDAP Password: # extended LDIF # # LDAPv3 # base <dc=example,dc=com> with scope subtree # filter: (objectClass=*) # requesting: ALL # # example.com dn: dc=example,dc=com objectClass: top objectClass: dcObject objectClass: organization o: MyOrg dc: example # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1

1.2 用户账户创建

新建一个OU的LDIF文件。

bash
# add_ou_people.ldif dn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People description: All people in the organization

添加新的OU。

bash
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_ou_people.ldif Enter LDAP Password: adding new entry "ou=People,dc=example,dc=com"

在Openldap内部生成密码哈希。

bash
root@69a9b6c75c35:/# slappasswd -s "userpass" {SSHA}lP2pSP56cT5EE98/bkvcNY8zJ0bB6O6n

新建一个User的LDIF文件。

bash
# add_test_user.ldif dn: cn=testu,ou=People,dc=example,dc=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson cn: testu sn: User givenName: Test mail: test.user@example.com uid: 1000 userPassword: {SSHA}lP2pSP56cT5EE98/bkvcNY8zJ0bB6O6n description: General test user account

添加新的User。

bash
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_test_user.ldif Enter LDAP Password: adding new entry "cn=testu,ou=People,dc=example,dc=com"

1.3 用户组创建与管理

新建一个OU为Groups的LDIF文件。

bash
# add_ou_groups.ldif dn: ou=Groups,dc=example,dc=com objectClass: organizationalUnit ou: Groups description: All groups in the organization

添加新的OU Groups。

bash
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_ou_groups.ldif Enter LDAP Password: adding new entry "ou=Groups,dc=example,dc=com"

新建一个Group的LDIF文件。

bash
# add_new_group_testg.ldif dn: cn=testg,ou=Groups,dc=example,dc=com objectClass: top objectClass: groupOfUniqueNames cn: testg description: My new test group uniqueMember: cn=testu,ou=People,dc=example,dc=com

添加新的Group并分配User。

bash
ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f add_new_group_testg.ldif Enter LDAP Password: adding new entry "cn=testg,ou=Groups,dc=example,dc=com"

检查Test User是否属于Test Group。

bash
ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -b "cn=testg,ou=Groups,dc=example,dc=com" "(uniqueMember=cn=testu,ou=People,dc=example,dc=com)" dn Enter LDAP Password: # extended LDIF # # LDAPv3 # base <cn=testg,ou=Groups,dc=example,dc=com> with scope subtree # filter: (uniqueMember=cn=testu,ou=People,dc=example,dc=com) # requesting: dn # # testg, Groups, example.com dn: cn=testg,ou=Groups,dc=example,dc=com # search result search: 2 result: 0 Success # numResponses:

1.4 用户信息更新

新建一个修改用户的LDIF文件。

bash
# modify_user.ldif dn: cn=testu,ou=People,dc=example,dc=com changetype: modify replace: sn sn: NewSurname - replace: givenName givenName: NewGivenName - add: mobile mobile: 18812345678 - delete: mail

更改姓和名,新增手机号码,删除邮件地址。每一项操作中间添加分隔符 -

bash
ldapmodify -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f modify_user.ldif Enter LDAP Password: modifying entry "cn=testu,ou=People,dc=example,dc=com"

2. OpenLDAP 命令行工具速查

命令行分为客户端和服务端两大类。

2.1 客户端工具 (用于管理 LDAP 数据)

下面示例,客户端和服务端在同一个服务器上,所以使用localhost。如果是不在同一个服务器上,则需要指定-H后面的域名或是IP,为了安全考虑,要使用加密连接 如ldaps://IP:636。

  1. ldapsearch
  • 用途: 从 LDAP 目录中查询和检索信息。它是最常用的工具,用于验证条目、查找用户、组等。
  • 示例: ldapsearch -x -H ldap://localhost:389 -b "dc=example,dc=com" "(objectClass=inetOrgPerson)"
  1. ldapadd
  • 用途: 向 LDAP 目录添加新的条目(例如用户、组、组织单位)。它通常与 LDIF (LDAP Data Interchange Format) 文件一起使用。
  • 示例: ldapadd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f new_user.ldif
  1. ldapmodify
  • 用途: 修改 LDAP 目录中现有条目的属性。它也通常与 LDIF 文件一起使用,文件指定了要进行的修改类型(添加、替换、删除属性值)。
  • 示例: ldapmodify -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -f modify_user.ldif
  1. ldapdelete
  • 用途: 从 LDAP 目录中删除条目。
  • 示例: ldapdelete -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W "cn=testu,ou=People,dc=example,dc=com"
  1. ldappasswd
  • 用途: 更改 LDAP 目录中用户的密码。
  • 示例:
    • 用户 testu 更改自己的密码:ldappasswd -x -H ldap://localhost:389 -D "cn=testu,ou=People,dc=example,dc=com" -W -s "new_password"
    • 管理员更改 testu 用户的密码:ldappasswd -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=com" -W -s "new_password_for_testu" "cn=testu,ou=People,dc=example,dc=com"
  1. ldapwhoami
  • 用途: 验证当前用户是否成功通过 LDAP 服务器认证,并显示认证后的 DN。常用于测试认证连接。
  • 示例: ldapwhoami -x -H ldap://localhost:389 -D "cn=testu,ou=People,dc=example,dc=com" -W

2.2 服务器端工具 (用于管理 OpenLDAP 服务器)

这些工具通常在 OpenLDAP 服务器主机上运行,并且通常需要 root 权限或 OpenLDAP 用户的权限。譬如在容器内部显示可以用的slap命令。最常用的是数据库的导入导出。

bash
root@69a9b6c75c35:/# slap slapacl slapadd slapauth slapcat slapd slapdn slapindex slappasswd slapschema slaptest
  1. slapcat
  • 用途: 将整个 OpenLDAP 数据库或其一部分导出为 LDIF 格式。常用于备份或迁移数据。
  • 示例: slapcat -b "dc=example,dc=com" -l backup.ldif
  1. slapadd
  • 用途: 将 LDIF 文件中的数据批量导入到 OpenLDAP 数据库中。通常用于恢复备份或初始化数据库。
  • 示例: slapadd -b "dc=example,dc=com" -l backup.ldif
  1. slapindex
  • 用途: 重建 OpenLDAP 数据库的索引。在更改索引配置或数据损坏时可能需要。
  • 示例: slapindex -b "dc=example,dc=com"
  1. slaptest
  • 用途: 检查 OpenLDAP 配置文件 (slapd.confcn=config 目录) 的语法是否正确。在启动 slapd 服务之前进行配置验证非常有用。
  • 示例: slaptest -f /etc/ldap/slapd.conf -u

3. OpenLDAP 核心守护进程 Slapd 及其配置

slapd 是 OpenLDAP 项目的核心组件,它是 OpenLDAP Directory Server 的守护进程(daemon)。简单来说,slapd 就是 OpenLDAP 服务器本身,它负责处理所有对 LDAP 目录的请求,包括认证、查询、添加、修改和删除条目等。

3.1 Slapd的作用

  • 监听 LDAP 请求: slapd 监听标准的 LDAP 端口(默认 389 用于非加密连接,636 用于 LDAPS/SSL/TLS 加密连接),等待客户端(如 ldapsearchldapaddldapmodify 等)的连接。
  • 处理请求: 接收到请求后,slapd 会根据其配置、目录数据和访问控制列表(ACLs)来处理这些请求。
  • 管理数据存储: slapd 管理后端数据库,负责数据的持久化存储和检索。MDB (Memory-Mapped Database / LMDB) 是由 Symas Corporation 开发,并作为 OpenLDAP 项目的一部分发布的。它现在是 OpenLDAP 默认和推荐的数据库后端。
  • 执行认证和授权: 根据用户提供的凭据进行认证,并根据配置的 ACLs 决定用户是否有权限执行特定操作。

3.2 传统配置方式:slapd.conf (已弃用)

基于文本文件的配置模式。在容器中的位置为/etc/ldap/ldap.conf。和Nginx的配置文件类似,每次更改配置后需要检查配置有效性并重启服务。文件示例:

bash
root@69a9b6c75c35:/etc/ldap# cat ldap.conf # # LDAP Defaults # # See ldap.conf(5) for details # This file should be world readable but not world writable. #BASE dc=example,dc=com #URI ldap://ldap.example.com ldap://ldap-master.example.com:666 #SIZELIMIT 12 #TIMELIMIT 15 #DEREF never # TLS certificates (needed for GnuTLS) TLS_CACERT /container/run/service/slapd/assets/certs/ca.crt TLS_REQCERT never

关于TLS的配置是Docker Compose里面的环境变量的映射。这种方式已不再使用,进而转变到基于 LDAP 目录本身的动态配置。

3.3 动态运行时配置:cn=config (推荐)

cn=config 是一种将 slapd 的配置本身存储为 LDAP 目录中的特殊条目的方式。这意味着你可以像管理普通 LDAP 数据一样,使用标准的 LDAP 工具(如 ldapaddldapmodifyldapdelete)来实时修改 slapd 的配置,而无需重启服务。

cn=config 并不是一个单一的文件。它通常对应文件系统上的一个目录(例如 /etc/ldap/slapd.d/),该目录下包含一系列的 LDIF 文件,每个文件代表一个配置条目。这些 LDIF 文件在 slapd 启动时被读取并加载到内存中,之后对配置的修改会直接反映在内存中,并同步更新到这些 LDIF 文件。

bash
root@69a9b6c75c35:/etc/ldap# ls slapd.d/ 'cn=config' 'cn=config.ldif' docker-openldap-was-admin-password-set docker-openldap-was-started-with-tls root@69a9b6c75c35:/etc/ldap/slapd.d# ls cn\=config 'cn=module{0}.ldif' 'cn=schema.ldif' 'olcDatabase={-1}frontend.ldif' 'olcDatabase={1}mdb.ldif' 'cn=schema' 'olcDatabase={0}config.ldif' 'olcDatabase={1}mdb'

通过下面的命令可以查看所有的配置,它非常的冗长。

bash
root@69a9b6c75c35:/etc/ldap/slapd.d# ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" ......省略 # {0}memberof, {1}mdb, config dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcMemberOf olcOverlay: {0}memberof olcMemberOfDangling: ignore olcMemberOfRefInt: TRUE olcMemberOfGroupOC: groupOfUniqueNames olcMemberOfMemberAD: uniqueMember olcMemberOfMemberOfAD: memberOf # {1}refint, {1}mdb, config dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcRefintConfig olcOverlay: {1}refint olcRefintAttribute: owner olcRefintAttribute: manager olcRefintAttribute: uniqueMember olcRefintAttribute: member olcRefintAttribute: memberOf ......省略

更改配置就和更改其他目录里的条目是类似的。创建一个LDIF文件并应用它。譬如修改上面例子里的配置,olcRefintAttribute 是一个多值属性。

bash
# delete_refint_attr.ldif dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config changetype: modify delete: olcRefintAttribute olcRefintAttribute: owner

修改 cn=config 配置通常需要使用 EXTERNAL SASL 机制通过 Unix Domain Socket (ldapi:///) 进行认证。这意味着你需要以 root 用户或 slapd 进程所属的用户身份执行 ldapmodify 命令。在容器内部,就是以root用户运行的。

bash
root@69a9b6c75c35:/etc/ldap/slapd.d# ldapmodify -Y EXTERNAL -H ldapi:/// -f delete_refint_attr.ldif

本文作者:潘晓可

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!