MongoDB 4.2 用戶管理

背景

最近在掃盲MongoDB 4.2 的相關知識點,順便記錄下平常的一些操做。包括:用戶管理、索引管理、引擎管理、副本集管理、分片管理等。本文對MongoDB的用戶管理進行說明,之前有針對MogoDB 3.0的用戶管理進行過說明:MongoDB 3.0 用戶建立javascript

本文MongoDB的配置文件模板:html

systemLog:
   verbosity: 0
   quiet: false
   traceAllExceptions: false
   syslogFacility: user
   path: /data/mongodb/logs/mongodb.log
   logAppend: true
   logRotate: rename
   destination: file
   timeStampFormat: iso8601-local
   component:
      accessControl:
         verbosity: 0
      command:
         verbosity: 0
      control:
         verbosity: 0
      ftdc:
         verbosity: 0
      geo:
         verbosity: 0
      index:
         verbosity: 0
      network:
         verbosity: 0
      query:
         verbosity: 0
      replication:
         verbosity: 0
         election:
            verbosity: 0
         heartbeats:
            verbosity: 0
         initialSync:
            verbosity: 0
         rollback:
            verbosity: 0
      sharding:
          verbosity: 0
      storage:
         verbosity: 0
         journal:
            verbosity: 0
         recovery:
            verbosity: 0
      transaction:
         verbosity: 0
      write:
         verbosity: 0

processManagement:
   fork: true
   pidFilePath: /data/mongodb/data/mongodb.pid
#   timeZoneInfo: <string>

net:
   port: 27017
   bindIp: 0.0.0.0
   maxIncomingConnections: 65536
   wireObjectCheck: true
   ipv6: false
   unixDomainSocket:
      enabled: true
      pathPrefix: /tmp
      filePermissions: 0700
   tls:
      mode: disabled
   compression:
      compressors: snappy,zstd,zlib
   serviceExecutor: synchronous

#security:
#   keyFile: <string>
#   clusterAuthMode: keyFile
#   authorization: enabled
#   transitionToAuth: false
#   javascriptEnabled: true
#   redactClientLogData: <boolean>
#   clusterIpSourceWhitelist:
#     - 127.0.0.1
#     - ::1

storage:
   dbPath: /data/mongodb/data/
   indexBuildRetry: true
   journal:
      enabled: true
      commitIntervalMs: 500
   directoryPerDB: true
   syncPeriodSecs: 60
   engine: wiredTiger
   wiredTiger:
      engineConfig:
#         cacheSizeGB: <number>
         journalCompressor: snappy
         directoryForIndexes: false
operationProfiling:
   # 指定應分析哪些操做,默認off:分析器已關閉,而且不收集任何數據;slowOp:收集比slowms的時間長的數據;all:收集全部操做的數據
   mode: slowOp
   slowOpThresholdMs: 100
   slowOpSampleRate: 1

replication:
   # 複製日誌(oplog)的最大大小(以M爲單位),僅適用於mongod。操做日誌一般是可用磁盤空間的5%,更改正在運行的副本集成員的操做日誌大小,請使用replSetResizeOplog管理命令。
   oplogSizeMB: 100
   # replSetName: <string>

#sharding:
   # 分片羣集中扮演的角色,可選值configsvr:配置服務器,端口27019開始;shardsvr:分片,端口27018開始;須要將實例部署爲副本集成員,使用replSetName設置並指定副本集的名稱,僅適用於mongod。
   # clusterRole: <string>
   # configDB: <string>
View Code

用戶管理

在一個新的實例上,建立的第一個用戶應該是具備管理其餘用戶權限的用戶管理員。在MongoDB部署上啓用訪問控制會強制執行身份驗證,要求用戶認證本身,用戶只能執行根據其角色肯定的操做。具體的用戶管理能夠看官方文檔或則MongoDB用戶建立,本文作下補充。
java

1,建立用戶:db.createUser(user, writeConcern)
mongodb

user:包含有關要建立的用戶的身份驗證和訪問信息。
writeConcern:可選,建立操做的寫關注級別。 writeConcern文檔的字段與getLastError命令的字段相同。

MongoDB4.2開始,可使用passwordPrompt()方法來提示輸入密碼,不須要在命令中指定密碼。但仍然能夠像使用早期版本的MongoDB同樣直接指定密碼。格式:數據庫

{
  user: "<name>",   -- 用戶名
  pwd: passwordPrompt(),    -- 提示輸入密碼,也能夠直接寫密碼
  customData: { <any information> },  -- 可選,可用於存儲與此特定用戶關聯的任何數據。 例如,這能夠是用戶的全名或員工ID。
  roles: [
    { role: "<role>", db: "<database>" } | "<role>",
    ...
  ],     -- 授予用戶的角色。 能夠指定一個空數組[]來建立沒有角色的用戶
  authenticationRestrictions: [
     {
       clientSource: ["<IP>" | "<CIDR range>", ...],
       serverAddress: ["<IP>" | "<CIDR range>", ...]
     },
     ...
  ],  -- 可選,服務器對建立的用戶強制執行的身份驗證限制,指定容許用戶鏈接到服務器或服務器能夠接受用戶的IP地址和CIDR(無類別域間路由)範圍的列表
  mechanisms: [ "<SCRAM-SHA-1|SCRAM-SHA-256>", ... ],  --可選,指定特定的SCRAM機制或用於建立SCRAM用戶憑據的機制
  passwordDigestor: "<server|client>"  --可選,指服務器仍是客戶端提取密碼。
}

其中在roles字段中,能夠指定內置角色用戶定義的角色:
數組

Built-In Roles(內置角色):
    1. 數據庫用戶角色:read、readWrite;
    2. 數據庫管理角色:dbAdmin、dbOwner、userAdmin;
    3. 集羣管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
    4. 備份恢復角色:backuprestore5. 全部數據庫角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    6. 超級用戶角色:root  
    // 這裏還有幾個角色間接或直接提供了系統超級用戶的訪問(dbOwner 、userAdmin、userAdminAnyDatabase)
    7. 內部角色:__system

具體權限服務器

read:容許用戶讀取指定數據庫
readWrite:容許用戶讀寫指定數據庫
dbAdmin:容許用戶在指定數據庫中執行管理函數,如索引建立、刪除,查看統計或訪問system.profile
userAdmin:容許用戶向system.users集合寫入,能夠找指定數據庫裏建立、刪除和管理用戶
clusterAdmin:只在admin數據庫中可用,賦予用戶全部分片和複製集相關函數的管理權限。
readAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的讀權限
readWriteAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的讀寫權限
userAdminAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的userAdmin權限
dbAdminAnyDatabase:只在admin數據庫中可用,賦予用戶全部數據庫的dbAdmin權限。
root:只在admin數據庫中可用。超級帳號,超級權限

建立用戶:app

db.createUser(
{
user:'dba',
pwd:passwordPrompt(),
roles:[{role:'root',db:'admin'}],
customData:{name:'運維帳號'},
authenticationRestrictions: [ {
        clientSource: ["192.168.163.134"],
        serverAddress: ["192.168.163.134"]
     } ]
}
)

說明建立一個用戶名爲dba的管理角色(root)的帳號,且備註爲運維帳號,並只能在IP爲192.168.163.134的主機上訪問。運維

use xxx
db.createUser(
{
user:'zjy',
pwd:passwordPrompt(),
roles:[{role:'readAnyDatabase',db:'admin'},
"readWrite"
],
customData:{name:'運維帳號'},
authenticationRestrictions: [ {
        clientSource: ["192.168.163.134"],
        serverAddress: ["192.168.163.134"]
     } ]
},
{ w: "majority" , wtimeout: 5000 }
)

說明建立一個用戶名爲zjy的帳號,對當前庫(xxx)有readWrite權限,對指定庫(admin)有readAnyDatabase權限;且備註爲運維帳號,並只能在IP爲192.168.163.134的主機上訪問。ide

關於帳號權限的一些說明能夠看MongoDB用戶建立

2,修改用戶密碼:db.changeUserPassword(username,password)

db.changeUserPassword('user','pwd')

3,查看指定用戶:db.getUser(username, args)

格式:

db.getUser( "<username>", {
   showCredentials: <Boolean>,
   showPrivileges: <Boolean>,
   showAuthenticationRestrictions: <Boolean>,
   filter: <document>
} )

其中"<username>"表示數據庫用戶,其餘的參數都是可選項:

  • showCredentials:查看用戶證書
  • showPrivileges:查看用戶權限
  • showAuthenticationRestrictions:查看用戶限制條件
> db.getUser('dba')
{
    "_id" : "admin.dba",
    "userId" : UUID("6a1c2217-0c5b-4aa6-a29b-de50ac1d84ae"),
    "user" : "dba",
    "db" : "admin",
    "customData" : {
        "name" : "運維帳號abc"
    },
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ],
    "mechanisms" : [
        "SCRAM-SHA-1",
        "SCRAM-SHA-256"
    ]
}

> db.getUser('dba',{showPrivileges:1})
...
...

4,查看當前庫的全部用戶:db.getUsers(<options>)

> db.getUsers() == show users [
    {
        "_id" : "xxx.zjy",
        "userId" : UUID("2ad9f4c9-e156-4e71-b8f9-3915beb322e8"),
        "user" : "zjy",
        "db" : "xxx",
        "customData" : {
            "name" : "運維帳號"
        },
        "roles" : [
            {
                "role" : "readAnyDatabase",
                "db" : "admin"
            },
            {
                "role" : "readWrite",
                "db" : "xxx"
            }
        ],
        "mechanisms" : [
            "SCRAM-SHA-1",
            "SCRAM-SHA-256"
        ]
    }
]

5,移除、刪除指定用戶:db.removeUser(username)db.dropUser(username, writeConcern)

> db.removeUser('zjy')
WARNING: db.removeUser has been deprecated, please use db.dropUser instead  --不推薦使用
true

> db.dropUser('accountAdmin01',{w: "majority", wtimeout: 5000})
true

若是在副本集上運行,則默認狀況下使用多數寫關注來執行db.dropUser()。

6,刪除當前庫全部用戶:db.dropAllUsers(writeConcern)

> db.dropAllUsers({w: "majority", wtimeout: 5000})
NumberLong(4)

7,更新指定用戶:db.updateUser(username, update, writeConcern)

格式:

db.updateUser(
   "<username>",
   {
     customData : { <any information> },
     roles : [
       { role: "<role>", db: "<database>" } | "<role>",
       ...
     ],
     pwd: passwordPrompt(),      // Or  "<cleartext password>"
     authenticationRestrictions: [
        {
          clientSource: ["<IP>" | "<CIDR range>", ...],
          serverAddress: ["<IP>", | "<CIDR range>", ...]
        },
        ...
     ],
     mechanisms: [ "<SCRAM-SHA-1|SCRAM-SHA-256>", ... ],
     passwordDigestor: "<server|client>"
   },
   writeConcern: { <write concern> }
)

上面各個參數的意思和createUser一致。

> db.updateUser(
... 'user123',
... {
... pwd:passwordPrompt(),
... roles:['read'],
... customData:{name:'運維帳號'},
... authenticationRestrictions: [ {
...         clientSource: ["192.168.163.134"],
...         serverAddress: ["192.168.163.134"]
...      } ]
... },
... { w: "majority" , wtimeout: 5000 }
... )

8,受權role給指定用戶:db.grantRolesToUser(username, roles, writeConcern)

格式:

db.grantRolesToUser( "<username>", [ <roles> ], { <writeConcern> } )
> show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-4178-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
        {
            "role" : "read",
            "db" : "products"
        }
    ],
    "customData" : {
        "name" : "運維帳號"
    },
    "mechanisms" : [
        "SCRAM-SHA-1",
        "SCRAM-SHA-256"
    ]
}
> db.grantRolesToUser('user123',['readWrite',{role:'read',db:'test'}])
> show users; { "_id" : "products.user123", "userId" : UUID("b71e3c9d-1e57-4178-b6f8-48445ee2ebfc"), "user" : "user123", "db" : "products", "roles" : [ { "role" : "readWrite", "db" : "products" }, { "role" : "read", "db" : "test" }, { "role" : "read", "db" : "products" } ], "customData" : { "name" : "運維帳號" }, "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] }

說明:在已有用戶(user123)的權限下,新增當前庫(products)的readWrite role和test庫的read role。

9,移除指定用戶的role:db.revokeRolesFromUser()

格式:

db.revokeRolesFromUser( "<username>", [ <roles> ], { <writeConcern> } )
> show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-4178-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "products"
        },
        {
            "role" : "read",
            "db" : "test"
        },
        {
            "role" : "read",
            "db" : "products"
        }
    ],
    "customData" : {
        "name" : "運維帳號"
    },
    "mechanisms" : [
        "SCRAM-SHA-1",
        "SCRAM-SHA-256"
    ]
}

> db.revokeRolesFrom
db.revokeRolesFromRole(  db.revokeRolesFromUser(

> db.revokeRolesFromUser('user123',[{role:'read',db:'test'},'readWrite'])

> show users; { "_id" : "products.user123", "userId" : UUID("b71e3c9d-1e57-4178-b6f8-48445ee2ebfc"), "user" : "user123", "db" : "products", "roles" : [ { "role" : "read", "db" : "products" } ], "customData" : { "name" : "運維帳號" }, "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] }

說明:移除已有用戶(user123)在當前庫(products)的readWrite role和test庫的read role權限。

10,用戶認證:db.auth(username,password)

> db.auth('dba','DBA')
1

以上說明的role都是內置角色,用戶自定義角色能夠看官方文檔說明。

角色管理

1,建立角色:db.createRole(role, writeConcern)

格式:

{
  role: "<name>",      --新角色的名稱
  privileges: [
     { resource: { <resource> }, actions: [ "<action>", ... ] },
     ...
  ],      --權限,由resource和actions組成。空數組表示無權限
  roles: [
     { role: "<role>", db: "<database>" } | "<role>",
      ...
  ],     --角色的數組,此角色從中繼承特權,空數組表示沒有繼承角色
  authenticationRestrictions: [
    {
      clientSource: ["<IP>" | "<CIDR range>", ...],
      serverAddress: ["<IP>" | "<CIDR range>", ...]
    },
    ...
  ]    --驗證限制
}

resource表示資源,包括database或collection也能夠是database和collection的組合:

{ db: <database>, collection: <collection> }

actions表示權限操做,"actions" 定義了"user"可以對 "resource document"執行的操做:

find、insert、remove、update

privilege表示權限,"privilege" 是一組"resource" 和 "actions" 的組,關於privileges的詳細信息見官方說明,裏面有各個命令的權限說明

>db.createRole(
   {role:"zhoujy", //角色名稱
       privileges: [ // 權限集
        {resource: //資源 
         {db:"xxx",     // 建立的zhoujy角色具備對xxx庫的操做權限,具體權限見actions
          collection:""   // xxx庫下對應的集合名 若是爲"" 表示全部集合
         },
          actions: [ "find", "insert", "remove","update" ]   //角色可進行的操做,注意這裏是一個數組
        }
                   ],
         roles: [{ role: "read", db: "admin" }] // 是否繼承其餘的角色,若是指定了其餘角色那麼新建立的角色自動繼承對應其餘角色的全部權限,該參數必須顯示指定
   },
  { w: "majority" , wtimeout: 5000 }
)

說明:建立了一個zhoujy的role,能夠像內置角色同樣來使用。

2,查看指定角色信息:db.getRole(rolename, args)

參數:

showBuiltinRoles:可選,在輸出中返回內置角色信息

showPrivileges:可選,在輸出中返回權限信息

> db.getRole('zhoujy')
{
    "role" : "zhoujy",
    "db" : "admin",
    "isBuiltin" : false,
    "roles" : [ ],
    "inheritedRoles" : [ ]
}

> db.getRole('zhoujy',{showPrivileges: true})
{
    "role" : "zhoujy",
    "db" : "admin",
    "isBuiltin" : false,
    "roles" : [ ],
    "inheritedRoles" : [ ],
    "privileges" : [
        {
            "resource" : {
                "db" : "xxx",
                "collection" : ""
            },
            "actions" : [
                "find",
                "insert",
                "remove",
                "update"
            ]
        }
    ],
    "inheritedPrivileges" : [
        {
            "resource" : {
                "db" : "xxx",
                "collection" : ""
            },
            "actions" : [
                "find",
                "insert",
                "remove",
                "update"
            ]
        }
    ]
}

3,查看當前數據庫中全部的角色信息:db.getRoles()

不帶參數運行,返回數據庫用戶定義角色的繼承信息,參數:

rolesInfo:1,返回全部用戶定義的角色信息

showPrivileges:true,返回全部用戶的權限信息

showBuiltinRoles:true,返回內置角色信息

>db.getRoles(
    {
      rolesInfo: 1,
      showPrivileges:true,
      showBuiltinRoles: true
    }
)

4,角色受權:db.grantPrivilegesToRole(rolename, privileges, writeConcern)

> db.grantPrivilegesToRole(
  "zhoujy",
  [
    {
      resource: { db: "products", collection: "" },
      actions: [ "insert","find"  ]
    }
  ],
  { w: "majority" }
)

說明:在已有的role下面,再追加權限。

5,角色權限回收:db.revokePrivilegesFromRole(rolename, privileges, writeConcern)

> db.revokePrivilegesFromRole(
  "zhoujy",
  [
    {
      resource: { db: "products", collection: "" },
      actions: [ "insert" ]
    }
  ],
  { w: "majority" }
)

說明:在已有的role下面,刪除權限。

6,角色繼承:db.grantRolesToRole(rolename, roles, writeConcern)

> db.grantRolesToRole(  
          "zhoujy",
           [ "zhoujy1","zhoujy2" ],
           { w: "majority" , wtimeout: 5000 }
                    )

說明:將 zhoujy一、zhoujy2 兩個角色(假設以前已經建立好)的權限授予zhoujy角色

7,繼承角色回收: db.revokeRolesFromRole(rolename, roles, writeConcern)

db.revokeRolesFromRole(
          "zhoujy" ,
          [ "zhoujy2" ]
                      ) 

說明:撤銷zhoujy角色從zhoujy2角色所繼承的全部權限

8,更新角色:db.updateRole(rolename, update, writeConcern)

格式:

    "<rolename>",  --角色名
    {
      privileges:
          [
            { resource: { <resource> }, actions: [ "<action>", ... ] },
            ...
          ],  --權限
      roles:
          [
            { role: "<role>", db: "<database>" } | "<role>",
            ...
          ],   --角色
      authenticationRestrictions:
          [
            {
              clientSource: ["<IP>" | "<CIDR range>", ...],
              serverAddress: ["<IP>", | "<CIDR range>", ...]
            },
            ...
          ]
    },    -- 限制
    { <writeConcern> } --寫關注
)
> db.updateRole(
   "zhoujy",
   {
      privileges: 
      [
        {
        resource:{db:"xxx", collection:""},
        actions: [ "find", "insert", "remove","update" ]
        }
       ],
      roles: []
   },
  { w: "majority" , wtimeout: 5000 }
)

9,刪除角色:db.dropRole(rolename, writeConcern)

> db.dropRole('myClusterwideAdmin', { w: "majority" })
true

10,刪除當前庫全部用戶自定義的角色:db.dropAllRoles(writeConcern)

db.dropAllRoles( { w: "majority" } )

到此,關於用戶管理的已經介紹完,更多的詳細信息能夠見官網說明,或能夠查閱MongoDB 權限控制系統簡介須要注意的是,須要開啓服務器參數中的security.authorization:true,纔會使用用戶驗證(db.auth())。

總結

本文大體介紹了MongoDB用戶管理的使用說明,後續根據須要會持續更新本文。關於用戶管理的更多說明能夠看官方文檔

 

參考文章:

MongoDB 3.0 用戶建立

MongoDB 權限控制系統簡介

相關文章
相關標籤/搜索