MongoDB認證和授權
- 2019 年 10 月 4 日
- 筆記
MongoDB認證和授權
要想了解MongoDB的許可權必須先了解如下一些關鍵字:
- user: 用戶,用於提供客戶端連接MongoDB的認證賬戶;
- role: 角色,數據許可權的集合,創建用戶的時候必須要指定對應的角色,否則用戶無法操作資料庫;
- resource: 資源,包括database或collection 也可以是database和collection的組合; 如
{db:<db>, collection:<collection>}
- actions: 許可權操作,定義了 user 能夠對 resource document 執行的操作; 如 增、刪、改、查;
- privilege: 許可權,privilege 是一組 resource 和 action的組合,對資源擁有什麼操作稱為許可權;
- authenticationDatabase: 認證庫,及創建角色或用戶時所在的庫; 如,在admin下創建MongoDB用戶那麼登錄的時候需要指定認證庫 admin; 在 test 庫下創建的用戶登錄的時候指定認證庫 test;
許可權認證
MondoDB單實例認證
MongodDB存儲所有的用戶資訊在admin資料庫的集合system.users中,保存資料庫、密碼和資料庫資訊。MongoDB默認不啟用許可權認證,只要能連接到伺服器,就可連接到mongod。 若要啟用安全認證,需要更改配置文件Authorization,也可簡寫為 auth。或者在命令行啟動MongoDB時加上 -auth
參數啟動,這樣當MongoDB啟動後就需要用戶和密碼進行認證了。
這是老版本MongoDB2.x中:
vim /etc/mongod.conf auth = true
MongoDB3.x中:
vim /etc/mongod.conf security: authorization:enabled
但是,不使用用戶名和密碼依然可以連接到資料庫。但是將沒有許可權查看資料庫。這裡可以認證用戶:
mongo use 庫(如admin) db.auth("user","pwd")
或直接 mongo 127.0.0.1/admin -u user -p
來連接資料庫。 在MongoDB授權部分,其中admin資料庫中的用戶名可以管理所有的資料庫,其他資料庫中的用戶只能管理其所在的資料庫。
MongoDB副本集認證
如果在副本集機制下開啟了 -auth
認證,那麼此時MongoDB副本集狀態就會變成不健康狀態,這就需要另外一個認證方式 KeyFile
。 簡單來說 KeyFile
就是用在副本集群間開啟認證的情況下需要的另一種認證方式,用來驗證集群間身份的。
在各個節點的配置文件中加入KeyFile(600):
vim /etc/mongod.conf security: authorization:enabled KeyFile:/path/.KeyFile
在副本集模式下,在整個配置完成前不要創建任何用戶,當認證好了之後,就可以創建用戶了。
角色管理
MondoDB支援基於角色的訪問控制(RBAC)來管理對MongoDB系統的訪問。一個用戶可以被授權一個或多個角色以決定該用戶對資料庫資源和操作的訪問許可權。在許可權以外,用戶是無法訪問系統的。 資料庫角色在創建用戶的role參數中設置。角色分為內建角色和自定義角色。
內建角色
MongoDB內建角色包括以下幾類:
1. 資料庫用戶角色
read:允許用戶讀取指定資料庫; readWrite:允許用戶讀寫指定資料庫;
2. 資料庫管理員角色
dbAdmin:允許用戶進行索引創建、刪除,查看統計或訪問system.profile,但沒有角色和用戶管理的許可權; userAdmin:提供了在當前資料庫中創建和修改角色和用戶的能力; dbOwner:提供對資料庫執行任何操作的能力。這個角色組合了readWrite、dbAdmin和userAdmin角色授權的特權;
3. 集群管理角色
hostManager:提供監視和管理伺服器的能力; clusterManager:在集群上提供管理和監視操作。可以訪問配置和本地資料庫,這些資料庫分別用於分片和複製; clusterMonitor:提供對監控工具的只讀訪問; clusterAdmin:提供最強大的集群管理訪問(副本集、分片、主從等)。組合了clusterManager、clusterMonitor和hostManager角色的能力,還提供了dropDatabase操作;
4. 備份恢復角色
backup:提供備份數據所需的能力; restore: 提供使用mongorestore恢複數據的能力;
5. 所有資料庫角色
readAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的讀許可權; readWriteAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的讀寫許可權; userAdminAnyDatabase:只在admin資料庫中可用,賦予用戶所有資料庫的userAdmin許可權; dbAdminAnyDataBase:只在admin資料庫中可用,賦予用戶所有資料庫的adAdmin許可權;
6. 超級用戶角色
root:超級許可權,只能針對admin庫;
7. 內部角色
__system:提供對資料庫中任何對象的任何操作的特權;
自定義角色
MongoDB內置角色一般來說都是夠用的,但當內置角色不滿足需求時就可以自定義角色了。使用 db.createRole()
方法來自定義角色。 只能在 admin庫 中創建角色;
use admin db.createRole( { role:<role_name>, #定義角色名稱 privilege:[ #許可權集 {resource:{cluster:true, actions:[<action_name>]}, {resource: {db:<db_name>, collection:<coll_name>}, actions:[<action_name>]} #定義對這個庫或集合可進行的許可權操作,這是一個數組 ], roles:[{role:<role_name>, db:<db_name>}] #是否繼承其他的角色
角色創建完畢後 MongoDB 會在系統庫 admin 下創建一個系統 collection 名叫 system.roles,裡面存儲的即是角色相關的資訊。使用如下命令查看:
db.system.roles.find()
操作角色
查看角色
db.getRole()
角色繼承
db.grantRolesToRole() #角色授權 db.revokeRolesfromRole() #角色移權
用戶管理
創建用戶
db.createUser({ user:"xxx", pwd:"xxxx", customDate:"xxx", roles:[{ #指定角色名稱以及認證庫 role:"xxx", db:"xxxx" }] })
認證
vim /etc/mongo.conf security: authorization:enabled
db.auth("user","passwd") #在use db後 或 mongo -u user -p passwd --authenticationDatabase xxx #在哪個庫創建的用戶就需要使用哪個庫進行認證
查看用戶
db.getUser("user") db.system.users.find()
刪除用戶
db.dropUser("user") db.dropAllUsers() #刪除當前庫所有用戶
添加用戶許可權
db.grantRolesToUser()
修改密碼
db.changeUserPassword("user","new_passwd")
關閉MongoDB,千萬不要 kill -9 pid
,使用 db.shutdownServer()
。
在MongoDB中刪除庫和集合併不會級聯刪除對應的角色和用戶。因此如果想徹底刪除對應的業務應該先刪除庫與其對應的角色和用戶。
如果既想實現精細化許可權控制又想簡化用戶管理,原則上建議只給開發創建一個賬戶,並且使用admin做認證庫,這樣可以避免清理過期業務庫而導致無法登陸的問題。