OpenLDAP 2.5.20 配置参数详解

OpenLDAP 2.5.20 cn=config 配置全解:参数查看与 ldapmodify 修改方式、全局/数据库/索引/限制/schema/模块七大类参数逐项修改-验证闭环与语义坑,全部实测回显。

OpenLDAP身份认证目录服务2026/10/27

OpenLDAP 2.5.20 配置参数详解

目标:逐项讲透 OpenLDAP 2.5.20 的 cn=config 配置体系——参数查看与在线修改方式、cn=config 全树参数总览、全局/数据库/索引/限制/schema/模块七大类参数的修改-验证闭环,所有命令与回显均已在 Ubuntu 22.04 真实环境实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(amd64)
  • 主机名:ldap01.lab.local,内网 IP 10.89.63.2
  • 软件版本:slapd 2.5.20+dfsg-0ubuntu0.22.04.1、ldap-utils 2.5.20+dfsg-0ubuntu0.22.04.1、openssl 3.0.2
  • 目录域:dc=lab,dc=local;管理员 DN:cn=admin,dc=lab,dc=local(密码 q1w2e3r4)
  • 目录数据:ou=people、ou=groups、uid=zhangsan、uid=lisi、cn=developers(安装流程见 《Ubuntu 22.04 安装 OpenLDAP 2.5.20 指南》)
  • 配置树:/etc/ldap/slapd.d/(cn=config);数据目录 /var/lib/ldap;监听 ldap:/// ldaps:/// ldapi:///

二、前置条件

  1. 已按《Ubuntu 22.04 安装 OpenLDAP 2.5.20 指南》完成安装与域初始化,slapd 处于运行状态:
systemctl is-active slapd

实测回显:

active
  1. 能以本地 root 身份经 ldapi socket 管理 cn=config(Ubuntu 默认即如此,机制见 6.3 frontend 一节):
ldapwhoami -Q -Y EXTERNAL -H ldapi:///

实测回显:

dn:gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
  1. 本文 LDIF 修改文件统一放 /root/ 下,示例管理口令统一 q1w2e3r4。

三、参数查看与修改方式

3.1 cn=config 与 slapd.conf 双口径

OpenLDAP 2.4 起配置有两条口径:

  • cn=config(Ubuntu 默认):配置即一棵 LDAP 树,根为 cn=config,文件形态存于 /etc/ldap/slapd.d/(LDIF)。查看用 ldapsearch/slapcat,修改用 ldapmodify 在线热改,绝大多数参数立即生效无需重启(TLS 参数、监听地址等少数除外)。禁止手工编辑 /etc/ldap/slapd.d/ 下的文件——slapd 启动时才读盘,手改会与在线状态漂移且丢 CRC 约定。
  • slapd.conf(老式):单文本文件全量配置,改后必须重启。Ubuntu 默认不启用(/etc/default/slapd 的 SLAPD_CONF 为空即走 cn=config);只有把 SLAPD_CONF 指到文件路径才切换。

本篇全部按 cn=config 口径。两口径不能混用,切换口径属于迁移操作(slaptest -f slapd.conf -F 目录可转换)。

3.2 查看:slapcat 与 ldapsearch 两种方式

离线导出全配置树(需可读 /var/lib/ldap,通常 sudo):

sudo slapcat -n 0 | grep -E '^dn: '

实测回显:

dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: cn={4}misc,cn=schema,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config

在线查看指定条目的指定属性(ldapsearch 方式,可远程可过滤):

ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config '(olcDatabase={1}mdb)' olcSuffix olcRootDN

实测回显(输出节选):

dn: olcDatabase={1}mdb,cn=config
olcSuffix: dc=lab,dc=local
olcRootDN: cn=admin,dc=lab,dc=local

两种方式取舍:slapcat -n 0 是离线全量快照(适合备份与审计),ldapsearch -b cn=config 是在线查询(适合脚本与精确取值),本文修改后验证一律用 ldapsearch。

3.3 修改:ldapmodify 三种 changetype

cn=config 的修改统一走 ldapmodify,changetype 三种动作:

动作用途对多值属性的行为
add新增属性或追加一个值已有同名值时报 20 Type or value exists
replace覆盖式重设多值属性整体替换(旧值全丢)
delete删除属性或指定值多值有序属性(如 olcAccess)delete 全删后 add 重建

认证方式用 -Q -Y EXTERNAL -H ldapi:///(本地 root 经 socket 的 SASL EXTERNAL,免密)。修改即时生效(少量参数需重启,逐项标注)。

四、cn=config 参数总览

4.1 配置树结构

cn=config 树分四层(对应 3.2 实测的 12 个条目):

层条目承载内容
全局cn=config日志级别、TLS 参数、PID/参数文件等全局项
模块cn=module{0},cn=config动态模块加载清单 olcModuleLoad
schemacn=schema,cn=config 及其 {0}~{4} 子条目objectClass/attributeType 定义
数据库olcDatabase={-1}frontend / {0}config / {1}mdb三库参数;overlay 挂在各业务库之下

4.2 全局参数速查表(cn=config 顶层)

参数默认值(Ubuntu 22.04 实测)作用
olcConfigFile / olcConfigDir(空)/ /etc/ldap/slapd.d老式配置文件路径 / cn=config 目录
olcArgsFile/var/run/slapd/slapd.argsslapd 命令行参数记录文件
olcPidFile/var/run/slapd/slapd.pidPID 文件
olcLogLevel256(stats)日志级别(位掩码,见 5.2)
olcToolRootPW(未设置)离线工具(slapadd/slapcat 等)的管理口令
olcTLSCertificateFile / KeyFile / CACertificateFile(未设置)TLS 证书/私钥/CA(安装篇 10.3 已配)
olcTLSProtocolMin(未设置)最低 TLS 版本(3.3=TLS1.2)
olcSecure / olcPasswordHash(未设置)/{SSHA}强制安全通道 / 默认口令哈希

4.3 数据库参数速查表(olcDatabase={1}mdb,实测值)

参数实测默认值作用
olcSuffixdc=lab,dc=local本库目录树后缀
olcRootDNcn=admin,dc=lab,dc=local超级管理员 DN(不受 ACL 限制)
olcRootPW{SSHA}…(base64)超级管理员口令哈希
olcDbDirectory/var/lib/ldapmdb 数据文件目录
olcDbMaxSize1073741824(1GB)数据库文件上限,应大于预期数据量
olcDbCheckpoint512 30每 512KB 或 30 分钟落盘检查点
olcLastModTRUE维护 createTimestamp/modifyTimestamp
olcDbIndexobjectClass eq;cn,uid eq;uidNumber,gidNumber eq;member,memberUid eq索引清单
olcAccess三条(见 6.3)本库 ACL

💡 技术拓展:olcDbIndex 后缀的索引类型不止一种——

类型原理适用
eq(等值)精确匹配哈希uid=zhangsan 这类等值过滤,最常用
pres(存在)属性有无索引仅过滤「有该属性即可」,少用
sub(子串)子串匹配mail=zhang 模糊查询,写放大明显
approx近似匹配依赖 metaphone 算法,语义不稳,少用

本文按读模式选 mail eq,sub(地址簿常按后缀模糊搜邮箱),uid 等等值属性保持默认 eq。

五、全局参数详解(cn=config 顶层)

5.1 olcPidFile 与 olcArgsFile

这两个文件参数由 Ubuntu 打包默认指向 /var/run/slapd/,正常无需改动:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b cn=config -s base olcPidFile olcArgsFile

实测回显:

dn: cn=config
olcArgsFile: /var/run/slapd/slapd.args
olcPidFile: /var/run/slapd/slapd.pid

改动场景仅限自定义运行目录(如 systemd 私有 /run 挂载变化),改后需 systemctl restart slapd。

5.2 olcLogLevel(日志级别)

olcLogLevel 是全局属性,只存在于 cn=config 顶层。放在数据库条目上会报 65(实测坑见 10.1)。当前值查看:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b cn=config -s base olcLogLevel

实测回显(安装篇已把级别设为 stats 后的值):

dn: cn=config
olcLogLevel: stats

修改为 stats(256,连接/操作/结果全量日志):

ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
EOF

实测回显:

modifying entry "cn=config"

验证日志真的落了:先发一次查询,再看 syslog 标识为 slapd 的日志(Ubuntu 22.04 上 slapd 日志经 syslog 机制进 journal,journalctl -t slapd 直接可读;容器/最小化环境若无 rsyslog 服务,日志只在 journal,不会出现 /var/log/syslog 文件):

ldapsearch -LLL -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b dc=lab,dc=local -s base dn > /dev/null
journalctl -t slapd --no-pager -n 3 | tail -3

实测回显(输出节选):

Oct 27 02:58:21 ldap01.lab.local slapd[2296]: conn=1000 op=1 SEARCH RESULT tag=101 err=0 qtime=0.000012 etime=0.000095 nentries=1 text=
Oct 27 02:58:21 ldap01.lab.local slapd[2296]: conn=1000 op=2 UNBIND
Oct 27 02:58:21 ldap01.lab.local slapd[2296]: conn=1000 fd=14 closed

常用级别对照:stats(256,日常推荐,连接+操作+结果)、conns(8,仅连接)、config(64,配置处理)、acl(128,ACL 命中过程,排权限首选)、-1(any,全开仅排障用)。立即生效,无需重启。

5.3 olcTLS* 传输加密参数

安装篇 10.3 已完成完整闭环(生成自签 CA → 写入 olcTLSCACertificateFile/olcTLSCertificateFile/olcTLSCertificateKeyFile → SLAPD_SERVICES 加 ldaps:/// → 重启 → ldaps/StartTLS 双通道验证)。参数要点补充:

  • 三个 File 参数指 slapd 服务端证书链;改后需 systemctl restart slapd(连接层参数不热生效);
  • olcTLSProtocolMin: 3.3 表示最低 TLS 1.2,生产建议显式设置;
  • olcTLSCipherSuite 可限制套件,2.5 用 OpenSSL 记法,留空走系统默认。

5.4 olcToolRootPW(离线工具口令)

离线工具(slapcat/slapadd/slapindex)默认以 root 身份运行免密直读数据。olcToolRootPW 为「非 root 运维账号跑离线工具」提供口令校验通道;root 场景设置与否行为一致,本环境保持未设置(见 4.2 表)。

六、数据库参数详解

6.1 三库总览

slapd 固定挂三个数据库条目(编号决定匹配顺序):

编号名称职责
{-1}frontend前端库所有库共享的默认参数(olcAccess 缺省、olcSizeLimit 等)
{0}config配置库cn=config 树本身的管理参数
{1}mdb业务库dc=lab,dc=local 数据真身(多后缀时会继续 {2}、{3}…)

frontend 的实测 ACL(解释了「本地 root 免密管理」的原理):

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b olcDatabase={-1}frontend,cn=config olcAccess olcSizeLimit

实测回显:

dn: olcDatabase={-1}frontend,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
olcAccess: {1}to dn.exact="" by * read
olcAccess: {2}to dn.base="cn=Subschema" by * read
olcSizeLimit: 5000

{0} 条把 uid=0+gid=0 的 socket 对端(本地 root)映射为 peercred 身份放行——这就是 -Q -Y EXTERNAL 免密改 cn=config 的机制;{1} 允许所有人读根 DN=""(取根 DSE);{2} 允许读 schema 子模式条目。olcSizeLimit 默认 500(本文演示改成了 5000,见 6.6)。

6.2 olcSuffix / olcRootDN / olcRootPW

三者为业务库身份三件套:olcSuffix 定义树后缀,olcRootDN 是不受 ACL 约束的超级管理员,olcRootPW 是其口令哈希。查看:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcSuffix olcRootDN olcDbDirectory olcDbMaxSize olcDbCheckpoint olcLastMod

实测回显:

dn: olcDatabase={1}mdb,cn=config
olcSuffix: dc=lab,dc=local
olcRootDN: cn=admin,dc=lab,dc=local
olcDbDirectory: /var/lib/ldap
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbMaxSize: 1073741824

修改 olcRootPW 闭环(改密→新密码验证→改回):先生成新哈希:

slappasswd -s NewPass456

实测回显(盐随机,每次不同):

{SSHA}sJWxHWb24y3zKfEqMl3oH9bvcK4Xfhyk

注:哈希含随机盐,你的输出与上面不同属正常;把命令输出原样代入下方 LDIF。

写入并验证:

sudo tee /root/rootpw.ldif > /dev/null << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}sJWxHWb24y3zKfEqMl3oH9bvcK4Xfhyk
EOF
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /root/rootpw.ldif

实测回显:

modifying entry "olcDatabase={1}mdb,cn=config"

新口令即时生效(无需重启):

ldapwhoami -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w NewPass456

实测回显:

dn:cn=admin,dc=lab,dc=local

验证后按同法改回 q1w2e3r4 的哈希(slappasswd -s q1w2e3r4 再 replace 一次),全文后续仍用 q1w2e3r4。

olcSuffix 与 olcRootDN 修改属于「换域」级操作:suffix 改了数据后缀不再匹配、rootDN 改了管理身份变了,正规做法是重配(安装篇方案 B)或 slapadd 重建,不做在线 rename。

6.3 olcAccess(ACL)详解

ACL 语法三段式:olcAccess: {序号}to <what> by <who> <access>。{N} 是执行序号(从上到下先命中先生效),what 可用 dn/attrs 过滤,who 常用 self(绑定者本人)、anonymous(匿名)、users(任一认证用户)、dn.exact=...(精确 DN)、*(所有人),access 从宽到严为 write/read/search/compare/auth/none。

默认三条(Ubuntu 打包,见安装篇 9.1)与收紧后三条(安装篇 9.2/9.3 已实测:匿名查询变 32 No such object、认证用户可读)之外,再补一个生产常用的「按组授权」例子——先建 groupOfNames 管理组并加载 memberof(模块加载见 8.2),随后授权该组可写 people 分支:

ldapadd -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcOverlay={1}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcMemberOf
olcOverlay: {1}memberof
EOF

实测回显:

adding new entry "olcOverlay={1}memberof,olcDatabase={1}mdb,cn=config"

⚠️ 注意:同一个库挂第二个 memberof overlay 仅为演示多 overlay 排布;生产环境一个库挂一个 memberof 即可(重复挂载会叠加反解开销)。

ACL 修改的完整 delete+add 闭环、匿名 32 语义坑与验证,见安装篇 9.2/9.3;ACL 排障时把 olcLogLevel 临时加 acl 位(如 replace: olcLogLevel 值 stats acl)可看到每条 ACL 的命中过程。

6.4 olcDbDirectory / olcDbCheckpoint / olcDbMaxSize / olcLastMod

  • olcDbDirectory: /var/lib/ldap:mdb 数据文件目录。迁移数据目录=改此参数+物理搬文件+chown openldap+重启;
  • olcDbCheckpoint: 512 30:每累计 512KB 写或 30 分钟做一次检查点(把脏页刷盘并截断事务日志),提高崩溃恢复速度;
  • olcDbMaxSize: 1073741824:数据文件上限 1GB。mdb 是空间预分配语义,按预期条目量设置——十万级条目留 4GB 起步;设置只影响文件增长上限,不影响内存占用;
  • olcLastMod: TRUE:维护操作时间戳属性(entryCSN/modifyTimestamp),同步复制(syncrepl)与增量审计依赖它,保持 TRUE。

修改示例(把 checkpoint 收紧为 10 分钟):

ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcDbCheckpoint
olcDbCheckpoint: 512 10
EOF

实测回显:

modifying entry "olcDatabase={1}mdb,cn=config"

验证:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcDbCheckpoint

实测回显:

dn: olcDatabase={1}mdb,cn=config
olcDbCheckpoint: 512 10

(演示后建议改回默认 512 30,按同法 replace 即可。)

6.5 olcDbIndex 与 slapindex

默认索引四条(objectClass eq、cn,uid eq、uidNumber,gidNumber eq、member,memberUid eq)。追加已存在的索引会报 80(实测坑见 10.2)——uid 已包含在 cn,uid eq 里。追加不重复的 mail 索引:

ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: mail eq,sub
EOF

实测回显:

modifying entry "olcDatabase={1}mdb,cn=config"

验证:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcDbIndex

实测回显:

dn: olcDatabase={1}mdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
olcDbIndex: mail eq,sub

新索引只对之后写入的数据即时生效;存量数据要重建索引(停服执行,slapindex 直读数据文件,root 运行时对 /var/lib/ldap 有写权限,完成后把属主交回 openldap):

sudo systemctl stop slapd
sudo slapindex -b "dc=lab,dc=local"
sudo chown -R openldap:openldap /var/lib/ldap
sudo systemctl start slapd

实测回显(root 运行时 slapindex 的权限告警为提示性输出,属预期):

WARNING!
Running as root!
There's a fair chance slapd will fail to start.
Check file permissions!

重启后查询正常即索引重建完成(mail 检索可实测 (mail=*@lab.local) 子串过滤响应)。

6.6 olcSizeLimit / olcTimeLimit(限制参数)

frontend 库的 olcSizeLimit 默认已存在且值为 500(实测见 6.1)——对它做 add 会报 20 Type or value exists,必须用 replace:

ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={-1}frontend,cn=config
changetype: modify
replace: olcSizeLimit
olcSizeLimit: 5000
EOF

实测回显:

modifying entry "olcDatabase={-1}frontend,cn=config"

验证:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b olcDatabase={-1}frontend,cn=config olcSizeLimit

实测回显:

dn: olcDatabase={-1}frontend,cn=config
olcSizeLimit: 5000

单次搜索超过 5000 条即返回 Size limit exceeded (4)。olcTimeLimit 同理(默认 3600 秒,replace 修改),约束单次搜索时长。两者也可下放到具体数据库覆盖全局值。

七、schema 详解

7.1 内置 schema 清单

Ubuntu 包默认加载四套 schema({0}~{3},见 3.2 全树回显;{4}misc 为本文导入):

编号schema提供的关键类/属性
{0}core核心person、organizationalUnit、top
{1}cosineCosine/X.500inetOrgPerson 依赖的公共属性
{2}nisNetwork Information ServiceposixAccount、posixGroup、shadowAccount
{3}inetorgpersonInetOrgPersoninetOrgPerson(用户条目主力类)

安装篇 8.3 的用户条目正是这四套的组合。

7.2 导入第三方 schema(misc.schema 全坑实录)

misc.schema 含 RIPE 等 RFC 1274 对象类。第一步就踩坑:cn=config 下不能直接把 include: 行塞进条目——

ldapadd -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: cn={4}misc,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: {4}misc
include: file:///etc/ldap/schema/misc.schema
EOF

实测回显:

ldap_add: Undefined attribute type (17)
	additional info: include: attribute type undefined

include 不是 cn=config 的合法属性,17 报错即停。正确姿势:用 slaptest 把「slapd.conf 口径的 include 清单」转换成 cn=config 口径的 LDIF,再导入:

mkdir -p /tmp/conv/slapd.d
sudo tee /tmp/conv/slapd.conf > /dev/null << 'EOF'
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
EOF
sudo slaptest -f /tmp/conv/slapd.conf -F /tmp/conv/slapd.d

实测回显:

config file testing succeeded

⚠️ 第二个坑:-F 目标目录必须事先存在且为空,否则 slaptest 直接拒绝:slaptest: bad configuration directory!。

从生成的 LDIF 截取条目头部(dn 到最后一行 schema 定义,剥离内部审计属性):

sudo sed -n '1,/^structuralObject/p' '/tmp/conv/slapd.d/cn=config/cn=schema/cn={4}misc.ldif' \
  | grep -vE 'structuralObject|entryUUID|creatorsName|createTimestamp|entryCSN|modifiersName|modifyTimestamp' \
  | sudo tee /tmp/conv/misc-entry.ldif > /dev/null
head -3 /tmp/conv/misc-entry.ldif

实测回显:

# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 1a4b5b33
dn: cn={4}misc,cn=schema,cn=config

⚠️ 第三个坑:转换产物的 dn 是 cn={4}misc(无父后缀),直接导入报 53 no global superior knowledge;必须把 dn 行补全为 cn={4}misc,cn=schema,cn=config(sed 替换后 head 可见)再导入:

ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /tmp/conv/misc-entry.ldif

实测回显:

adding new entry "cn={4}misc,cn=schema,cn=config"

7.3 验证 schema 生效

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn | grep misc

实测回显:

dn: cn={4}misc,cn=schema,cn=config

出现 cn={4}misc 即生效,之后条目即可引用 misc 定义的对象类/属性(立即生效,无需重启)。

八、模块与 overlay

8.1 olcModuleLoad(动态模块)

查看已加载模块:

ldapsearch -LLL -Q -Y EXTERNAL -H ldapi:/// -b cn=module{0},cn=config olcModuleLoad

实测回显(本文加载 memberof/syncprov 后的全量):

dn: cn=module{0},cn=config
olcModuleLoad: {0}back_mdb
olcModuleLoad: {1}memberof
olcModuleLoad: {2}syncprov

Ubuntu 打包默认只加载 back_mdb;模块文件在 /usr/lib/ldap/(memberof.so、syncprov.so 等)。追加模块用 add:

ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: memberof
EOF

实测回显:

modifying entry "cn=module{0},cn=config"

💡 技术拓展:syncprov 与复制拓扑——syncprov 是 syncrepl 的「提供者端」overlay,加载它只是给了复制能力,不等于已开启复制:还需在库上配置 olcSyncrepl(消费者侧)或 olcServerID/mirrormode(多主侧),且要求 olcLastMod=TRUE。本文只加载到能力层做边界演示,主从/多主的节点级配置属进阶部署,按生产拓扑另行规划。

8.2 memberof overlay 配置与验证

模块加载后,还要在业务库上挂 overlay 实例:

ldapadd -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcMemberOf
olcOverlay: {0}memberof
EOF

实测回显:

adding new entry "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"

建一个 groupOfNames 组并立即反解验证(memberof 对挂载之后的成员变更实时生效):

ldapadd -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 << 'EOF'
dn: cn=team-a,ou=groups,dc=lab,dc=local
objectClass: groupOfNames
cn: team-a
member: uid=zhangsan,ou=people,dc=lab,dc=local
EOF
ldapsearch -LLL -x -H ldapi:/// -D "cn=admin,dc=lab,dc=local" -w q1w2e3r4 -b ou=people,dc=lab,dc=local '(uid=zhangsan)' memberOf

实测回显:

adding new entry "cn=team-a,ou=groups,dc=lab,dc=local"

dn: uid=zhangsan,ou=people,dc=lab,dc=local
memberOf: cn=team-a,ou=groups,dc=lab,dc=local

uid=zhangsan 条目上自动出现 memberOf 属性——这是 overlay 反写的虚拟属性(入库存的是组侧 member,读时反向生成)。

8.3 memberOf 语义坑:posixGroup 的 memberUid 不触发

安装篇 8.3 的 cn=developers 是 posixGroup,其成员属性 memberUid 存的是uid 字符串(zhangsan)而非 DN。memberof overlay 的工作机制基于 DN 关系(olcMemberOfMemberAD 默认 member),因此对 memberUid 的增删不会生成 memberOf(实测:对 cn=developers 做 memberUid 增删后查 uid=lisi 无 memberOf 属性)。两条路:要么组用 groupOfNames+member(DN 型,如 8.2 的 team-a),要么显式改 overlay 的 olcMemberOfGroupAD/olcMemberOfMemberAD 语义并自担 uid→DN 映射的复杂度。这是 SSSD/应用查询「用户所属组」时最常见的落差点。

九、生产配置模板

适用场景:8GB 内存 / SSD / 千人以内规模的企业内网目录(Linux 账号源 + 应用统一认证)。以下为在本文实测环境上可直接套用的 cn=config 修改清单(每段独立可执行,值与本文实测口径一致):

# 1. 日志:日常 stats;排权限时临时叠加 acl
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
EOF

# 2. TLS:证书三件套 + 最低版本(证书签发见安装篇第十章)
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/tls/ca.crt
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/tls/server.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/tls/server.key
-
add: olcTLSProtocolMin
olcTLSProtocolMin: 3.3
EOF

# 3. ACL 收紧:密码自管、其余认证用户可读、匿名仅认证
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by self write by users read by * none
EOF

# 4. 索引:mail 子串检索(读多写少的地址簿场景)
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: mail eq,sub
EOF

# 5. 检查点:10 分钟一档(SSD 场景可承受)
ldapmodify -Q -Y EXTERNAL -H ldapi:/// << 'EOF'
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcDbCheckpoint
olcDbCheckpoint: 512 10
EOF

要点说明:模板第 1/3/4/5 段改完即时生效;第 2 段 TLS 属连接层参数,改完需 systemctl restart slapd 并确认 /etc/default/slapd 的 SLAPD_SERVICES 已含 ldaps:///。更大规模(万人级)把 olcDbMaxSize 上调至预期数据量的 2 倍以上,并为 uid/sn/givenName 增加 eq 索引;多主复制在库级追加 olcSyncrepl/olcServerID 配置,不在本模板范围。

十、常见问题(FAQ)

Q1:修改 olcLogLevel 报 Object class violation (65) attribute 'olcLogLevel' not allowed? olcLogLevel 是 cn=config 顶层全局属性,放到 olcDatabase={1}mdb,cn=config 等数据库条目上会报 65。实测报错原文:

ldap_modify: Object class violation (65)
	additional info: attribute 'olcLogLevel' not allowed

把 dn 改为 cn=config 即可。

Q2:追加索引报 Other (e.g., implementation specific) error (80) duplicate index definition? uid 已在默认索引 cn,uid eq 中,再 add uid eq 即报 80。实测原文:

ldap_modify: Other (e.g., implementation specific) error (80)
	additional info: duplicate index definition for attr "uid"

先 ldapsearch … olcDbIndex 看现状,只追加不重复的属性,或用 replace 整体重写索引清单。

Q3:改 olcSizeLimit 报 Type or value exists (20)? frontend 的 olcSizeLimit 默认就有值(500),add 同名属性报 20。用 replace: olcSizeLimit 覆盖即可(见 6.6 闭环)。

Q4:匿名搜索明明有条目却报 32 No such object? ACL 把匿名判成 none 时的标准语义是「装作不存在」防信息泄露,不是数据丢了(安装篇 9.3 实测复现)。用管理身份再查一次确认数据在,然后核对该库 olcAccess。

Q5:schema 导入一连串报错(17/坏目录/53)? 三连坑与解法见 7.2 实测实录:include 行不能直塞(17)→ slaptest -F 目标目录必须存在且为空 → 产物 dn 要补全 ,cn=schema,cn=config 父后缀(否则 53 no global superior knowledge)。

Q6:ldapmodify 显示 modifying entry 成功,验证却还是旧值? 两查:一是改错了条目(如把全局属性改到数据库条目、或 {N} 序号写重);二是所改参数属于「重启生效」类(TLS 三件套、监听等),需 systemctl restart slapd。验证一律用 ldapsearch 读回目标属性为准。

Q7:journalctl 里没有 slapd 的 stats 日志? 确认三点:olcLogLevel 确为 stats(5.2 回读);查询命令用 journalctl -t slapd(syslog 标识匹配)而非按单元过滤;最小化系统/容器环境若无 rsyslog,/var/log/syslog 文件不存在属正常,日志只进 journal。

十一、参考链接