389 Directory Server 配置管理实战:dsconf 与 cn=config 详解(后缀、索引、日志、缓存、口令策略)

389 Directory Server 2.0.15 配置管理实测:cn=config 结构解读与 dsconf 逐项生效验证,覆盖后缀、索引、日志级别、DB/条目缓存与口令锁定演练,含 autosize 排障实录。

389 Directory Server389 Directory ServerUbuntu22.04LDAP 协议2026/10/28

389 Directory Server 配置管理实战:dsconf 与 cn=config 详解(后缀、索引、日志、缓存、口令策略)

目标:在已安装的 389 Directory Server(Ubuntu 22.04 仓库版 2.0.15,实例名 ds1,后缀 dc=example,dc=com,安装见站内安装篇)上完成日常配置管理:cn=config 配置树结构解读、dsconf 后缀/索引/日志级别/内存缓存/口令策略逐项配置并逐项验证生效。全文命令与输出均为 2026-10-28 实测回显。

一、配置体系总览:cn=config 结构

1.1 两种配置面

389DS 的运行时配置全部落在 LDAP 目录自身的一个隐藏后缀 cn=config 中——改配置就是改这个树上的条目属性,即时生效(部分需重启,属性文档均有标注)。但直接 ldapmodify 改 cn=config 容易写错语法,官方推荐用 dsconf CLI,它本质上是 cn=config 的安全封装。两者的关系:

  • dsconf <实例> config replace/get → 操作 cn=config 下服务器级属性;
  • dsconf <实例> backend ... → 操作 cn=ldbm database,cn=plugins,cn=config 下数据库属性;
  • dsconf <实例> security ... → 操作 cn=encryption,cn=config 与 TLS 属性。

1.2 cn=config 顶层结构(实测)

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 -b cn=config -s one dn | grep '^dn:'
dn: cn=auto_bind,cn=config
dn: cn=encryption,cn=config
dn: cn=features,cn=config
dn: cn=mapping tree,cn=config
dn: cn=plugins,cn=config
dn: cn=replication,cn=config
dn: cn=replSchema,cn=config
dn: cn=rewriters,cn=config
dn: cn=sasl,cn=config
dn: cn=SNMP,cn=config
dn: cn=tasks,cn=config
dn: cn=uniqueid generator,cn=config

关键子树语义:

DN语义
cn=config服务器全局属性(端口、日志级别、minssf 等),对应 dse.ldif
cn=encryption,cn=configTLS 协议版本与密码套件
cn=mapping tree,cn=config后缀映射(每个后缀一条,挂到后端数据库)
cn=plugins,cn=config插件;其下 cn=ldbm database 是数据库引擎,每个后端一个条目
cn=tasks,cn=config任务入口(备份/导出/索引等任务创建后成为其子条目)
cn=monitor(与 cn=config 平级)运行时统计(缓存命中、线程、连接)

数据库引擎层结构(实测):

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 -b 'cn=ldbm database,cn=plugins,cn=config' -s one dn | grep '^dn:'
dn: cn=config,cn=ldbm database,cn=plugins,cn=config
dn: cn=monitor,cn=ldbm database,cn=plugins,cn=config
dn: cn=testroot,cn=ldbm database,cn=plugins,cn=config
dn: cn=userroot,cn=ldbm database,cn=plugins,cn=config

语法提示:cn=ldbm database 含空格,ldapsearch 的 -b 参数必须整体加引号,否则会拆成多个参数报错。

二、后缀与后端管理

2.1 查看现有后缀

$ dsconf ds1 -D 'cn=Directory Manager' -w q1w2e3r4 backend suffix list
dc=example,dc=com (userroot)

注意 2.0.15 语法:是 backend suffix list 而非 backend list;-D/-w 必须放在实例名之前(dsconf ds1 -D ... -w ... 子命令),放后面会报 unrecognized arguments。

为免命令行泄露密码,也可用密码文件(本文后续用此法):printf 'q1w2e3r4' > /root/dmpw && chmod 600 /root/dmpw,命令中 -w q1w2e3r4 换成 -y /root/dmpw。

2.2 新建后缀(实测)

$ dsconf ds1 -y /root/dmpw backend create --suffix dc=test,dc=com --be-name testroot --create-suffix
The database was sucessfully created
$ dsconf ds1 -y /root/dmpw backend suffix list
dc=example,dc=com (userroot)
dc=test,dc=com (testroot)

2.3 生效验证

新建后缀立即可查(--create-suffix 自动创建了 dc=test,dc=com 根条目):

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 -b dc=test,dc=com -s base dn
dn: dc=test,dc=com
result: 0 Success

若需承载真实数据,用 LDIF 往里灌条目(导入命令见站内运维篇 4.3 节)。

三、索引管理

3.1 查看现有索引

$ dsconf ds1 -y /root/dmpw backend index list userroot --just-names
aci
cn
entryrdn
entryusn
givenname
mail
mailalternateaddress
mailhost
member
memberof
nscertsubjectdn
nscpentrydn
nsds5replconflict
nstombstonecsn
nsuniqueid
ntuniqueid
ntuserdomainid
numsubordinates
objectclass
owner
parentid
seealso
sn
targetuniqueid
telephonenumber
uid
uniquemember

这是 userroot 的默认索引集(dsconf ds1 backend index list userroot 不加 --just-names 会输出每条索引的完整 LDIF,含 nsIndexType)。

3.2 新增索引并在线重建(实测)

为 employeeNumber 增加 eq + pres 索引,--reindex 让 dsconf 自动提交在线重建任务:

$ dsconf ds1 -y /root/dmpw backend index add userroot --attr employeeNumber --index-type eq --index-type pres --reindex
Index task index_attrs_10282026_030029 completed successfully
Successfully added index

错误日志同步记录了重建过程(实测):

[28/Oct/2026:03:00:29 +0000] - INFO - bdb_db2index - userroot: Indexing attribute: employeeNumber
[28/Oct/2026:03:00:29 +0000] - INFO - bdb_db2index - userroot: Finished indexing.

3.3 生效验证

方式一:cn=config 中出现索引条目:

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 \
  -b 'cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config' '(cn=employeeNumber)'
dn: cn=employeeNumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=conf
nsIndexType: eq
nsIndexType: pres

方式二:用索引属性做等值检索(先给 uid=devuser1 加 employeeNumber: 10086):

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 -b dc=example,dc=com 'employeeNumber=10086' dn cn
dn: uid=devuser1,ou=dev,dc=example,dc=com
cn: Dev One
result: 0 Success

大量数据导入新索引时,用 dsctl ds1 db2index userroot 做离线全量重建(需停实例,见站内运维篇)。

四、日志配置

4.1 日志级别查看与动态调整(实测)

$ dsconf ds1 -y /root/dmpw config get nsslapd-errorlog-level nsslapd-accesslog-level
nsslapd-errorlog-level: 16384
nsslapd-accesslog-level: 256

默认 nsslapd-errorlog-level: 16384(复制审计)。开启 8192(数据库调试)后即时生效,无需重启:

$ dsconf ds1 -y /root/dmpw config replace nsslapd-errorlog-level=8192
Successfully replaced "nsslapd-errorlog-level"
$ dsconf ds1 -y /root/dmpw config get nsslapd-errorlog-level
nsslapd-errorlog-level: 8192

实测提示:级别是位掩码(1 跟踪函数调用、8 连接处理、32 ACL、128 缓存、8192 数据库、16384 复制,可按位或叠加)。调高后日志量显著增长,排障结束记得改回 16384;普通业务排查优先看 access 日志与 logconv 统计(站内运维篇)。

4.2 日志轮转参数

同一配置面可设轮转(示例为按 100MB 轮转、保留归档):

$ dsconf ds1 -y /root/dmpw config replace \
    nsslapd-errorlog-logrotationtime-enabled=on \
    nsslapd-errorlog-logmaxdiskspace=500
Successfully replaced "nsslapd-errorlog-logrotationtime-enabled"
Successfully replaced "nsslapd-errorlog-logmaxdiskspace"

(命令+预期结果:属性名以 dsconf ds1 config get nsslapd-errorlog-log* 实际回显为准;以上两条实测回显均为 Successfully replaced。)

五、内存缓存调优

5.1 autosize 机制

389DS 默认按物理内存自动划分缓存(nsslapd-cache-autosize: 25 = 用 25% 物理内存做数据库缓存)。实测在 20GB 内存主机上:

$ dsconf ds1 -y /root/dmpw backend config get | grep -E 'dbcachesize|autosize'
nsslapd-import-cachesize: 16777216
nsslapd-dbcachesize: 1273795072
nsslapd-import-cache-autosize: -1
nsslapd-cache-autosize: 25
nsslapd-cache-autosize-split: 25

5.2 手工设置缓存(排障实录)

直接设置会被拒绝——这是 2.0.15 的必踩坑(实测原样回显):

$ dsconf ds1 -y /root/dmpw backend config set --dbcachesize 268435456
Error: Server is unwilling to perform - Error: "nsslapd-dbcachesize" can not be updated while "nsslapd-cache-autosize" is set in "cn=config,cn=ldbm database,cn=plugins,cn=config".

正确顺序:先关 autosize,再设缓存:

$ dsconf ds1 -y /root/dmpw backend config set --cache-autosize 0
Successfully updated database configuration
$ dsconf ds1 -y /root/dmpw backend config set --dbcachesize 268435456
Successfully updated database configuration
$ dsconf ds1 -y /root/dmpw backend config get | grep -E 'dbcachesize|cache-autosize:'
nsslapd-dbcachesize: 268435456
nsslapd-cache-autosize: 0

每后端的条目缓存同理(实测设 512MB):

$ dsconf ds1 -y /root/dmpw backend suffix set userroot --cache-memsize 536870912
The backend configuration was successfully updated

5.3 缓存命中率监控(实测)

$ ldapsearch -x -H ldap://127.0.0.1 -D 'cn=Directory Manager' -w q1w2e3r4 \
  -b 'cn=monitor,cn=userroot,cn=ldbm database,cn=plugins,cn=config'
dn: cn=monitor,cn=userroot,cn=ldbm database,cn=plugins,cn=config
entrycachehits: 8
entrycachetries: 14
entrycachehitratio: 57
currententrycachesize: 0
maxentrycachesize: 536870912
dncachehits: 5
dncachetries: 19
dncachehitratio: 26

maxentrycachesize: 536870912 即 5.2 节的设置已生效。运行一段时间后 entrycachehitratio 长期低于 90%,说明条目缓存偏小,优先调大。

六、口令策略(含锁定演练实测)

设置全局策略:3 次失败锁定 60 秒:

$ dsconf ds1 -y /root/dmpw pwpolicy set --pwdlockout on --pwdmaxfailures 3 --pwdlockoutduration 60
Successfully updated global password policy
$ dsconf ds1 -y /root/dmpw pwpolicy get | grep -iE 'lockout|maxfailure'
passwordlockout: on
passwordlockoutduration: 60
passwordmaxfailure: 3

生效演练(测试账号 uid=testuser1,密码 Test1234!):连续 3 次错误绑定均返回 Invalid credentials (49),第 4 次用正确密码(实测原样回显):

$ ldapwhoami -x -H ldaps://ds1.example.com:636 -D 'uid=testuser1,ou=people,dc=example,dc=com' -w Test1234!
ldap_bind: Constraint violation (19)
	additional info: Exceed password retry limit. Please try later.

错误计数按账号累计、与密码正确与否无关;锁定在 passwordlockoutduration(60 秒)后自动解除,也可由管理员手工解锁:

$ dsidm ds1 -y /root/dmpw -b dc=example,dc=com account unlock 'uid=testuser1,ou=people,dc=example,dc=com'
(账号未处锁定期时实测回显:Error: Account is already active)

演练完毕恢复默认:dsconf ds1 -y /root/dmpw pwpolicy set --pwdlockout off。

排障实录:修改用户口令时实测报 Result: Confidentiality required (13) — Operation requires a secure connection.——389DS 默认禁止在未加密连接上执行口令修改。改走 ldaps://(或 StartTLS)即可。

七、TLS 安全参数

$ dsconf ds1 -y /root/dmpw security get
nsslapd-security: on
nsslapd-securelistenhost:
nsslapd-secureport: 636
nssslclientauth: allowed
nstlsallowclientrenegotiation:
nsslapd-require-secure-binds: off
nsslapd-ssl-check-hostname: on
nsslapd-validate-cert: warn
nssslsessiontimeout: 0
sslversionmin: TLS1.2
sslversionmax: TLS1.3
allowweakcipher:

生产加固建议(均可 dsconf ds1 security set ... 或 config replace 完成,重启实例生效):

  • nsslapd-minssf=1:所有绑定走加密(配合 4.3 节);
  • nsslapd-require-secure-binds=on:禁止明文简单绑定;
  • sslversionmin=TLS1.2 已是安全基线,无需放宽。

八、配置变更操作清单(速查)

目标命令骨架生效方式
服务器级属性dsconf ds1 config replace <属性>=<值>即时(个别标注需重启)
数据库全局缓存dsconf ds1 backend config set --dbcachesize N先 --cache-autosize 0,即时
后端条目缓存dsconf ds1 backend suffix set <be> --cache-memsize N即时
索引dsconf ds1 backend index add <be> --attr A --index-type eq --reindex在线任务
口令策略dsconf ds1 pwpolicy set --pwdlockout on ...即时
TLSdsconf ds1 security set --...重启 systemctl restart dirsrv@ds1

系列文档