1. 程式人生 > >【九】MongoDB管理之安全性

【九】MongoDB管理之安全性

方法 開啟 oot backup 由於 alt 集群管理 失敗 exec

要保證一個安全的MongoDB運行環境,DBA需要實施一些控制保證用戶或應用程序僅僅訪問它們需要的數據。這些措施包括但不限於:

  • 認證機制
  • 基於角色的訪問控制
  • 加密
  • 審計

一、認證機制

認證是驗證客戶端用戶身份的過程。開啟訪問控制後,MongoDB需要所有客戶端認證它們自己身份以決定它們的訪問權限。盡管認證和授權比較相近,但是認證是區別於授權的,認證是證明身份,授權是決定它們訪問的資源和操作。

1、用戶

為了認證客戶端,你必須要添加一個對應的用戶到MongoDB.

  • 用戶管理接口:db.createUser()方法可以創建一個用戶,添加完成後可以分配角色給用戶,第一個用戶必須是管理員,用來管理其他用戶。你也可以更新存在的用戶,必須修改密碼和權限。
  • 認證數據庫:當添加一個用戶後,你在某個指定的數據庫中添加該用戶,那麽這個數據庫對於該用戶就是個認證數據庫。一個用戶可以有權限訪問多個數據庫,通過分配角色權限來做到。
  • 認證用戶:為了認證用戶,可以通過db.author()方法。
  • 分片集群用戶:為分片集群創建用戶,可以通過mongos實例進行,mongodb將用戶信息存儲到config server的admin庫中。但是有些操作需要直接連接到分片主機上進行的,這時這些用戶就不行了,需要到分片主機上創建shard local管理用戶

2、認證機制

1)SCRAM-SHA-1

2)MONGODB-CR

3)x.509

二、基於角色的訪問控制

MongoDB默認是沒有開啟訪問控制,你能開啟通過--auth參數重啟mongod服務。一旦開啟了,用戶連接mongod必須指定用戶名和密碼。

1、內建角色

MongoDB提供許多內建角色,用於不同級別的訪問數據庫資源。在每個數據庫中都存在內建數據庫用戶角色和數據庫管理員角色

1)數據庫用戶角色

每個數據庫都包含以下角色:

  • read:提供讀權限,除了非系統集合
  • readWrite:提供讀寫權限

2)數據庫管理員角色

每個數據庫都包含以下角色:

  • dbAdmin:提供schema相關的操作、索引、搜集統計信息等權限,不能分配角色。
  • dbOwner:這個角色包括readWrite、dbAdmin、userAdmin角色的權限
  • userAdmin:提供修改和創建角色和用戶的權限。由於該角色能夠分配權限,包括他們自己,所以間接的提供超級用戶的權限。

3)集群管理角色

  • clusterAdmin:提供集群管理的最高權限,包括clusterManager、clusterMonitor、hostManager角色。此外還有刪除數據庫的權限
  • clusterManager:能夠訪問config和local數據庫的權限
  • clusterMonitor:對於監控工具提供只讀權限
  • hostManager:提供監控和管理主機的權限

4)備份和恢復角色

  • backup:除了system.profile集合,該角色提供足夠的權限來使用MongoDB Cloud Manager、Ops Manager、mongodump等工具對所有集合進行備份。
  • restore:恢復數據的權限

5)所有數據庫權限

  • readAnyDatabase:提供讀所有數據庫的權限
  • readWriteAnyDatabase:同readWrite,範圍是所有數據庫。
  • userAdminAnyDatabase:同userAdmin,範圍是所有數據庫
  • dbAdminAnyDatabase:同dbAdmin,範圍所有數據庫

6)超級角色

  • root:提供所有權限

7)內部角色

  • __system:提供維護數據庫對象的權限,一般不用分配給用戶。

2、自定義角色

MongoDB提供許多內建角色,當然,如果不滿足需要,你可以創建自己的角色

你可以使用db.createRole()方法創建角色,這些角色被存儲在admin庫的system.roles集合中。

3、基於集合級別的訪問控制

基於集合級別訪問控制允許DBA基於某些特定集合給用戶分配權限,也就是用戶只能訪問某些特定的集合。

【訪問級別控制實例:單機環境】

步驟一:在未啟用訪問級別前創建管理員用戶,(如果不這樣,一旦開啟了訪問控制,你雖然可以進入mongos,但是不具有任何增刪改權限了):

技術分享
use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)
技術分享

步驟二:帶--auth參數重啟mongod服務(即開啟訪問級別控制)

mongod --dbpath=/data/27019/db --fork --logpath=/data/27019/log/mongodb.log --port 27019 --auth

步驟三:使用管理員登錄並創建一個普通用戶

技術分享
[[email protected] 27019]# mongo --port 27019 -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"   #使用管理員登錄
use test
db.createUser(                           #在test庫中創建所屬用戶testUser,雖然該用戶屬於test庫,但是通過角色分配,它也可以對其他數據庫有操作權限
    {
      user: "testUser",
      pwd: "12345678",
      roles: [
         { role: "read", db: "children" },   #對children庫有只讀權限
         { role: "readWrite", db: "test" },  #對test庫有讀寫權限
         { role: "readWrite", db: "HashTest" } #對HashTest庫有讀寫權限
      ]
    }
)
#使用新用戶testUser登錄測試 [[email protected] 27019]# mongo --port 27019 -u "testUser" -p "12345678" MongoDB shell version: 3.2.0 connecting to: 127.0.0.1:27019/test > db.user.insert({"_id":1,"name":"darren"}) #向test庫中插入數據,可以成功 WriteResult({ "nInserted" : 1 }) > use children #向children庫中插入數據,失敗,因為只有讀的權限 switched to db children > db.user.insert({"_id":1,"name":"darren"}) WriteResult({ "writeError" : { "code" : 13, "errmsg" : "not authorized on children to execute command { insert: \"user\", documents: [ { _id: 1.0, name: \"darren\" } ], ordered: true }" } })
> use HashTest
switched to db HashTest
> db.user.insert({"_id":1,"name":"darren"}) #向HashTest庫中插入數據,成功。
WriteResult({ "nInserted" : 1 })
技術分享

總結:MongoDB一個數據庫需要屬於一個用戶,當一個相同的用戶需要訪問多個數據庫,不需要在每個數據庫中都建立同樣的用戶,可以建立一個專門管理用戶的庫,通過角色分配達到這種目的,更加容易維護和管理。

三、加密

1、傳輸加密

你可以用TLS/SSL來加密MongoDB的網絡流量,它們能夠確保網絡流量僅僅被需要的客戶端讀取。

2、靜態加密

有兩種主要的方法加密靜態數據:應用程序層加密和存儲層加密。你可以一起用也可以單獨使用一種。V3.2中為WiredTiger存儲引擎引入新的加密選項,這種特性允許你加密數據文件,如此一來只有帶有解密鍵的那部分能夠解密和讀取數據。詳細講解請參考官方手冊。

四、審計

MongoDB企業版包括審計功能。審計功能允許管理員和用戶在部署多用戶和應用程序環境時跟蹤系統活動。具體請查閱官方文檔。

五、其他方面安全控制

1、MongoDB配置

確保禁用http狀態接口,默認mongodb是禁用的。

2、網絡安全

配置操作系統防火墻控制訪問系統級別或者使用VPN。

1)防火墻規則(liunx)

通過指定防火墻規則,mongodb管理員可以控制哪些主機可以連接到mongodb服務器上,從而減少mongodb服務器曝光度,限制風險。

在iptables規則配置分為鏈,這裏主要控制兩個鏈:
  • INPUT:控制所有進入者
  • OUTPUT:控制所有輸出

這個模式適用於所有到mongod實例的單機或者副本集成員主機,目的是只允許應用服務器連接到mongodb服務器上:

iptables -A INPUT -s <ip-address> -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27017 -m state --state ESTABLISHED -j ACCEPT

2)VPNs

具體參考文檔。

【九】MongoDB管理之安全性