MongoDB 5.0副本集关闭用户认证保留集群认证问题排查
1. 关于clusterAuthMode=keyFile --keyFile参数作用的认知是否正确?
该认知不正确。
MongoDB 有明确的默认规则:只要启动时指定了--keyFile参数(即集群内部认证采用keyFile模式),客户端侧的访问控制(也就是--auth参数对应的能力)会被隐式自动启用,不需要额外添加--auth参数。keyFile相关配置不是仅作用于节点间认证的独立开关,它和客户端访问控制是强关联的默认联动逻辑。
2. 为什么配置keyFile参数后无法从集群外部无认证访问?
核心原因就是上述隐式启用认证的规则:你虽然手动删除了启动参数里的--auth,但只要保留了--keyFile配置,客户端访问认证就默认处于开启状态,所有未携带合法认证凭证的客户端请求,在执行需要权限的命令时都会被拒绝。
你遇到的pymongo.errors.OperationFailure: command usersInfo requires authentication报错,是pymongo驱动的副本集连接逻辑导致的:当连接字符串指定了replicaset参数时,驱动会自动执行副本集拓扑发现、服务端能力检测流程,过程中会调用usersInfo这类需要认证的命令,因为你没有传入账号密码,所以直接触发权限报错。
当你把keyFile相关参数全部删除后,mongod没有配置任何内部认证方式,客户端访问控制也不会被自动启用,所以无认证连接可以正常执行命令,这和你观察到的现象完全一致。
另外需要说明:你当前仅删除--auth参数的操作,永远无法实现「关闭客户端认证、保留节点间认证」的需求,因为默认联动逻辑不支持。要实现这个需求,必须显式指定关闭客户端授权,不能靠删除--auth参数实现,推荐使用mongod专属配置文件启动服务,不要把所有参数都堆在systemd的ExecStart行里,核心配置示例如下:
security: clusterAuthMode: keyFile keyFile: /etc/mongodb/keyFile authorization: disabled # 显式关闭客户端侧访问认证 replication: replSetName: mongodb net: bindIp: localhost,<your_ip> port: 27017
修改配置后重启所有mongod节点即可达到预期效果。
注意:关闭客户端侧认证会导致所有能连通数据库端口的用户都可以任意读写、删除数据,仅建议在隔离的纯测试环境使用,生产环境严禁这样配置。
3. 可靠的认证配置验证方式
不要直接用带副本集参数的远程连接作为唯一验证手段,驱动的自动逻辑会引入很多干扰项,建议按以下分层验证,结果最准确:
- 验证内部节点认证状态
登录任意一台副本集节点,本地直连mongod执行rs.status()命令,检查返回结果中所有成员的health字段为1、stateStr字段符合预期(PRIMARY/SECONDARY/ARBITER),没有节点处于不可达状态。
同时查看mongod运行日志(默认路径/var/log/mongodb/mongod.log),搜索关键字Authentication failed,如果没有副本节点之间的认证失败记录,说明内部节点间的keyFile认证工作正常。 - 验证客户端侧认证状态
本地直连单个mongod节点(不要加副本集参数:pymongo连接时加上directConnection=True参数,mongo shell加--directConnection参数),不传入任何账号密码,执行db.serverCmdLineOpts()查看运行时配置:- 如果
parsed.security.authorization字段值为disabled,说明客户端认证已关闭; - 不带认证信息执行
db.adminCommand({ping:1})、rs.status()等普通命令,如果可以正常返回结果,说明无认证访问规则生效。
- 如果
- 远程访问验证
本地验证通过后,再从外部机器分别测试直连单个节点、带副本集参数的连接方式,不带账号密码执行常规命令,确认可以正常返回结果即可。
内容的提问来源于stack exchange,提问作者Mia Altieri

