LDAP Account Manager 9.7 常用 CLI 命令与工具详解

讲清 LAM 9.7 的 CLI 运维工具链:ldap-utils 七件套增删改查实测、slapcat/slapadd 数据与配置库备份恢复闭环、lamdaemon 配额家目录机制、systemctl 管控、会话清理与日志轮转,全部在 Debian 13.7 + OpenLDAP 2.6.10 环境实测。

LDAP Account ManagerLDAP Account ManagerLDAP 协议PHP 编程2026/10/28

LDAP Account Manager 9.7 常用 CLI 命令与工具详解

目标:讲清 LDAP Account Manager(LAM)日常运维所需的全部命令行工具——ldap-utils 套件对目录数据的增删改查、slapcat/slapadd 的备份与恢复、lamdaemon 的配额与家目录管理、systemctl 服务管控、会话与临时文件清理、日志文件轮转——并逐条给出实测回显。本文全部命令已在 Debian 13.7(x86_64)+ OpenLDAP slapd 2.6.10 + Apache 2.4.69 + PHP 8.4.27 + LAM 9.7-1 环境实测通过,实测日期 2026-10-28。

一、环境信息

  • 操作系统:Debian 13.7(trixie,x86_64),systemd 引导
  • 目录服务后端:OpenLDAP slapd 2.6.10+dfsg-1(同机部署,数据后缀 dc=example,dc=net,配置库 cn=config)
  • Web 环境:Apache 2.4.69(event MPM)+ libapache2-mod-php(PHP 8.4.27)
  • LDAP Account Manager:9.7-1(官方 deb 包)+ 可选包 ldap-account-manager-lamdaemon 9.7-1
  • CLI 工具版本:ldap-utils 2.6.10+dfsg-1、logrotate 3.22.0(版本实测见 2.2)
  • 目录内测试条目:uid=tester1,ou=people,dc=example,dc=net(密码 q1w2e3r4,由 LAM 界面创建)、cn=users,ou=groups,dc=example,dc=net
  • 演示账号:目录管理员 DN cn=admin,dc=example,dc=net(密码 q1w2e3r4)
  • LAM 服务器 profile:lam,activeTypes 为 user,group
  • 安装过程见 《Debian 13 安装 LDAP Account Manager 9.7 指南》,配置参数语义见 《LDAP Account Manager 9.7 配置参数详解》

二、工具概览

2.1 定位:LAM 没有自己的 CLI

先明确一个容易找错方向的定位:LAM 9.7 不提供任何专属命令行管理工具。deb 包内没有 LAM 管理命令,可选包 ldap-account-manager-lamdaemon 里也只有一个供 SSH 远程调用的 Perl 脚本(lamdaemon.pl),不是交互式 CLI。LAM 的全部管理功能都在 Web 界面,它的 CLI 运维由四类系统级工具构成,LAM 只是这些工具的管理对象:

工具所属包用途是否随 LAM 自带
ldapsearch/ldapadd/ldapmodify/ldapdelete/ldappasswd/ldapwhoami/ldapcompareldap-utils直接操作 LDAP 目录数据:查/增/改/删/改密/验证/比对否,装 OpenLDAP 客户端即有
slapcat/slapaddslapd数据库与配置库的备份/恢复否,装 slapd 即有
lamdaemon.plldap-account-manager-lamdaemon供 LAM Web 端经 SSH 调用,管理 shell 服务器上的配额与家目录可选包
systemctlsystemd管控承载 LAM 的 apache2 与后端 slapd系统自带
会话/临时文件清理手工清理 /var/lib/ldap-account-manager/ 下的 sess/ 与 tmp/—
logrotatelogrotate轮转 LAM 文件日志与审计日志系统通常自带

分工解读:LAM 界面是"人管数据",ldap-utils 是"脚本管数据"——两者操作同一个目录,LAM 界面建的用户在命令行同样可见、可改;slapcat/slapadd 管"数据本身的安全";lamdaemon 管"LAM 界面够不着的远端机器";systemctl 管"承载 LAM 的两个服务"。

2.2 版本与包归属确认

ldapsearch -VV | head -1
dpkg -S /usr/bin/ldapsearch /usr/sbin/slapcat /usr/share/ldap-account-manager/lib/lamdaemon.pl
dpkg -l ldap-account-manager-lamdaemon | tail -1

实测回显:

ldapsearch: @(#) $OpenLDAP: ldapsearch 2.6.10+dfsg-1 (May 29 2025 23:41:48) $
ldap-utils: /usr/bin/ldapsearch
slapd: /usr/sbin/slapcat
ldap-account-manager-lamdaemon: /usr/share/ldap-account-manager/lib/lamdaemon.pl
ii  ldap-account-manager-lamdaemon 9.7-1        all          Quota and home directory management for LDAP Account Manager

三、前置条件

其一,绑定凭据可用。所有 ldap-utils 命令的公共前置是能绑定目录,排障第一步:

ldapwhoami -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4

实测回显:

dn:cn=admin,dc=example,dc=net

参数全文通用:-x 简单认证;-H 服务地址;-D 绑定 DN;-w 绑定密码。生产环境把密码换成 -W(交互输入)或 -y <文件>(从文件读,文件权限设 600),避免密码进入 shell 历史与脚本;本文为演示可执行性使用明文。

其二,LAM 侧已就绪。服务器 profile lam 已配置、Web 登录可用(安装与初始化见 B1,profile 参数见 C1)。CLI 与 Web 操作的是同一目录、没有"同步"概念:本文的 uid=tester1 由 LAM 界面创建,全程用 CLI 操作,两边改动即时互见。

其三,lamdaemon 为可选组件。仅在需要"LAM 界面管理远程 shell 服务器的家目录与配额"时安装(见第六节),不影响本文其余内容。

四、ldap-utils 套件详解

七个命令按"查—验证—比—增—改—密—删"的运维动线排列,全部实测。

4.1 ldapwhoami:绑定验证

最轻量的连通性与凭据检查。错误密码实测:

ldapwhoami -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w wrongpass; echo exit=$?

实测回显:

ldap_bind: Invalid credentials (49)
exit=49

Invalid credentials (49) 是 LDAP 体系最常见的报错,含义是"DN 或密码不对"但不会细分是哪种——批量改密后验证凭据全靠它的退出码。

4.2 ldapsearch:查询

查全目录条目 DN(-b 搜索起点,末尾 dn 是要返回的属性):

ldapsearch -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -b dc=example,dc=net dn

实测回显:

# extended LDIF
#
# LDAPv3
# base <dc=example,dc=net> with scope subtree
# filter: (objectclass=*)
# requesting: dn 
#

# example.net
dn: dc=example,dc=net

# people, example.net
dn: ou=people,dc=example,dc=net

# groups, example.net
dn: ou=groups,dc=example,dc=net

# users, groups, example.net
dn: cn=users,ou=groups,dc=example,dc=net

# tester1, people, example.net
dn: uid=tester1,ou=people,dc=example,dc=net

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5

脚本场景用 -LLL 输出纯 LDIF(去掉注释与统计信息):

ldapsearch -LLL -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -b ou=people,dc=example,dc=net "(uid=tester1)" uid cn

实测回显:

dn: uid=tester1,ou=people,dc=example,dc=net
uid: tester1
cn: Test User

要点:过滤器 (uid=tester1) 放在 -b 之后;末尾列出的属性决定返回什么(省略则返回全部);-LLL 是巡检/监控脚本的标准姿势。

4.3 ldapcompare:属性比对

不动数据的轻量断言,适合监控脚本判断状态:

ldapcompare -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 "uid=tester1,ou=people,dc=example,dc=net" "uid:tester1"; echo exit=$?

实测回显(匹配):

TRUE
exit=6

不匹配实测(比对 uid:nonexistent):

FALSE
exit=5

要点:ldapcompare 用退出码而非输出传结果——TRUE=6、FALSE=5,与多数命令"0 即成功"的直觉相反,脚本判断 $? 时别踩坑。

4.4 ldapadd:添加条目

LDIF 文件方式添加。先写 /tmp/add-tester2.ldif:

dn: uid=tester2,ou=people,dc=example,dc=net
objectClass: inetOrgPerson
objectClass: posixAccount
uid: tester2
cn: Tester Two
sn: Two
uidNumber: 10002
gidNumber: 10000
homeDirectory: /home/tester2

执行:

ldapadd -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -f /tmp/add-tester2.ldif

实测回显:

adding new entry "uid=tester2,ou=people,dc=example,dc=net"

重复添加同一 DN 实测报错:

ldapadd -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -f /tmp/add-tester2.ldif; echo exit=$?

实测回显:

ldap_add: Already exists (68)
adding new entry "uid=tester2,ou=people,dc=example,dc=net"
exit=68

要点:objectClass 决定必填属性——inetOrgPerson 要 cn/sn,posixAccount 要 uidNumber/gidNumber/homeDirectory;报 68 说明 DN 已存在,幂等脚本先探测再增删。

4.5 ldapmodify:修改条目

修改走 LDIF 的 changetype: modify。写 /tmp/mod-tester1.ldif:

dn: uid=tester1,ou=people,dc=example,dc=net
changetype: modify
replace: description
description: modified by ldapmodify

执行并回读验证:

ldapmodify -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -f /tmp/mod-tester1.ldif
ldapsearch -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -b uid=tester1,ou=people,dc=example,dc=net -s base description

实测回显:

modifying entry "uid=tester1,ou=people,dc=example,dc=net"
# extended LDIF
#
# LDAPv3
# base <uid=tester1,ou=people,dc=example,dc=net> with scope baseObject
# filter: (objectclass=*)
# requesting: description 
#

# tester1, people, example.net
dn: uid=tester1,ou=people,dc=example,dc=net
description: modified by ldapmodify

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

要点:replace: 整体替换属性值;删除属性用 delete: description;-s base 只查目标条目本身不做子树搜索。

4.6 ldappasswd:密码管理

管理员为用户改密(-D/-w 是管理员凭据,-s 给新密码,目标 DN 放最后):

ldappasswd -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -s "newpass123" "uid=tester1,ou=people,dc=example,dc=net"

实测回显:命令无输出即成功。

分别用新、旧密码验证:

ldapwhoami -x -H ldap://localhost -D "uid=tester1,ou=people,dc=example,dc=net" -w newpass123
ldapwhoami -x -H ldap://localhost -D "uid=tester1,ou=people,dc=example,dc=net" -w q1w2e3r4; echo exit=$?

实测回显:

dn:uid=tester1,ou=people,dc=example,dc=net
ldap_bind: Invalid credentials (49)
exit=49

要点:管理员绑定可为任意用户改密、无需旧密码;按 ldappasswd(1) 手册口径,-D 用用户自己的 DN 且省略 -s 时服务器生成随机密码并打印(自助改密场景)。口令在目录里以哈希落盘(实测 slapcat 可见 userPassword:: e1NTSEF9...,即 {SSHA} 的 base64 形态),ldappasswd 走 LDAP Password Modify 扩展,与 LAM 界面改密等效。

4.7 ldapdelete:删除条目

ldapdelete -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 "uid=tester2,ou=people,dc=example,dc=net"
ldapsearch -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -b ou=people,dc=example,dc=net dn | grep "^dn:"

实测回显(删除无输出,回查确认只剩 tester1):

dn: ou=people,dc=example,dc=net
dn: uid=tester1,ou=people,dc=example,dc=net

删除非空 OU 实测报错:

ldapdelete -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 "ou=people,dc=example,dc=net"; echo exit=$?

实测回显:

ldap_delete: Operation not allowed on non-leaf (66)
	additional info: subordinate objects must be deleted first
exit=66

要点:ldapdelete 只能删叶子条目,报 66 说明其下还有子条目;LDAP 目录默认没有引用完整性——CLI 删除用户不会自动把它从组里移除,组内残留的成员属性需另行清理(LAM 界面删除用户时会一并处理组关系,这是两者行为差异最大的地方)。

五、slapcat 与 slapadd:数据备份与恢复

5.1 两个数据库与落盘形态

OpenLDAP 有两个独立数据库:编号 -n 0 是配置库(cn=config,对应 /etc/ldap/slapd.d/),编号 -n 1 是数据数据库(本文为 dc=example,dc=net,对应 /var/lib/ldap/)。数据目录原始文件实测:

ls -la /var/lib/ldap/

实测回显:

total 136
drwxr-xr-x 2 openldap openldap   4096 Oct 28 10:56 .
drwxr-xr-x 1 root     root       4096 Oct 28 11:06 ..
-rw------- 1 openldap openldap 122880 Oct 28 12:10 data.mdb
-rw------- 1 openldap openldap   8192 Oct 28 12:10 lock.mdb

数据以 LMDB 双文件落盘(data.mdb/lock.mdb,属主 openldap、权限 600)。服务运行时直接复制 .mdb 文件有拿到不一致快照的风险,标准备份方式是 slapcat 导出 LDIF。

5.2 在线备份 slapcat

slapcat 是只读导出,slapd 运行中即可执行:

slapcat -n 1 -l /tmp/backup-data.ldif
slapcat -n 0 -l /tmp/backup-config.ldif
wc -l /tmp/backup-data.ldif /tmp/backup-config.ldif

实测回显:

  69 /tmp/backup-data.ldif
  667 /tmp/backup-config.ldif
  736 total

数据备份文件头部实测节选(每个条目自带 entryUUID/entryCSN 等运行时属性,恢复时原样写回、条目身份不丢):

dn: dc=example,dc=net
objectClass: top
objectClass: dcObject
objectClass: organization
o: example.net
dc: example
structuralObjectClass: organization
entryUUID: e6ae7ff2-6709-1041-8358-f5b6e2785e8d
creatorsName: cn=admin,dc=example,dc=net
createTimestamp: 20261028105558Z
entryCSN: 20261028105558.375446Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=net
modifyTimestamp: 20261028105558Z

要点:两份备份都要做——-n 1 丢的是数据,-n 0 丢的是 schema、ACL、索引等全部服务端配置;只备前者,新机器会因配置库缺失而起不来。

5.3 数据库恢复闭环(实测)

恢复前必须停 slapd。实测全流程:

systemctl stop slapd
systemctl is-active slapd
rm -f /var/lib/ldap/data.mdb /var/lib/ldap/lock.mdb
ls -la /var/lib/ldap/

实测回显:

inactive
total 12
drwxr-xr-x 2 openldap openldap 4096 Oct 28 12:10 .
drwxr-xr-x 1 root     root     4096 Oct 28 11:06 ..

导入并修正属主、重启、验证:

slapadd -n 1 -l /tmp/backup-data.ldif
echo exit=$?
chown -R openldap:openldap /var/lib/ldap
systemctl start slapd
systemctl is-active slapd
ldapsearch -x -H ldap://localhost -D "cn=admin,dc=example,dc=net" -w q1w2e3r4 -b dc=example,dc=net dn | grep "^dn:"
ldapwhoami -x -D "uid=tester1,ou=people,dc=example,dc=net" -w q1w2e3r4

实测回显:

0
active
dn: dc=example,dc=net
dn: ou=people,dc=example,dc=net
dn: ou=groups,dc=example,dc=net
dn: cn=users,ou=groups,dc=example,dc=net
dn: uid=tester1,ou=people,dc=example,dc=net
dn:uid=tester1,ou=people,dc=example,dc=net

5 个条目全部回来,且 tester1 用原密码直接绑定成功(实测最后一行)——userPassword 的哈希随 LDIF 一起恢复了。

要点:

  • 属主是恢复成败的关键:slapadd 以 root 执行时新文件属主跟随执行者,恢复后统一 chown -R openldap:openldap /var/lib/ldap,否则 slapd 读不了库。
  • slapadd 成功时静默(退出码 0、无输出)。

5.4 配置库恢复闭环(实测)

systemctl stop slapd
ls /etc/ldap/slapd.d/ | head -2
rm -rf /etc/ldap/slapd.d/*
slapadd -n 0 -F /etc/ldap/slapd.d -l /tmp/backup-config.ldif
echo exit=$?
ls /etc/ldap/slapd.d/ | head -2
chown -R openldap:openldap /etc/ldap/slapd.d
systemctl start slapd
systemctl is-active slapd
ldapwhoami -x -D "cn=admin,dc=example,dc=net" -w q1w2e3r4

实测回显:

cn=config
cn=config.ldif
0
cn=config
cn=config.ldif
active
dn:cn=admin,dc=example,dc=net

要点:配置库恢复同样要停服;-F 必须指向 /etc/ldap/slapd.d;属主同样要还给 openldap。

5.5 在线 slapadd 的报错(实测)

slapd 运行中、目标库非空时直接 slapadd:

slapadd -n 1 -l /tmp/backup-data.ldif; echo exit=$?

实测回显:

mdb_id2entry_put: mdb_put failed: MDB_KEYEXIST: Key/data pair already exists(-30799) "dc=example,dc=net"
=> mdb_tool_entry_put: id2entry_add failed: err=-30799
=> mdb_tool_entry_put: txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
slapadd: could not add entry dn="dc=example,dc=net" (line=1): txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
exit=1

要点:根因是"目标库已有数据";事务中止后库保持原样、无半写状态。恢复的标准姿势永远是"停服 → 清空数据文件 → slapadd → chown → 起服"。

六、lamdaemon:配额与家目录管理脚本

6.1 机制与 profile 参数

LAM 界面上"创建家目录/设置磁盘配额"这类操作,目标不是 LDAP 目录,而是家目录所在的 shell 服务器。LAM 的实现:Web 进程按 profile 里的 SSH 参数连到目标机器,执行服务器上的 lamdaemon.pl,由它在本机完成家目录创建、quota 设置。链路如下:

LAM (Apache/PHP) --SSH--> scriptUserName@scriptServer --sudo--> lamdaemon.pl(本机执行 quota/家目录操作)

profile 中对应的参数出厂值实测:

grep -o '"scriptPath": "[^"]*"\|"scriptServer": "[^"]*"\|"scriptRights": "[^"]*"\|"scriptUserName": "[^"]*"' /var/lib/ldap-account-manager/config/lam.conf

实测回显:

"scriptPath": ""
"scriptServer": ""
"scriptRights": "750"
"scriptUserName": ""

参数含义:scriptPath 目标机上 lamdaemon.pl 的绝对路径;scriptServer 目标机地址;scriptUserName SSH 登录用户;scriptRights 新建家目录的权限(出厂 750);另有 scriptSSHKey 支持私钥认证。配置修改方式见 C1 第三节(Web 界面或直接编辑 JSON,新会话生效)。

6.2 服务端安装与 sudo 授权

在"家目录所在的那台机器"(不是 LAM 所在机器)安装可选包:

apt-get install -y ldap-account-manager-lamdaemon
dpkg -L ldap-account-manager-lamdaemon

实测回显(包内只有脚本与文档):

/.
/usr
/usr/share
/usr/share
/usr/share/doc
/usr/share/doc/ldap-account-manager-lamdaemon
/usr/share/doc/ldap-account-manager-lamdaemon/README.Debian
/usr/share/doc/ldap-account-manager-lamdaemon/changelog.Debian.gz
/usr/share/doc/ldap-account-manager-lamdaemon/changelog.gz
/usr/share/doc/ldap-account-manager-lamdaemon/copyright
/usr/share/ldap-account-manager
/usr/share/ldap-account-manager/lib
/usr/share/ldap-account-manager/lib/lamdaemon.pl

按包内 README.Debian 原文(实测摘录):脚本由 LAM 主安装经 SSH 调用,需为执行用户配置免密 sudo:

This package installs the lamdaemon scripts on the server where
home directories and/or quotas are managed.

The scripts are called by the main LDAP Account Manager installation
via SSH.

You will have to setup sudo for these scripts. Please see the
documentation in package ldap-account-manager for this topic.

Example sudo entry:

someuser  ALL= NOPASSWD: /usr/share/ldap-account-manager/lib/lamdaemon.pl *

即把示例条目落到 /etc/sudoers.d/(someuser 换成 scriptUserName 对应的系统用户);SSH 认证用密码或 scriptSSHKey 指定的私钥均可。

6.3 实测边界说明

本文实测环境为单机部署(LAM 与 LDAP 同机、无独立 shell 服务器),SSH 联动链路未做端到端实测;6.1 的参数出厂值、6.2 的包文件与 sudoers 授权口径均为实测与官方包内文档摘录。联调建议的检查顺序:先在目标机用 sudo -l -U <用户> 核对授权、确认 SSH 凭据可登录,再到 LAM 界面做一次家目录创建;失败时把主配置 logLevel 调到 7 看 LAM 日志(见 C1 5.1.3),同时查目标机 syslog。

七、systemctl:服务管控

LAM 无独立服务,systemd 只托管承载它的 apache2 与后端 slapd。slapd 状态实测:

systemctl status slapd --no-pager -n 3 | head -12

实测回显:

● slapd.service - OpenLDAP Server Daemon
     Loaded: loaded (/usr/lib/systemd/system/slapd.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-10-28 12:10:31 UTC; 19s ago
 Invocation: 8e043d764ab84eae9de9885dbe813551
       Docs: man:slapd
             man:slapd-config
             man:slapd-mdb
   Main PID: 19378 (slapd)
      Tasks: 3 (limit: 19553)
     Memory: 3.8M (peak: 4.9M)
        CPU: 17ms
     CGroup: /system.slice/slapd.service

重启与状态检查:

systemctl restart slapd && systemctl is-active slapd
systemctl restart apache2 && systemctl is-active apache2

实测回显:

active
active

要点:改 /etc/ldap-account-manager/ 下的 LAM 配置文件不需要重启任何服务(LAM 每个新会话重读配置,见 C1 第三节);只有改 php.ini、Apache 虚拟主机这类底层配置才需要 systemctl restart apache2。

八、会话与临时文件清理

8.1 会话文件 sess/

LAM 把 PHP 会话存在自己的目录(不落 php.ini 默认的 /var/lib/php/sessions)。登录一次后实测:

ls -la /var/lib/ldap-account-manager/sess/

实测回显:

total 24
drwx------ 2 www-data root      4096 Oct 28 12:11 .
drwxr-xr-x 5 root     root      4096 Oct 28 11:22 ..
-rw-r--r-- 1 root     root        40 Oct  2 05:30 .htaccess
-rw------- 1 www-data www-data 11791 Oct 28 12:11 sess_e2f0e97c2d97261d500e97cfa23ae0ec

解读:sess_* 文件即登录会话(一个在线浏览器会话一个文件,属主 www-data);.htaccess 是 deb 包自带的 Web 访问拒绝配置,不要删。

为什么需要手工清理:Debian 的系统级会话清理任务 /etc/cron.d/php(每 30 分钟触发 /usr/lib/php/sessionclean)只按 php.ini 的 session.save_path 清文件;而 PHP 自身的概率 GC 在 Debian 的 php.ini 里被禁用(实测 session.gc_probability = 0)。LAM 自定义的 sess 目录两套机制都覆盖不到,长期运行需要管理员兜底:

rm -f /var/lib/ldap-account-manager/sess/sess_*

实测清理后目录只剩 .htaccess 一个文件。注意:清理会话文件等于强制对应用户重新登录,应安排在变更窗口;若只是想缩短在线时长,应调主配置 sessionTimeout(分钟级滑动窗口,见 C1 5.1.2),而不是靠删文件。

8.2 临时文件目录 tmp/

/var/lib/ldap-account-manager/tmp/ 存放 Web 操作的过程性文件,实测结构:

ls -laR /var/lib/ldap-account-manager/tmp/

实测回显:

/var/lib/ldap-account-manager/tmp/:
total 16
drwx------ 3 www-data root 4096 Oct 28 11:53 .
drwxr-xr-x 5 root     root 4096 Oct 28 11:22 ..
-rw-r--r-- 1 root     root  220 Oct  2 05:30 .htaccess
drwxr-xr-x 2 www-data root 4096 Oct 28 11:22 internal

/var/lib/ldap-account-manager/tmp/internal:
total 12
drwxr-xr-x 2 www-data root 4096 Oct 28 11:22 .
drwx------ 3 www-data root 4096 Oct 28 12:25 ..
-rw-r--r-- 1 root     root   40 Oct  2 05:30 .htaccess

清理实测(保留目录结构与其中的 .htaccess,先放一个 dirty.txt 模拟残留):

find /var/lib/ldap-account-manager/tmp/ -mindepth 1 -type f ! -name ".htaccess" -delete
ls -la /var/lib/ldap-account-manager/tmp/

实测回显:

total 16
drwx------ 3 www-data root 4096 Oct 28 12:25 .
drwxr-xr-x 5 root     root 4096 Oct 28 11:22 ..
-rw-r--r-- 1 root     root  220 Oct  2 05:30 .htaccess
drwxr-xr-x 2 www-data root 4096 Oct 28 11:22 internal

要点:internal/ 子目录为 LAM 自用(实测为空),清理时保留目录本身;同目录可加进 cron(如每日一次)实现例行清理。

九、日志文件轮转

LAM 的文件日志(logDestination 设为文件路径)与审计日志(auditLogType: FILE)按行追加,LAM 不自带轮转配置——实测 /etc/logrotate.d/ 下 deb 包未提供任何 LAM 相关文件,需管理员自行添加。

实测开启两个日志(logLevel: 5、logDestination: /var/log/lam/lam.log、auditLogType: FILE、auditLogTarget: /var/log/lam/audit.log,目录属主 www-data):

mkdir -p /var/log/lam && chown www-data:www-data /var/log/lam

登录一次后落盘实测:

ls -la /var/log/lam/

实测回显:

-rw-r--r-- 1 www-data www-data  157 Oct 28 12:20 audit.log
-rw-r--r-- 1 www-data www-data  526 Oct 28 12:20 lam.log

两类日志各取一行(实测):

2026-10-28 12:20:24: LDAP Account Manager (21a2051c0d0b9b86ea9e4cc8fdea35a4 - 127.0.0.1 - cn=admin,dc=example,dc=net) - NOTICE: User cn=admin,dc=example,dc=net (127.0.0.1) successfully logged in.
2026-10-28 12:20:24 LDAP Account Manager AuditLog (21a2051c0d0b9b86ea9e4cc8fdea35a4 - 127.0.0.1 - cn=admin,dc=example,dc=net) - Login to server profile: lam

审计日志连"登录 profile"事件也记录,排障时先看它。

logrotate 配置,写入 /etc/logrotate.d/lam:

/var/log/lam/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    copytruncate
    dateext
}

关键选择是 copytruncate:LAM 进程以追加方式持续持有文件句柄,标准 create 式轮转后旧句柄仍写旧文件名;copytruncate 复制后原地截断,无需重启 Apache。delaycompress 让最近一份轮转件先保持未压缩、下轮再压缩。强制轮转实测:

logrotate -f /etc/logrotate.d/lam
ls -la /var/log/lam/

实测回显:

-rw-r--r-- 1 www-data www-data    0 Oct 28 12:20 audit.log
-rw-r--r-- 1 www-data www-data  314 Oct 28 12:20 audit.log-20261028
-rw-r--r-- 1 www-data www-data    0 Oct 28 12:20 lam.log
-rw-r--r-- 1 www-data www-data 1052 Oct 28 12:20 lam.log-20261028

轮转后再登录,日志继续写新的 lam.log(实测尾部一行):

2026-10-28 12:20:52: LDAP Account Manager (9f318cf48306a3aa7b284f0bb7420a9d - 127.0.0.1 - cn=admin,dc=example,dc=net) - NOTICE: User cn=admin,dc=example,dc=net (127.0.0.1) successfully logged in.

要点:轮转件后缀 lam.log-20261028 来自 dateext;看不到 .gz 是 delaycompress 的正常表现(下轮才压缩)。

十、注意事项

  • CLI 与 LAM 界面操作同一目录,改动即时互见;大批量导入/变更走 CLI(LDIF),单条日常维护留给界面。
  • 密码传参三姿势:明文 -w(演示用)、交互 -W、文件 -y;脚本与共享终端环境一律 -y 并给文件 600 权限。
  • slapadd 前必须停 slapd,恢复后必须 chown openldap:openldap(数据 /var/lib/ldap、配置 /etc/ldap/slapd.d 两处都要)。
  • 备份成对做:-n 1 数据库 + -n 0 配置库;只备数据,新机器会缺 schema/索引/ACL。
  • ldapcompare 退出码 TRUE=6、FALSE=5,监控脚本判断返回码别套"0 为真"的习惯。
  • 清理 sess/ 等于强制重登;目录里的 .htaccess 一律不删。
  • logrotate 必须 copytruncate,否则轮转后日志仍写进旧句柄、新文件恒为空。

十一、常见问题(FAQ)

Q1:绑定报 Invalid credentials (49)? DN 或密码之一错误(不细分)。先 ldapsearch -x -D ... -s base -b <DN> dn 确认 DN 存在,再核对密码;LAM 登录页报错与 CLI 报 49 是同一目录行为,可互相印证。

Q2:ldapadd 报 Already exists (68)? DN 已存在。幂等脚本先 ldapsearch -LLL -b <后缀> "(uid=xxx)" dn 探测,存在则跳过或改走 ldapmodify。

Q3:slapadd 报 MDB_KEYEXIST ... (-30799)? 目标库非空。停 slapd、清空数据文件后再 slapadd(见 5.5),事务中止不会留半写数据。

Q4:slapadd 恢复后 slapd 正常启动,但绑定失败/查不到数据? 先查文件属主:数据文件必须是 openldap:openldap(600),配置库目录树同理;补 chown -R openldap:openldap 后重启 slapd(见 5.3/5.4)。

Q5:LAM 界面的家目录/配额按钮不生效? lamdaemon 链路未通。逐项核对:profile 的 scriptServer/scriptPath/scriptUserName 是否已填、目标机是否安装 ldap-account-manager-lamdaemon、sudoers 是否按 6.2 放行、SSH 凭据能否登录目标机。

Q6:LAM 有自带日志轮转吗? 没有。deb 包不往 /etc/logrotate.d/ 放文件(实测),文件日志与审计日志都按第九节自行配置。

Q7:清理 sess/ 目录后用户必须重新登录? 是,sess 文件就是会话本体。想缩短期限应调 sessionTimeout(见 C1 5.1.2),清理文件只用于长期残留兜底。

十二、参考链接