1. 程式人生 > 資料庫 >關於Mongodb 認證鑑權你需要知道的一些事

關於Mongodb 認證鑑權你需要知道的一些事

前言

本文主要給大家介紹了Mongodb認證鑑權的一些相關內容,通過設定認證鑑權會對大家的mongodb安全進一步的保障,下面話不多說了,來一起看看詳細的介紹吧。

一、Mongodb 的許可權管理

認識許可權管理,說明主要概念及關係

與大多數資料庫一樣,Mongodb同樣提供了一套許可權管理機制。 為了體驗Mongodb 的許可權管理,我們找一臺已經安裝好的Mongodb,可以參照這裡搭建一個單節點的Mongodb。

直接開啟mongo shell:

./bin/mongo --port=27017

嘗試執行stats命令以檢視appdb資料庫的狀態:

MongoDB Enterprise > use appdb
MongoDB Enterprise > db.stats()
{
 "ok" : 0,"errmsg" : "not authorized on nscl to execute command { dbstats: 1.0,scale: undefined }","code" : 13
}

此時的提示正是說明你當前的操作沒有獲得許可,使用appdb預建立的使用者進行鑑權:

> db.auth('appuser','yourpassword')
1
> db.stats()
{
 "db" : "appdb","collections" : 0,"views" : 0,"objects" : 0,"avgObjSize" : 0,"dataSize" : 0,"storageSize" : 0,"numExtents" : 0,"indexes" : 0,"indexSize" : 0,"fileSize" : 0,"ok" : 1
}

可以發現,在通過驗明身份之後,stats操作的鑑權獲得了許可。

以上例子可能讓你對資料庫鑑權有了點淺顯認識,那麼接下來開始說點概念了,大致是叫基於角色的許可權控制

[圖-角色許可權控制]

先解釋下圖中的幾個實體:

  • Resource,資源 一個資源可以是一個數據庫、集合、或者一個叢集..往大了說,任何可能被操作的事物都可以被當做資源。
  • Action,動作 動作是指對資源的一個執行行為,比如讀取表、讀取資料庫,其中讀取便是一個動作。
  • Privilege,許可權 許可權指的是對某類或某一些資源執行某些動作的允許,與Permission的意義一致。
  • Role,角色 系統中的角色,通常是代表了一種權力等級的象徵,比如論壇中的管理員、版主、遊客等等,就是角色; 系統定義中,角色往往代表一組許可權的集合。
  • User,使用者 可登入系統的實體,一個使用者通常可被賦予多個角色。

噢,關於圖的簡單解釋: 許可權定義了對某些資源的某些操作,角色則可以擁有多個許可權; 使用者User可以被賦予多個角色,從而獲得這些角色所擁有的許可權以操作某些資源

對於Mongodb來說,只要開啟鑑權,所有的DB訪問操作都需要通過許可權檢查。而大致的操作流程跟下圖類似

[圖-mongo鑑權]

Mongodb 的使用者歸屬於某個資料庫,使用者需要在所屬的資料庫中進行鑑權;
一旦通過鑑權,當前的會話(連線)中所有操作將按照使用者被賦予的角色許可權執行檢查。

二、鑑權方式

闡述Mongodb支援的幾種鑑權方式 鑑權方式是指Mongodb如何識別接入使用者,如何檢查許可權是否合法的一系列校驗機制。

  • SCRAM-SHA-1 SCRAM-SHA-1 是預設的鑑權機制,定義於 IETF standard,RFC 5802 是一種安全性較高的"挑戰-應答"鑑權機制。關於"挑戰-應答"可以參考維基百科
  • MongoDB Challenge and Response (MONGODB-CR) 3.0 以前採用的機制,已經廢棄
  • x.509 Certificate Authentication. 基於證書的鑑權,採用該方式可建立 SSL/TLS 加密連線
  • LDAP proxy authentication 基於LDAP 系統的鑑權,僅企業版支援
  • Kerberos authentication 基於Kerberos 的鑑權,僅企業版支援

SCRAM-SHA-1 是當前推薦使用的鑑權方式,既然如此,有必要上圖繼續解釋:


步驟解讀

  1. 客戶端發起一個SCRAM鑑權請求; 鑑權引數中帶上使用者名稱、客戶端隨機字串(防止重放攻擊);
  2. 服務端發出一個挑戰響應; 服務側先檢查使用者名稱,通過後生成一個salt因子、迭代數、合併字串(包含客戶端隨機串和服務端隨機串)
  3. 客戶端響應一個proof(證明資料)和合並字串; 響應的 proof資料根據服務所給的隨機引數以及客戶端金鑰生成,是一個客戶端簽名與金鑰異或計算後的結果;
  4. 服務端將儲存的金鑰結合隨機引數,使用同樣的演算法生成簽名並校驗客戶端 proof資料; 若校驗通過,服務端採用類似方式傳送自己的簽名;
  5. 客戶端校驗服務端簽名資料。

可以看到,SCRAM鑑權時也類似SSL/TLS 的握手過程,但相比之下簡單許多,同時在效能方面也要具備優勢; 然後我們看看安全性的部分:

  • 資訊竊聽,傳輸過程中全部採用動態簽名,保證密碼不會被傳輸;
  • 重放攻擊,由於使用了隨機數,每次生成的資料都不一樣,可避免重複資料攻擊;
  • 服務假冒,鑑權過程是雙向的,即客戶端會校驗服務端身份,而服務端金鑰也根據密碼生成,中間人無法仿造;
  • 儲存安全,密碼在資料庫中均沒有明文儲存,都通過不可逆的演算法加密儲存。

另外SCRAM-SHA-1 相比MONGODB-CR的優勢還有:

A tunable work factor (iterationCount),可靈活調整的安全係數 Per-user random salts rather than server-wide salts 每個使用者有獨立的隨機係數 A cryptographically stronger hash function (SHA-1 rather than MD5),更安全的hash函式 Authentication of the server to the client as well as the client to the server. 支援雙向認證

對 SCRAM-SHA-1的實現感興趣?戳這裡

三、內部鑑權

副本集、分片叢集內鑑權方式

內部鑑權是指 Mongo叢集內部節點之間進行訪問的鑑權方式,比如副本集內主備之間的訪問、分片叢集內Mongos 與Mongod之間的訪問。 內部鑑權目前支援兩種方式:

  • KeyFiles 金鑰檔案方式,採用SCAM-SHA-1 的鑑權機制,檔案內包含了一個共享金鑰,由叢集內所有成員共同持有。 通常,金鑰的長度在6-1024字元內,採用Base64編碼。如何使用?
  • X.509 證書 證書鑑權,用於SSL/TLS加密連線通道。 如何使用?

四、資料庫角色

針對Mongodb資料庫中的各種角色進行說明

資料庫訪問

角色名稱 擁有許可權
read 允許讀取指定資料庫的角色
readWrite 允許讀寫指定資料庫的角色

資料庫管理

角色名稱 擁有許可權
dbAdmin 允許使用者在指定資料庫中執行管理函式,如索引建立、刪除,檢視統計或訪問system.profile
userAdmin 允許管理當前資料庫的使用者,如建立使用者、為使用者授權
dbOwner 資料庫擁有者(最高),集合了dbAdmin/userAdmin/readWrite角色許可權

叢集管理

角色名稱 擁有許可權
clusterAdmin 叢集最高管理員,集合clusterManager/clusterMonitor/hostManager角色許可權
clusterManager 叢集管理角色,允許對分片和副本集叢集執行管理操作,如addShard,resync等
clusterMonitor 叢集監控角色,允許對分片和副本集叢集進行監控,如檢視serverStatus
hostManager 節點管理角色,允許監控和管理節點,比如killOp、shutdown操作

備份恢復

角色名稱 擁有許可權
backup 備份許可權,允許執行mongodump操作
restore 恢復許可權,允許執行mongoresotre操作

資料庫通用角色

角色名稱 擁有許可權
readAnyDatabase 允許讀取所有資料庫
readWriteAnyDatabase 允許讀寫所有資料庫
userAdminAnyDatabase 允許管理所有資料庫的使用者
dbAdminAnyDatabase 允許管理所有資料庫

特殊角色

角色名稱 擁有許可權
root 超級管理員,擁有所有許可權
__system 內部角色,用於叢集間節點通訊

基本是這些,有興趣可看看官方的內建角色 Mongodb 的使用者及角色資料一般位於當前例項的 admin資料庫,system.users存放了所有資料; 存在例外的情況是分片叢集,應用接入mongos節點,鑑權資料則存放於config節點。因此有時候為了方便分片叢集管理,會單獨為分片內部節點建立獨立的管理操作使用者;

五、相關操作

簡單列舉使用者許可權相關的常用操作

授權啟動

./bin/mongod --auth

預設為非授權啟動 也可以通過security.authorization配置指定

建立管理員使用者

use admin
db.createUser({
 user:'admin',pwd:'admin@2016',roles:[
 {role:'clusterAdmin',db:'admin'},{role:'userAdminAnyDatabase',db:'admin'}
 ]})

建立使用者

use appdb
db.createUser({user:'appuser',pwd:'appuser@2016'})

授予許可權

use appdb
db.grantRolesToUser("appuser",[{role:'readWrite',db:'appdb'}])

刪除許可權

use appdb
db.revokeRolesFromUser("appuser",[{ role: "read",db: "appdb" }])

更多操作

六、常見問題

shell 操作提示錯誤

use appdb
MongoDB Enterprise > db.stats()
{
 "ok" : 0,"errmsg" : "not authorized on appdb to execute command { dbstats: 1.0,"code" : 13
}

原因:當前連線未鑑權或使用者沒有操作許可權 解決:為使用者分配適當許可權,並執行auth操作,如下:

db.auth('appuser','yourpassword');

無法執行 eval 操作

db.eval() 是一個全域性操作,可執行任意資料庫指令碼; 執行該命令需要擁有anyAction或anyResource的許可權,通常不建議為資料庫使用者賦予這樣的許可權。 該命令存在安全風險,已不建議使用(mongodb 3.0之後已經過期)。

總結

以上就是這篇文章的全部內容了,本文還有許多不足,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對我們的支援。

擴充套件閱讀

Mongodb 鑑權機制 https://docs.mongodb.com/manual/core/authentication/

Mongodb 內建角色介紹 https://docs.mongodb.com/manual/reference/built-in-roles/#database-user-roles

Mongodb 許可權操作介紹 https://docs.mongodb.com/manual/reference/privilege-actions/#security-user-actions

運維-Mongodb鑑權介紹 http://www.ywnds.com/?p=5635