若忘记 admin 密码,如何通过本地.ini 的 [admins] 段重置并立即生效?
解读
国内生产环境常把 CouchDB 部署在 Linux 服务器或 K8s 集群中,运维人员一旦遗失 admin 密码,既无法调用 /_config 接口,也无法登录 Fauxton 控制台。此时唯一零依赖、零停机的办法就是直接改写本地 ini 文件中的 [admins] 段,让 CouchDB 在下一次外部请求触发时自动把明文密码哈希化并覆盖旧值,从而立即生效。面试官想确认候选人是否理解“哈希替换”机制、是否知道 ini 加载顺序以及是否具备线上最小权限操作意识。
知识点
- CouchDB 配置层叠:default.ini → default.d/.ini → local.ini → local.d/.ini,后者覆盖前者;local.ini 通常由运维自行维护,升级不会被覆盖。
- [admins] 段规则:键即用户名,值可以是明文或已哈希的 -pbkdf2-… 串;CouchDB 发现明文后,会当场哈希并写回文件,随后内存生效。
- 哈希算法:默认 PBKDF2,迭代 10 000 次,SHA1 作为 PRF,长度 20 字节,盐长度 16 字节;该过程由哈希模块 couch_passwords 完成,无需外部工具。
- 触发条件:任意一次需要认证的外部 HTTP 请求(如 curl -u new:pass http://127.0.0.1:5984/_session)都会迫使 CouchDB 重载 [admins] 段并完成哈希化;无需重启服务。
- 文件权限:ini 文件需couchdb:couchdb 读写权限,否则哈希化后无法写回,导致“表面改完、实际未生效”的坑。
- 国内云镜像:阿里云、腾讯云、华为云市场镜像均把 CouchDB 装成 systemd 服务,unit 里 ProtectSystem=strict 会限制写/etc,建议把自定义配置放在 /opt/couchdb/etc/local.d/ 下,避免系统目录只读。
- 安全合规:国内等保 2.0 要求“账号最小化”,重置后需第一时间把 ini 文件权限改回 600,并在堡垒机留审计日志。
答案
- 登录宿主机,切换到 couchdb 用户(防止权限漂移):
sudo -iu couchdb bash - 确认本地可写配置路径,优先用 local.d 目录:
vim /opt/couchdb/etc/local.d/10-admins.ini - 写入新密码(明文即可):
[admins]
admin = NewPass@2025 - 保存退出后确保属主与权限:
chown couchdb:couchdb /opt/couchdb/etc/local.d/10-admins.ini
chmod 600 /opt/couchdb/etc/local.d/10-admins.ini - 触发哈希化并验证立即生效:
curl -u admin:NewPass@2025 http://127.0.0.1:5984/_session
返回 200 并含 {"userCtx":{"name":"admin",...}} 即成功;此时打开文件可见明文已被替换成 -pbkdf2-… 串。 - 若 CouchDB 以 systemd 运行且启用了 ProtectSystem,需把 local.d 目录挂成读写卷或临时执行 systemctl reload couchdb(reload 不重连客户端,无中断),但多数场景下第 5 步已足够。
拓展思考
- 多节点集群:ini 只影响本机,需逐台执行;若使用 Kubernetes ConfigMap,应把明文密码做成 Secret,滚动更新 Pod,让 Sidecar 触发 curl 完成哈希化,避免 Secret 长期留存明文。
- 与 LDAP 集成:国内金融客户常把 CouchDB 接入公司 AD,此时 [admins] 段仅留本地应急账号,生产密码遗忘应走 LDAP 解锁流程,而非改 ini,防止“双轨制”账号体系。
- 审计与回滚:在 /opt/couchdb/etc/local.d/ 里加时间戳文件,如 20250518-admin-reset.ini,保留历史记录;配合 git 或配置中心,能实现“一键回滚到旧密码哈希”。
- 安全加固:改密后立刻执行
curl -X PUT http://admin:NewPass@127.0.0.1:5984/_node/_local/_config/chttpd/require_valid_user -d '"true"'
关闭“匿名可读”漏洞,满足国内**网络安全法第 21 条“访问控制”**要求。