一、项目目标
用 OpenLDAP 统一存放账号。
iMC 通过 LDAP 读取账号做 MS-CHAP / 802.1X 认证。
提供 自助改密 页面(用户自己改密码)。
提供 图形化管理后台(比 phpLDAPadmin 好用、仍在维护)。
关键约束:iMC 做 MS-CHAP 认证需要 sambaNTPassword 这个字段(NT 哈希 / 或本方案中的明文密码)。普通的 userPassword(SSHA) 不行。
二、最终架构(docker compose 三服务)
数据目录(宿主 bind 挂载,固定为 /srv/openldap):
/srv/openldap/data→/var/lib/ldap/srv/openldap/config→/etc/ldap/slapd.d
compose 网络:默认 openldap_default,服务间用服务名 openldap 互相访问(SSP/LAM 都填 ldap://openldap:389)。
三、关键配置参数(以下均为示例值,部署时请替换为你的真实环境)
账号字段约定(用户定):
uid= 账户名(登录名)cn= 名字sn= 必填,填成账户名(inetOrgPerson 强制要求 sn)
四、目录结构与文件清单
/srv/openldap/ # 宿主部署目录(bind 挂载源)
├── docker-compose.yml
├── .env
├── openldap/
│ ├── Dockerfile # 基于 osixia,补装 slapd-contrib
│ └── bootstrap/ # samba.schema + seed(bootstrap 阶段加载)
├── ssp-conf/
│ ├── config.inc.local.php # SSP PHP 配置(覆盖默认)
│ └── posthook-update-smbnt.php # 改密后同步明文到 sambaNTPassword
├── scripts/
│ ├── add_user.sh # 建号(自动建 OU + 写明文密码)
│ ├── setup-smbk5pwd.sh # 手动加载 smbk5pwd overlay(已加载,可不动)
│ └── (备份)add_user.sh.* / setup-smbk5pwd.sh.back
├── config/ # slapd.d 配置库(持久化)
└── data/ # LDAP 数据(持久化)
本文档以 test.com.cn / dc=test,dc=com,dc=cn 作为示例域名;实际部署时请将全文统一替换为你的真实域名与 Base DN。
五、核心技术方案(最重要的认知)
5.1 iMC 对通用 OpenLDAP 的密码处理方式
这是整个方案的关键转折点。
H3C iMC 官方的 MS-CHAPv2 案例全部基于 Windows AD:iMC 用"虚拟计算机账号"加入 AD,直接从 AD 取 NT 哈希。
但接的是 通用 OpenLDAP(不是 AD)时,iMC 没有"取 NT 哈希"的机制,只能退而求其次:从你指定的"用户密码属性"读取明文密码,再自己算 NT 哈希。
结论:
sambaNTPassword放 NT 哈希(32 位 hex)→ iMC 把 hex 当明文再 MD4 一遍 → 错误 → 报E63032 密码错误。sambaNTPassword放 明文密码 → iMC 自己 MD4 → 正确 → 认证通过。
所以本方案让 sambaNTPassword 存明文(不是 NT 哈希)。
5.2 因此方案做了这些调整
add_user.sh:直接把明文密码写入sambaNTPassword(不再用 smbk5pwd / exop / NT 哈希双保险)。SSP:关闭
$samba_mode(它会写 NT 哈希),改用$posthook,在改密成功后把新明文同步到sambaNTPassword。smbk5pwdoverlay:对 iMC 场景不再必要(已加载也无害,仅 exop 触发)。
5.3 两个密码字段的区别(务必理解)
posthook 的作用:用户在 SSP 网页改密后,自动把新明文同步写进 sambaNTPassword,保证两个字段一致,iMC 才能用新密码认证。
5.4 安全注意
sambaNTPassword的 schema 长度限制是 32 字符,密码超过 32 位会写不进去(密码策略别设太长)。该字段以明文存储密码;当前 ACL 已禁止匿名读取,但管理员和用户本人仍可读到。
如果以后 iMC 版本支持"NT 哈希模式"或切到 AD,建议改回存 NT 哈希。
六、踩坑记录(时间线,含已推翻的错误假设)
注:早期关于"重启循环是 bind 挂载权限 / 坏配置"的判断,最终被第 4 条证伪——真正元凶是
USER openldap。
七、当前状态(截至 2026-07-31 18:06,posthook 闭环后订正)
✅ 三个容器均
Up:openldap、ldap-ssp、ldap-lam✅
smbk5pwdoverlay 已加载并持久化(olcOverlay={2}smbk5pwd)✅
ou=students、ou=teachers两个 OU 已建✅ 测试账号已建:
uid=zhangsan,ou=students,...(cn=张三,初始zhangsan@123)示例账号:
uid=zhangsan2,ou=students,...(cn=张三2,密码Test@1234;两字段一致,可用于 iMC 测试)
✅ 已闭环:服务器上
$posthook的php前缀已加上(第 49 行 ="php /var/www/conf/posthook-update-smbnt.php"),SSP 自助改密可正常同步明文到sambaNTPassword,整条链路完整跑通。
八、待办事项
1. ✅【已完成】补 SSP posthook 的 php 前缀
服务器第 49 行已确认为 "php /var/www/conf/posthook-update-smbnt.php",SSP 自助改密同步已生效,该项关闭。
2. 【建议】iMC 实测
在 iMC 侧:
接入类型:LDAP
服务器:
ldap://<服务器IP>:389Base DN(只同步学生组):
ou=students,dc=test,dc=com,dc=cn用户密码属性:
sambaNTPassword(iMC 当明文读,自己算 NT 哈希)认证协议:MS-CHAPv2
测试账号:
zhangsan2/Test@1234
3. 【可选】建号工具补充
管理员重置密码脚本(同时重置
userPassword+sambaNTPassword):待补充reset_user.sh教师组账号:
./add_user.sh <uid> <cn> [密码] teachers
九、常用命令速查
# 建学生组账号(默认组 students)
./scripts/add_user.sh <uid> <cn> [密码]
# 建教师组账号
./scripts/add_user.sh <uid> <cn> [密码] teachers
# 查账号 + NT 哈希
docker exec openldap ldapsearch -x -D "cn=admin,dc=test,dc=com,dc=cn" -w 'Admin@1234,a' \
-b "ou=students,dc=test,dc=com,dc=cn" "(uid=<uid>)" dn sambaNTPassword sambaSID
# 手动触发 posthook(绕过 SSP,验证脚本本身)
docker exec ldap-ssp php /var/www/conf/posthook-update-smbnt.php <uid> <新明文密码>
# 管理员重置某账号密码(同时两字段)
docker exec openldap ldappasswd -x -D "cn=admin,dc=test,dc=com,dc=cn" -w 'Admin@1234,a' \
-s '<新密码>' "uid=<uid>,ou=students,dc=test,dc=com,dc=cn"
docker exec -i openldap ldapmodify -x -D "cn=admin,dc=test,dc=com,dc=cn" -w 'Admin@1234,a' <<LDIF
dn: uid=<uid>,ou=students,dc=test,dc=com,dc=cn
changetype: modify
replace: sambaNTPassword
sambaNTPassword: <新密码>
LDIF
# 看容器状态
docker ps
# 看 openldap 日志
docker logs --tail 40 openldap
十、一句话总结
OpenLDAP 存账号、sambaNTPassword 存明文密码(iMC 读它自己算 NT 哈希做 MS-CHAPv2)、SSP 自助改密通过 posthook 把明文同步进 sambaNTPassword、LAM 做图形管理。整条链路(建号 / 改密 / iMC 认证)已全部跑通并完成闭环,可直接用于生产或分发给同事部署。