只读用户无法执行db.serverstatus()是权限设计使然;需在admin库授予clustermonitor角色(如新建monitor_user账号),该角色专为只读监控设计且符合最小权限原则,避免使用hostmanager或clusteradmin等高危角色。

只读用户无法执行 db.serverStatus() 是权限设计使然
默认 read 角色不包含任何服务器级监控命令权限,哪怕只是看状态。这不是 bug,是 MongoDB 的权限分层逻辑:数据库角色(如 read)只覆盖本库的集合读取操作,serverStatus、top、collStats 等命令属于“管理动作”,必须显式授权。
用 clusterMonitor 角色补充监控能力
该角色专为只读监控场景设计,但注意它**只能在 admin 数据库中授予**,且自带对 local 和 admin 库部分系统集合的只读访问(如 local.oplog.rs、admin.system.version)。
- 必须先切换到
admin数据库再执行授权:use admin - 不能直接给已有只读用户追加
clusterMonitor—— 该角色要求用户本身存在于admin库,所以推荐新建一个专用监控账号:
use admin
db.createUser({
user: "monitor_user",
pwd: "strong_password",
roles: [
{ role: "read", db: "target_db" },
{ role: "clusterMonitor", db: "admin" }
]
})
这样既能查 target_db 的业务数据,也能运行 db.serverStatus()、db.currentOp()、db.top() 等命令。
避免误用 hostManager 或 clusterAdmin
这两个角色权限过重:hostManager 允许关闭实例、修改日志级别;clusterAdmin 可重配复制集、踢出节点。生产环境给监控账号授这些角色等于埋雷。
-
clusterMonitor是唯一安全、轻量、符合最小权限原则的选择 - 如果只需要查某个库的慢查询或索引统计,
db.collection.stats()需要dbAdmin权限,此时应单独为该库授予{ role: "dbAdmin", db: "target_db" },而非扩大监控范围 - 所有监控类命令都依赖
auth模式开启,未启用认证时权限机制不生效
验证权限是否生效的关键点
别只测 find() 成功就认为 OK —— 监控权限容易被忽略的失效点有三个:
- 连接时必须指定
--authenticationDatabase admin,否则即使密码正确也会因认证库错位失败 -
db.serverStatus()返回结果里若缺少connections或mem字段,说明权限不足(不是命令不存在) - 在非
admin库下执行db.runCommand({ serverStatus: 1 })会报not authorized on admin to execute command,这是正常现象,必须切到admin库再运行
真正难处理的是权限组合后的隐性冲突,比如同时授了 readAnyDatabase 和 clusterMonitor,前者会覆盖后者对 local 库的访问控制,导致某些监控命令行为异常 —— 这种边界情况几乎不会在文档里写明,只能靠实测验证。











