mongodb 5.0+副本集认证失败主因是mongod未启动:keyfile权限必须为400(-r--------),600或644均被拒;selinux/apparmor常静默拦截;auth与keyfile不可同时启用,须先初始化副本集再启用authorization。

副本集部署时认证报错,八成不是密码错了,而是 mongod 根本没起来——keyfile 权限不对、SELinux 拦了、或 auth 和 keyFile 顺序冲突,这三类问题占实际故障的 90% 以上。
keyfile 权限必须是 400,不是 600 也不是 644
MongoDB 5.0+ 启动时会严格校验 keyfile 权限:只接受 -r--------(即 chmod 400)。任何其他权限都会直接退出,日志里只写 Keyfile permissions are too open,不会提示你该改哪。
-
chmod 600 /path/to/keyfile→ 失败,MongoDB 认为“too open” -
chmod 644或chmod 755→ 必然失败,group/other 有读或执行位 - 用
touch创建后没改权限 → 默认 644,直接中招 - 正确命令只有一条:
chmod 400 /path/to/keyfile,不加-R,不犹豫
mongod 用户必须能读 keyfile,且父目录要有 x 权限
权限设成 -r-------- 还报 Permission denied?说明 mongod 进程用户(通常是 mongod 或 mongodb)根本读不到文件,常见于路径中间某级目录没开放进入权限。
- 查服务用户:
ps aux | grep mongod,看 USER 列 - 模拟读取:
sudo -u mongod cat /path/to/keyfile,失败就说明链路断了 - 检查每一级父目录:
sudo -u mongod ls -ld /path/to,确保都有x(执行位) - 别放
/home/xxx/或/tmp/下——这些路径常被 SELinux 或系统策略默认限制
auth=true 和 keyFile 不能同时开在 rs.initiate 前
很多教程让一上来就配好 auth: true 和 keyFile,结果 rs.initiate() 直接报 Unauthorized。这不是 bug,是设计逻辑:副本集初始化阶段,节点间通信依赖 keyfile,但 auth 会强制所有操作先认证,而此时用户还没建、shell 也没登录,形成死锁。
- 正确做法:先注释掉配置里的
security.authorization和security.keyFile - 启动所有节点,用
mongo连上 primary,执行rs.initiate(cfg) - 等状态变成 PRIMARY 后,再停机,补上
keyFile,最后才开启authorization: true - 重启前确认所有节点的
replSet名称和keyFile路径完全一致
连接时必须指定 authSource=admin,且密码不含未编码特殊字符
即使 keyfile 和 auth 都跑通了,客户端连不上仍大概率卡在 authSource 配置。MongoDB 默认把 root 用户建在 admin 库,但连接字符串若没显式声明 ?authSource=admin,驱动会默认去目标库找用户,自然失败。
- 错误写法:
mongodb://root:pass@host:27017/mydb→ 认证数据库默认为mydb,找不到用户 - 正确写法:
mongodb://root:pass@host:27017/mydb?authSource=admin - 密码含
@、:、/等字符 → 必须 URL 编码,比如pass@word要写成pass%40word - Java/Python/Node.js 客户端都要显式传
authSource参数,不能依赖默认值
真正麻烦的从来不是“怎么配”,而是“哪一层拦住了”——keyfile 权限、SELinux 上下文、auth 启用时机、authSource 指定,四层嵌套,漏一个就卡死。调的时候别猜,用 sudo -u mongod cat 和 setenforce 0 逐层验证,比翻日志快十倍。











