最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】MongoDB开启访问控制后currentOp出错:not authorized on admin to execute command

MongoDB crifan 9056浏览 0评论

折腾:

【已解决】给MongoDB限制IP访问

期间,另外,继续去研究:

<code>[root@naturling-general-01 ~]# mongo
MongoDB shell version: 3.2.19
connecting to: test
&gt; db.currentOp().inprog
&gt; db.currentOp(true).inprog
&gt; use gridfs
switched to db gridfs
&gt; db.currentOp(true).inprog
&gt; db.currentOp().inprog
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; use admin
switched to db admin
&gt; db.auth("admin", "pwd")
1
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; use gridfs
switched to db gridfs
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; 
</code>

->发现了是:

此处的用户,没有权限执行currentOp操作

看来是需要:

把访问控制关了

然后去添加一个,超级用户

确保拥有所有的权限

至少确保有执行

db.currentOp

的权限才行。

先去搞清楚:

currentOp

这个权限,是否有对应的role

Built-In Roles — MongoDB Manual 3.6

中没有找到

mongo currentOp not authorized

MongoDB – admin user not authorized – Stack Overflow

应该直接把:userAdminAnyDatabase改为root,算最简单粗暴的办法了

https://docs.mongodb.com/manual/reference/built-in-roles/#root

“root¶

Provides access to the operations and all the resources of the readWriteAnyDatabase, dbAdminAnyDatabase, userAdminAnyDatabase, clusterAdmin roles, restore, and backuproles combined.

Changed in version 3.4: The root role includes privileges from the backup role.

Changed in version 3.0.7: The root has validate action on system. collections. Previously, rootdoes not include any access to collections that begin with the system. prefix other than system.indexes and system.namespaces.

The root role includes privileges from the restore role.”

总之就是:

root权限,有用任何权限。

换句话说:

对于一个数据库来说,比如此处的gridfs,从dbOwner换成root,则有用超级的权限,最高的权限

mongodb之用户管理与系统管理常用命令-追马-51CTO博客

中看到了currentOp:

“db.currentOp() displays currently executing operations in the db”

是通过:

db.help()

显示出来的。

去试试:

<code>&gt; use gridfs
switched to db gridfs
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; db.auth("gridfs", "pwd")
1
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; db.help()
DB methods:
        db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [ just calls db.runCommand(...) ]
        db.auth(username, password)
        db.cloneDatabase(fromhost)
db.commandHelp(name) returns the help for the command
        db.copyDatabase(fromdb, todb, fromhost)
        db.createCollection(name, { size : ..., capped : ..., max : ... } )
        db.createUser(userDocument)
        db.currentOp() displays currently executing operations in the db
        db.dropDatabase()
        db.eval() - deprecated
        db.fsyncLock() flush data to disk and lock server for backups
        db.fsyncUnlock() unlocks server following a db.fsyncLock()
        db.getCollection(cname) same as db['cname'] or db.cname
        db.getCollectionInfos([filter]) - returns a list that contains the names and options of the db's collections
        db.getCollectionNames()
        db.getLastError() - just returns the err msg string
        db.getLastErrorObj() - return full status object
        db.getLogComponents()
        db.getMongo() get the server connection object
        db.getMongo().setSlaveOk() allow queries on a replication slave server
        db.getName()
        db.getPrevError()
        db.getProfilingLevel() - deprecated
        db.getProfilingStatus() - returns if profiling is on and slow threshold
        db.getReplicationInfo()
        db.getSiblingDB(name) get the db at the same server as this one
        db.getWriteConcern() - returns the write concern used for any operations on this db, inherited from server object if set
        db.hostInfo() get details about the server's host
        db.isMaster() check replica primary status
        db.killOp(opid) kills the current operation in the db
        db.listCommands() lists all the db commands
        db.loadServerScripts() loads all the scripts in db.system.js
        db.logout()
        db.printCollectionStats()
        db.printReplicationInfo()
        db.printShardingStatus()
        db.printSlaveReplicationInfo()
        db.dropUser(username)
        db.repairDatabase()
        db.resetError()
        db.runCommand(cmdObj) run a database command.  if cmdObj is a string, turns it into { cmdObj : 1 }
        db.serverStatus()
        db.setLogLevel(level,&lt;component&gt;)
        db.setProfilingLevel(level,&lt;slowms&gt;) 0=off 1=slow 2=all
        db.setWriteConcern( &lt;write concern doc&gt; ) - sets the write concern for writes to the db
        db.unsetWriteConcern( &lt;write concern doc&gt; ) - unsets the write concern for writes to the db
        db.setVerboseShell(flag) display extra information in shell output
        db.shutdownServer()
        db.stats()
        db.version() current version of the server
&gt; db.stats()
{
        "db" : "gridfs",
        "collections" : 2,
        "objects" : 21612,
        "avgObjSize" : 238683.47043309273,
        "dataSize" : 5158427163,
        "storageSize" : 4873072640,
        "numExtents" : 0,
        "indexes" : 4,
        "indexSize" : 626688,
        "ok" : 1
}
&gt; db.version()
3.2.19
&gt; db.currentOp()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0 }",
        "code" : 13
}
&gt; db.serverStatus()
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { serverStatus: 1.0 }",
        "code" : 13
}
&gt; 
</code>

看来

此处虽然已经是gridfs这个数据库的dbOwner了,但是还是有其他一些命令,不能指定的,比如:

db.currentOp()

db.serverStatus()

等等。

MongoDB 基础(六)安全性(权限操作) – CSDN博客

关于角色,参考官方文档提取总结如下:

角色分类
角色
权限及角色
(本文大小写可能有些变化,使用时请参考官方文档)
Database User Roles
read
CollStats,dbHash,dbStats,find,killCursors,listIndexes,listCollections
readWrite
CollStats,ConvertToCapped,CreateCollection,DbHash,DbStats,
DropCollection,CreateIndex,DropIndex,Emptycapped,Find,
Insert,KillCursors,ListIndexes,ListCollections,Remove,
RenameCollectionSameDB,update
Database Administration Roles
dbAdmin
collStats,dbHash,dbStats,find,killCursors,listIndexes,listCollections,
dropCollection 和 createCollection 在 system.profile 
dbOwner
角色:readWrite, dbAdmin,userAdmin
userAdmin
ChangeCustomData,ChangePassword,CreateRole,CreateUser,
DropRole,DropUser,GrantRole,RevokeRole,ViewRole,viewUser
Cluster Administration Roles
clusterAdmin
角色:clusterManager, clusterMonitor, hostManager
clusterManager
AddShard,ApplicationMessage,CleanupOrphaned,FlushRouterConfig,
ListShards,RemoveShard,ReplSetConfigure,ReplSetGetStatus,
ReplSetStateChange,Resync,
 
EnableSharding,MoveChunk,SplitChunk,splitVector
clusterMonitor
connPoolStats,cursorInfo,getCmdLineOpts,getLog,getParameter,
getShardMap,hostInfo,inprog,listDatabases,listShards,netstat,
replSetGetStatus,serverStatus,shardingState,top
 
collStats,dbStats,getShardVersion
hostManager
applicationMessage,closeAllDatabases,connPoolSync,cpuProfiler,
diagLogging,flushRouterConfig,fsync,invalidateUserCache,killop,
logRotate,resync,setParameter,shutdown,touch,unlock
Backup and Restoration Roles
backup
提供在admin数据库mms.backup文档中insert,update权限
列出所有数据库:listDatabases
列出所有集合索引:listIndexes
 
对以下提供查询操作:find
*非系统集合
*系统集合:system.indexes, system.namespaces, system.js
*集合:admin.system.users 和 admin.system.roles
restore
非系统集合、system.js,admin.system.users 和 admin.system.roles 及2.6 版本的system.users提供以下权限:
collMod,createCollection,createIndex,dropCollection,insert
 
列出所有数据库:listDatabases
system.users :find,remove,update
All-Database Roles
readAnyDatabase
提供所有数据库中只读权限:read
列出集群所有数据库:listDatabases
readWriteAnyDatabase
提供所有数据库读写权限:readWrite
列出集群所有数据库:listDatabases
userAdminAnyDatabase
提供所有用户数据管理权限:userAdmin
Cluster:authSchemaUpgrade,invalidateUserCache,listDatabases
admin.system.users和admin.system.roles:
collStats,dbHash,dbStats,find,killCursors,planCacheRead
createIndex,dropIndex
dbAdminAnyDatabase
提供所有数据库管理员权限:dbAdmin
列出集群所有数据库:listDatabases
Superuser Roles
root
角色:dbOwner,userAdmin,userAdminAnyDatabase
readWriteAnyDatabase, dbAdminAnyDatabase,
userAdminAnyDatabase,clusterAdmin
Internal Role
__system
集群中对任何数据库采取任何操作

尽量还是想要去搞清楚:

currentOp这个操作

到底属于哪个(系统内置)的role?

还是系统内置的role中,并没有包含currentOp?

mongo currentOp belong which role

$currentOp (aggregation) — MongoDB Manual 3.6

$currentOp (aggregation)是3.6版本才新增的

-》以为是db.currentOp()是3.6新增的

-〉我此处服务器端3.2版本中没有此命令呢

db.currentOp() — MongoDB Manual 3.6

才发现是:db.currentOp()早就有了

-》此处服务器端3.2(3.2.19)的mongo中db.help()就列出来了

“db.currentOp and the database profiler report the same basic diagnostic information for all CRUD operations, including the following:

* aggregate”

上面指的是:

db.currentOp的aggregate,是3.6才有的

看到了解释了:

“Access Control

On systems running with authorization, the user must have access that includes the inprog privilege action.”

必须有:inprog才可以有权限执行此命令

但是又说了:

“Changed in version 3.2.9: On mongod instances, users can run db.currentOp( { “$ownOps”: true} ) to view their own operations even without the inprog privilege action.”

我此处的服务器端mongo是3.2.19,大于3.2.9,按照道理,应该是:

不需要inprog,就可以直接运行:

db.currentOp()

才对啊。

难道是,没有inprog权限时,只有运行:

db.currentOp( { “$ownOps”: true} )

才可以?

去试试,果然是可以的:

<code>&gt; db.currentOp( { "$ownOps": true} ) 
{
        "inprog" : [
                {
                        "desc" : "conn12",
                        "threadId" : "139682983704320",
                        "connectionId" : 12,
                        "client" : "127.0.0.1:36136",
                        "active" : true,
                        "opid" : 144849,
                        "secs_running" : 0,
                        "microsecs_running" : NumberLong(36),
                        "op" : "command",
                        "ns" : "admin.$cmd",
                        "query" : {
                                "currentOp" : 1,
                                "$ownOps" : true
                        },
                        "numYields" : 0,
                        "locks" : {

                        },
                        "waitingForLock" : false,
                        "lockStats" : {

                        }
                }
        ],
        "ok" : 1
}
</code>

说明:

此处的:

“client” : “127.0.0.1:36136”,

就表示:

当前,连接到自己的数据库,此处的gridfs,有一个client在连接

对应的:

  • IP:127.0.0.1

    • 而127.0.0.1就表示是自己本机中的client

      • 就是此处正在(服务器端本地)使用的mongo shell

  • 端口:36136

而:

db.currentOp(true)

等价于:

db.currentOp({ “$all”: true })

是,不可以(在没有inprog权限时)运行的:

<code>&gt; db.currentOp(true)
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0, $all: true }",
        "code" : 13
}
&gt; db.currentOp({ "$all": true })
{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { currentOp: 1.0, $all: true }",
        "code" : 13
}
</code>

所以接着去看看:

inprog Privilege Actions — MongoDB Manual 3.6

inprog属于Deployment Management Actions方面的权限

注:killop也同属于Deployment Management Actions方面的权限

而全部的完整的权限分类是:

* Query and Write Actions

* Database Management Actions

* Deployment Management Actions

* Replication Actions

* Sharding Actions

* Server Administration Actions

* Session Actions

* Diagnostic Actions

* Internal Actions

所以清楚了:

currentOp这个命令,运行之前,要确保有inprog的这个权限:

inprog Privilege Actions — MongoDB Manual 3.6

才可以。

特例:

在3.2.9之后,没有inprog权限,也可以运行:

<code>db.currentOp( { "$ownOps": true} )
</code>

注意:

db.currentOp(true)

== db.currentOp({ “$all”: true })

不等于 db.currentOp( { “$ownOps”: true} )

而想要获得inprog这个权限

可以参考:

Manage Users and Roles — MongoDB Manual 3.6

https://docs.mongodb.com/manual/tutorial/manage-users-and-roles/#create-role-to-manage-ops

创建manageOpRole这个role:

manageOpRole = db.currentOp() + db.killOp()

但是显然还麻烦(虽然更安全)

所以,还是去:

把数据库grifs的用户权限,设置为root(而不是dbOwner)

-》这样就是超级用户权限,拥有了所有的,针对于gridfs的权限了

参考:

【已解决】给MongoDB数据库新建用户和权限

去删除掉gridfs的权限

然后加上用户,带root的权限

结果没有权限删掉出用户:

<code>[root@naturling-general-01 ~]# mongo
MongoDB shell version: 3.2.19
connecting to: test
&gt; use gridfs
switched to db gridfs
&gt; db.runCommand({dropAllUsersFromDatabase: 1})
{
        "ok" : 0,
        "errmsg" : "not authorized on gridfs to execute command { dropAllUsersFromDatabase: 1.0 }",
        "code" : 13
}
</code>

所以只能先去,去除权限控制:

<code>vi /etc/mongod.conf

</code>

     33 #security:

     34 #  authorization: ‘enabled’

然后删掉用户:

<code>&gt; use admin
switched to db admin
&gt; db.runCommand({dropAllUsersFromDatabase: 1})
{ "n" : 1, "ok" : 1 }
&gt; show users
&gt; use gridfs
switched to db gridfs
&gt; db.runCommand({dropAllUsersFromDatabase: 1})
{ "n" : 1, "ok" : 1 }
&gt; show users
&gt; 
</code>

然后重新创建之前的用户,都设置为对应数据库的root,即可。

<code>&gt; use admin
switched to db admin
&gt; db.createUser({
...     user: "admin",
...     pwd: "pwd",
...     roles: [ { role: "root", db: "admin" } ]
... })
Successfully added user: {
        "user" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
&gt; show users
{
        "_id" : "admin.admin",
        "user" : "admin",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
</code>

但是给,普通的数据库,gridfs去创建root时,出错:

【已解决】mongo中给普通数据库gridfs创建root的角色失败:Error couldn’t add user No role named root@gridfs

【总结】

至此,已经清楚了:

之前开启了权限访问控制后,对于已经是gridfs数据库的dbOwner的grdifs用户去:

db.currentOp()

结果:

not authorized on admin to execute command { currentOp: 1.0 }”

原因是:

gridfs这个用户,并没有inprog权限

那怎么才能有inprog权限呢?

只有去admin数据库中,创建一个,带有inprog权限的用户,

然后使用该用户登录后,切换到gridfs数据库中,再去:

db.currentOp()

才可以。

而:

root = readWriteAnyDatabase + dbAdminAnyDatabase + userAdminAnyDatabase + clusterAdmin + restore + backup

-》而其中的:clusterAdmin = clusterManager + clusterMonitor +hostManager + dropDatabase

-》而其中的:clusterMonitor = … + inprog + … + serverStatus + …

所以对于inprog权限,系统内置的角色中,已经有clusterMonitor包含了该权限 

-》或 clusterAdmin(包含了clusterMonitor)

-〉或root (包含了clusterAdmin)

注意:上述几个角色,都只能针对于admin数据库的

-》换句话说:去其他数据库,比如此处的gridfs,是没法使用赋值这些角色的

所以可以去admin数据库中创建对应的带了这些权限的用户,比如:

<code>&gt; use admin
switched to db admin
&gt; db.runCommand({dropAllUsersFromDatabase: 1})
{ "n" : 1, "ok" : 1 }
&gt; db.createUser({
...     user: "root",
...     pwd: "pwd",
...     roles: [ { role: "root", db: "admin" } ]
... })
Successfully added user: {
        "user" : "root",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
&gt; show users
{
        "_id" : "admin.root",
        "user" : "root",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
</code>

然后就可以:

切换到对应数据库

<code>use gridfs
</code>

然后运行命令,查看对应的连接信息了:

<code>db.currentOp()
db.currentOp(true)
db.currentOp({ "$all": true })
</code>

转载请注明:在路上 » 【已解决】MongoDB开启访问控制后currentOp出错:not authorized on admin to execute command

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
84 queries in 0.201 seconds, using 22.18MB memory