1. 程式人生 > 實用技巧 >CodeForces681C - Heap Operations - 優先佇列+模擬

CodeForces681C - Heap Operations - 優先佇列+模擬

1. 安全認證概述

MongoDB 預設是沒有賬號的,可以直接連線,無須身份驗證。實際專案中肯定是要許可權驗證的,否則 後果不堪設想。所以對MongoDB進行安全認證 是必須要做的。

2. 使用者相關操作

2.1 切換到admin資料庫對使用者的新增

use admin;
db.createUser(userDocument):用於建立 MongoDB 登入使用者以及分配許可權的方法

db.createUser( 
	{
		user: "賬號",
		pwd: "密碼",
		roles: [
		{ role: "角色", db: "安全認證的資料庫" }, 
		{ role: "角色", db: "安全認證的資料庫" }
		]
	} 
)
  • user:建立的使用者名稱稱,如 admin、root 、lagou
  • pwd:使用者登入的密碼
  • roles:為使用者分配的角色,不同的角色擁有不同的許可權,引數是陣列,可以同時設定多個
  • role:角色,MonngoDB 已經約定好的角色,不同的角色對應不同的許可權
  • db:資料庫例項名稱,如 MongoDB 4.0.2 預設自帶的有 admin、local、config、test 等,即為哪個資料庫例項設定使用者
db.createUser({
  user:"root",
  pwd:"123456",
  roles:[{role:"root",db:"admin"}]
})

2.2 修改密碼

db.changeUserPassword( 'rootNew' );

2.3 使用者新增角色

db.grantRolesToUser( '使用者名稱' , [{ role: '角色名' , db: '資料庫名'}])

2.4 以auth方式啟動mongod

./bin/mongod -f conf/mongo.conf --auth
(也可以在mongo.conf 中新增auth=true 引數)

2.5 驗證使用者

db.auth("賬號","密碼")

2.6 刪除使用者

db.dropUser("使用者名稱")

3. 角色

3.1 資料庫內建的角色

read:允許使用者讀取指定資料庫
readWrite:允許使用者讀寫指定資料庫 
dbAdmin:允許使用者在指定資料庫中執行管理函式,如索引建立、刪除,檢視統計或訪問 system.profile 
userAdmin:允許使用者向system.users集合寫入,可以找指定資料庫裡建立、刪除和管理使用者 
clusterAdmin:只在admin資料庫中可用,賦予使用者所有分片和複製集相關函式的管理許可權 
readAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀許可權 
readWriteAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀寫許可權 
userAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的userAdmin許可權 
dbAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin許可權 
root:只在admin資料庫中可用。超級賬號,超級許可權 
dbOwner:庫擁有者許可權,即readWrite、dbAdmin、userAdmin角色的合體

3.2 各個型別使用者對應的角色

資料庫使用者角色:read、readWrite
資料庫管理角色:dbAdmin、dbOwner、userAdmin 
叢集管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager 
備份恢復角色:backup、restore; 
所有資料庫角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超級使用者角色:root 
這裡還有幾個角色間接或直接提供了系統超級使用者的訪問(dbOwner 、userAdmin、 userAdminAnyDatabase)

4. 單機安全認證實現流程

建立 mydb1 資料庫並建立了兩個使用者,zhangsan 擁有讀寫許可權,lisi 擁有隻讀許可權測試這兩個賬戶的許可權。
以超級管理員登入測試許可權。

4.1 建立管理員

MongoDB 服務端開啟安全檢查之前,至少需要有一個管理員賬號,admin 資料庫中的使用者都被視為管理員
如果 admin 庫沒有任何使用者的話,即使在其他資料庫中建立了使用者,啟用身份驗證,預設的連線方式依然會有超級許可權,即仍然可以不驗證賬號密碼照樣能進行 CRUD,安全認證相當於無效。

shard1:PRIMARY> use admin
switched to db admin
shard1:PRIMARY> db.createUser({
...   user:"root",
...   pwd:"123456",
...   roles:[{role:"root",db:"admin"}]
... })
Successfully added user: {
        "user" : "root",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
shard1:PRIMARY>

4.2 建立普通使用者

如下所示 rpp_resume 是自己新建的資料庫,沒安全認證之前可以隨意 CRUD,其餘的都是 mongoDB4.0.2 自帶的資料庫

shard1:PRIMARY> show dbs
admin       0.000GB
config      0.001GB
local       0.001GB
rpp_resume  0.000GB
  • 為 admin 庫建立管理員之後,現在來為普通資料庫建立普通使用者,以 rpp_resume 為例,方式與建立管理員一致,切換到指定資料庫進行建立即可。
  • 如下所示,為 rpp_resume 資料庫建立了兩個使用者,zhangsan 擁有讀寫許可權,lisi 擁有隻讀許可權,密碼 都是 123456.
shard1:PRIMARY> show dbs
admin       0.000GB
config      0.001GB
local       0.001GB
rpp_resume  0.000GB
shard1:PRIMARY> use rpp_resume
switched to db rpp_resume
shard1:PRIMARY> db
rpp_resume
shard1:PRIMARY> db.createUser({
...   user:"zhangsan",
...   pwd:"123456",
...   roles:[{role:"readWrite",db:"rpp_resume"}]
... })
Successfully added user: {
        "user" : "zhangsan",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "rpp_resume"
                }
        ]
}
shard1:PRIMARY> db.createUser({
...   user:"lisi",
...   pwd:"123456",
...   roles:[{role:"read",db:"rpp_resume"}]
... })
Successfully added user: {
        "user" : "lisi",
        "roles" : [
                {
                        "role" : "read",
                        "db" : "rpp_resume"
                }
        ]
}
shard1:PRIMARY>

接著從客戶端關閉 MongoDB 服務端,之後以安全認證方式進行啟動

> use admin
switched to db admin
> db.shutdownServer() 
> server should be down...

4.3 MongoDB 安全認證方式啟動

./bin/mongod -f conf/mongo.conf --auth
(也可以在mongo.conf 中新增auth=true 引數)

4.4 以普通使用者登入驗證許可權

普通使用者現在仍然像以前一樣進行登入,如下所示直接登入進入 rpp_resume 資料庫中,登入是成功的,只是登入後日志少了很多東西,而且執行 show dbs 命令,以及 show tables 等命令都是失敗的,即使沒有被安全認證的資料庫,使用者同樣操作不了,這都是因為許可權不足,一句話:使用者只能在自己許可權範圍 內的資料庫中進行操作

[root@rpp mongodb]# ./bin/mongo localhost:37017/rpp_resume
MongoDB shell version v4.2.9
connecting to: mongodb://localhost:37017/rpp_resume?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2450aa2a-b830-40fb-a568-9b22d205bb3e") }
MongoDB server version: 4.2.9
shard1:SECONDARY> show dbs

如下所示,登入之後必須使用 db.auth(“賬號”,“密碼”) 方法進行安全認證,認證通過,才能進行許可權範圍內的操作

shard1:SECONDARY> db.auth("zhangsan","123456")
1
shard1:SECONDARY> show dbs
2020-10-11T12:13:30.423+0800 E  QUERY    [js] uncaught exception: Error: listDatabases failed:{
        "operationTime" : Timestamp(1602389608, 1),
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk",
        "$gleStats" : {
                "lastOpTime" : Timestamp(0, 0),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(1602389608, 1),
        "$configServerState" : {
                "opTime" : {
                        "ts" : Timestamp(1602389597, 2),
                        "t" : NumberLong(1)
                }
        },
        "$clusterTime" : {
                "clusterTime" : Timestamp(1602389608, 1),
                "signature" : {
                        "hash" : BinData(0,"MxDcKpZdPP+t62G0PiLfmgaSJMk="),
                        "keyId" : NumberLong("6881926690809839647")
                }
        }
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:135:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:87:12
shellHelper.show@src/mongo/shell/utils.js:906:13
shellHelper@src/mongo/shell/utils.js:790:15
@(shellhelp2):1:1
shard1:SECONDARY> rs.slaveOk()
shard1:SECONDARY> show dbs
rpp_resume  0.000GB
shard1:SECONDARY>

4.5 以管理員登入驗證許可權

客戶端管理員登入如下所示,管理員 root 登入,安全認證通過後,擁有對所有資料庫的所有許可權。

[root@rpp mongodb]# ./bin/mongo localhost:37017
MongoDB shell version v4.2.9
connecting to: mongodb://localhost:37017/test?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("7d54c6fa-bb32-450e-874e-03af43ffc375") }
MongoDB server version: 4.2.9
shard1:SECONDARY> use admin
switched to db admin
shard1:SECONDARY> db.auth("root","123456")
1
shard1:SECONDARY> show dbs
admin       0.000GB
config      0.001GB
local       0.001GB
rpp_resume  0.000GB

5. 分片叢集安全認證

5.1 開啟安全認證之前進入路由建立管理員和普通使用者

參考上面的單機安全認證實現流程

5.2 關閉所有的配置節點 分片節點 和 路由節點

安裝psmisc
yum install psmisc
安裝完之後可以使用killall 命令 快速關閉多個程序 
killall mongod

5.3 生成金鑰檔案 並修改許可權

openssl rand -base64 756 > /data/mongodb/testKeyFile.file 
chmod 600 /data/mongodb/testKeyFile.file

5.4 配置節點叢集和分片節點叢集開啟安全認證和指定金鑰檔案

auth=true 
keyFile=/data/mongodb/testKeyFile.file

5.5 在路由配置檔案中 設定金鑰檔案

keyFile=data/mongodb/testKeyFile.file

5.6 啟動所有的配置節點 分片節點 和 路由節點 使用路由進行許可權驗證

可以編寫一個shell 指令碼 批量啟動

./bin/mongod -f config/config-17017.conf 
./bin/mongod -f config/config-17018.conf 
./bin/mongod -f config/config-17019.conf 
./bin/mongod -f shard/shard1/shard1-37017.conf 
./bin/mongod -f shard/shard1/shard1-37018.conf 
./bin/mongod -f shard/shard1/shard1-37019.conf 
./bin/mongod -f shard/shard2/shard2-47017.conf 
./bin/mongod -f shard/shard2/shard2-47018.conf 
./bin/mongod -f shard/shard2/shard2-47019.conf 
./bin/mongos -f route/route-27017.conf

5.7 Spring boot 連線安全認證的分片叢集

spring.data.mongodb.username=賬號 
spring.data.mongodb.password=密碼 
spring.data.mongodb.uri=mongodb://賬號:密碼@IP:埠/資料庫名