上一篇博客主要聊了下mongodb的分片機制以及分片集群的搭建,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13958295.html;今天我們來了解下mongodb的訪問控制;
什么是訪問控制?
簡單講訪問控制就是指,哪些用戶可以訪問哪些資源,對資源有哪些操作(權限);在mongodb中我們把數據庫、或者集合叫做資源;也就說訪問控制是用來限制某些用戶對數據庫或集合的操作;我們在mysql數據庫中,我們通過給賬號授權的方式達到控制哪些用戶可以從哪些主機訪問數據庫,對數據庫有哪些操作;其中賬號由用戶名稱和主機地址構成;在mongodb中采用的不是用戶+主機地址的方式,而是通過給用戶賦予一個或多個角色,這個角色或多個角色的所有權限就是這個用戶擁有的權限;默認情況mongodb是沒有啟用訪問控制的,所以只要能夠連接上mongodb實例,我們就可以在其上做任何操作,在某種程度上,這是一種極為不安全的方式,為了杜絕這種不安全的訪問方式,我們需要對mongodb進行訪問控制;
mongodb中的角色權限說明
mongodb默認內置了一些角色,不同的角色擁有不同的權限,如下圖
查看mongodb中某個數據庫所有內置角色
> db.runCommand({rolesInfo:1,showBuiltinRoles:true}) { "roles" : [ { "role" : "dbAdmin", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] }, { "role" : "dbOwner", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] }, { "role" : "enableSharding", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] }, { "role" : "read", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] }, { "role" : "readWrite", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] }, { "role" : "userAdmin", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } ], "ok" : 1 } >
提示:以上是mongodb中test庫的默認角色;如果要查看其它庫,我們需要切換到其他庫,然后運行上述命令查看即可;
查詢當前數據中的某個角色
> db test > db.runCommand({rolesInfo:"userAdmin"}) { "roles" : [ { "role" : "userAdmin", "db" : "test", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } ], "ok" : 1 } >
查詢其他數據庫中指定的角色權限
> db.runCommand({rolesInfo:{role:"userAdmin",db:"config"}}) { "roles" : [ { "role" : "userAdmin", "db" : "config", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } ], "ok" : 1 } > db.runCommand({rolesInfo:{role:"root",db:"config"}}) { "roles" : [ ], "ok" : 1 } > db.runCommand({rolesInfo:{role:"root",db:"admin"}}) { "roles" : [ { "role" : "root", "db" : "admin", "isBuiltin" : true, "roles" : [ ], "inheritedRoles" : [ ] } ], "ok" : 1 } >
創建一個用戶名為tom,其角色為超級管理員角色root
> use admin switched to db admin > db.createUser({user:"tom",pwd:"admin123.com",roles:[{"role":"root","db":"admin"}]}) Successfully added user: { "user" : "tom", "roles" : [ { "role" : "root", "db" : "admin" } ] } >
查看當前庫用戶列表
> db admin > db.getUsers() [ { "_id" : "admin.tom", "userId" : UUID("67bf434a-49fc-4ed5-9e9b-23c443a2fc93"), "user" : "tom", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } ] >
創建數據庫管理員用戶
> db.createUser({user:"jerry",pwd:"admin123.com",roles:["userAdminAnyDatabase"]}) Successfully added user: { "user" : "jerry", "roles" : [ "userAdminAnyDatabase" ] } > db.getUsers() [ { "_id" : "admin.jerry", "userId" : UUID("5d0b77f2-b7f1-40cd-8149-f08b2e1e6a80"), "user" : "jerry", "db" : "admin", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] }, { "_id" : "admin.tom", "userId" : UUID("67bf434a-49fc-4ed5-9e9b-23c443a2fc93"), "user" : "tom", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } ] >
提示:如果創建用戶時,未指定db,則表示當前該用戶對當前所在db生效;
刪除用戶
> db.dropUser("jerry") true > db.getUsers() [ { "_id" : "admin.tom", "userId" : UUID("67bf434a-49fc-4ed5-9e9b-23c443a2fc93"), "user" : "tom", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } ] >
提示:刪除用戶,需切換到對應數據下,指定對應用戶名稱即可;在mongodb中用戶是對應數據庫的,一個用戶可以對應一個或多個數據庫,在指定數據庫刪除用戶,就表示刪除指定用戶對指定數據庫的訪問權限;
修改指定用戶的密碼
> db admin > db.changeUserPassword("tom","123456") >
提示:修改用戶密碼,第一個是指定用戶的名稱,第二個是指定新密碼;
驗證用戶名和密碼
給錯誤的密碼
> db admin > db.auth("tom","admin") Error: Authentication failed. 0 >
給正確的密碼
> db admin > db.auth("tom","123456") 1 >
創建一個普通用戶
> use testdb switched to db testdb > db.createUser({user:"test",pwd:"admin",roles:[{role:"readWrite",db:"testdb"}]}) Successfully added user: { "user" : "test", "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] } > db.getUsers() [ { "_id" : "testdb.test", "userId" : UUID("95ecb34c-46f4-44fa-8948-4f0875499d8e"), "user" : "test", "db" : "testdb", "roles" : [ { "role" : "readWrite", "db" : "testdb" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } ] >
提示:以上就創建了一個名為test的用戶,它可對testdb這個庫下的所有collection做讀寫操作;
創建一個多角色的用戶
> db testdb > db.createUser( ... { ... user:"jerry1", ... pwd:"admin123.com", ... roles:[ ... {role:"clusterAdmin",db:"admin"}, ... {role:"readWrite",db:"testdb"}, ... {role:"read",db:"testdb1"} ... ] ... }) Successfully added user: { "user" : "jerry1", "roles" : [ { "role" : "clusterAdmin", "db" : "admin" }, { "role" : "readWrite", "db" : "testdb" }, { "role" : "read", "db" : "testdb1" } ] } > db.getUsers() [ { "_id" : "testdb.jerry1", "userId" : UUID("43d66bf8-1e3a-4c14-ad73-5961b5a7660f"), "user" : "jerry1", "db" : "testdb", "roles" : [ { "role" : "clusterAdmin", "db" : "admin" }, { "role" : "readWrite", "db" : "testdb" }, { "role" : "read", "db" : "testdb1" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] }, { "_id" : "testdb.test", "userId" : UUID("95ecb34c-46f4-44fa-8948-4f0875499d8e"), "user" : "test", "db" : "testdb", "roles" : [ { "role" : "readWrite", "db" : "testdb" } ], "mechanisms" : [ "SCRAM-SHA-1", "SCRAM-SHA-256" ] } ] >
提示:在mongodb中一個用戶可以授權擁有多個角色權限;
開啟mongodb服務端訪問控制配置
重啟服務
[root@node12 ~]# systemctl restart mongod.service [root@node12 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 *:27017 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node12 ~]#
測試:現在連接mongodb,看看會發生什么?
[root@node12 ~]# mongo MongoDB shell version v4.4.1 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("68fa2f83-64a4-42c2-8d64-9ee73a77e883") } MongoDB server version: 4.4.1 > show dbs > db test > show tables Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus >
提示:現在我們直接連接mongodb是可以正常連接,但是我們沒法查看數據列表以及collections了;這個時候我們就需要進行用戶認證了;
認證用戶
> db test > db.auth("test","admin") Error: Authentication failed. 0 > use testdb switched to db testdb > db.auth("test","admin") 1 > show dbs > show collections >
提示:認證用戶必須切換到對應的數據庫下做認證;我這里test用戶只能對testdb庫下的所有collection進行讀寫,所以認證以后,我們在使用 show dbs命令就看不到系統admin和config庫了;除了上述連接數據庫以后使用db.auth()做用戶認證,我們也可直接在連接數據庫時指定用戶名和密碼,如下
[root@node12 ~]# mongo -utest -padmin testdb MongoDB shell version v4.4.1 connecting to: mongodb://127.0.0.1:27017/testdb?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("60c43e94-04c6-46f4-be07-07ca8fa06b2f") } MongoDB server version: 4.4.1 > show dbs > exit bye [root@node12 ~]# mongo -utest -padmin 192.168.0.52:27017/testdb MongoDB shell version v4.4.1 connecting to: mongodb://192.168.0.52:27017/testdb?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("a30dbd64-7b59-4a8e-b95d-02ff30e256f3") } MongoDB server version: 4.4.1 > show dbs > show tables >
以上就是在mongodb中開啟訪問控制,創建用戶,授權的操作;我們只需要在配置文件中指定開啟認證功能,然后使用具有創建用戶權限的用戶登錄數據庫創建用戶授權即可;