0

We need to have a user with minimal privileges that is only able to lock a mongo instance, using db.fsyncLock() and db.unlock(), to ensure we can take consistent snapshots of the disk images. I currently have the following role created:

{
    "role" : "local_lock",
    "db" : "admin",
    "isBuiltin" : false,
    "roles" : [ ],
    "inheritedRoles" : [ ],
    "privileges" : [
        {
            "resource" : {
                "cluster" : true
            },
            "actions" : [
                "logRotate",
                "resync",
                "unlock"
            ]
        }
    ],
    "inheritedPrivileges" : [
        {
            "resource" : {
                "cluster" : true
            },
            "actions" : [
                "logRotate",
                "resync",
                "unlock"
            ]
        }
    ]
}

But when I use this user to attempt a lock I receive the following:

> db.fsyncLock()
{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { fsync: 1.0, lock: true }",
    "code" : 13,
    "codeName" : "Unauthorized"
}
>

What other permissions are required? Mongo versions as follows:

MongoDB shell version v3.4.7
MongoDB server version: 3.4.7
ModulusJoe
  • 1,416
  • 10
  • 17

3 Answers3

1

I believe I was making a typo assigning the role to the user, the following does indeed work:

[
    {
        "role" : "local_lock",
        "db" : "admin",
        "isBuiltin" : false,
        "roles" : [ ],
        "inheritedRoles" : [ ],
        "privileges" : [
            {
                "resource" : {
                    "cluster" : true
                },
                "actions" : [
                    "fsync",
                    "unlock"
                ]
            }
        ],
        "inheritedPrivileges" : [
            {
                "resource" : {
                    "cluster" : true
                },
                "actions" : [
                    "fsync",
                    "unlock"
                ]
            }
        ]
    }
]
ModulusJoe
  • 1,416
  • 10
  • 17
0

Well, limiting user to this tight may not be a good idea and potentially he/she may not perform this action at all.

However, try granting fsync and unlock permissions to account. See fsync and unlock actions in documentation.

Saleem
  • 8,728
  • 2
  • 20
  • 34
  • This is a user being assumed by an automated process, hence the requirement for the user to be locked as tightly as possible. Looks like I had an ID10T error somewhere :/ – ModulusJoe Aug 21 '17 at 13:21
0

That's how I done it for sharded cluster (mongodb v3.6). I want to backup from a separate replica in each sharded replicaset. For that, I login to the replica, connect to local mongod, lock database write and start doing filecopy. After that, I unblock database back. So:

  1. Create a new role for backup with additional permissions at a primary node for each sharded replicaset:
shard_01_r2:PRIMARY> db.createRole(
{
  "role": "local_backup_with_locks",
  "roles": [
    "backup"
  ],
  "privileges": [
    {
      "resource": {
        "cluster": true
      },
      "actions": [
        "fsync",
        "unlock",
        "enableProfiler",
        "replSetGetStatus"
      ]
    }
  ],
  "authenticationRestrictions": [
    {
      "clientSource": [
        "127.0.0.1",
        "::1"
      ]
    }
  ]
}
)
  1. Create a backup user here so that each shard could be separately manage:
shard_01_r2:PRIMARY> db.createUser(
    {
    user: "dtci_backup",
    pwd: "XXX",
    roles: [ { role: "local_backup_with_locks", db: "admin" } ]
    }
)
  1. Create this user "globally" via mongos, for backup config servers. As there is no need to add fsynclock/unlock here, we could assign backup role only:
mongos> db.createUser(
    {
    user: "dtci_backup",
    pwd: "XXX",
    roles: [ { role: "backup", db: "admin" } ]
    }
)

That's it! Now you're able to connect locally for any replica in each shard and make backup from it without influence onto other replicas/cluster.