Mongodb 叢集加keyFile認證,Mongodb使用者管理(轉:http://blog.csdn.net/wlzjsj/article/details/61421230)
介紹
自從遠古計繩結開始,資料庫的儲存就註定了今天的地位和多樣性,Nosql的出現更是解決了現有的關係型資料庫無法解決的一些難題,對高效能,靈活度,擴充套件性,海量資料的問題。隨之而出現的高速記憶體索引資料庫、列式儲存、影象儲存等等,這篇文章主要講的是mongodb文件型資料庫,mongodb目前也在各種大中小型創業型公司大受歡迎,佔據了一定的地位。文章講解的是如何搭建一個安全認證的mongodb叢集(安全認證還是很重要,各大資料庫被淪陷後,怎麼有效預防被勒索比特幣….)
mongodb叢集有三種模式,主從模式,副本集模式、sharding分片模式。主從模式官網也不再推薦上生產環境,主要是安全性太低。副本集和sharding模式目前是用的最廣的方案,通常這2種方案的選擇通過資料量和併發數來權衡。在GB級別的基本上副本集方案可滿足,TB級別或以上採用sharding模式,解決單機容量和單機併發能力。這兩種既有自己的優勢也有自己的缺點,比如sharding模式分片越多,效能自然下降越多。
進入正題,講解副本集的搭建以及配置安全認證。副本集有兩種方案,一種是有仲裁節點(Arbiter
),如圖1,一種是不含仲裁節點,如圖2所示。
圖1 一主一從一仲裁
圖2 多節點副本
當資料節點為偶數時候需要增加仲裁節點,故障時候仲裁新的主,當資料節點為奇數時候無需仲裁節點,根據id優先順序選舉新的主。仲裁節點本身不儲存資料,如果配置仲裁節點使用虛擬機器即可。本文為了節約機器提高資料的安全度使用的是不帶仲裁節點的方案:
一、 環境:
系統:Ubuntu 16.04.02 LTS
mongodb版本:https://www.mongodb.org/dr/fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.2.tgz
伺服器:
Mongodb 主機 |
伺服器埠地址 |
預設角色 |
mongodb主機 1 |
10.10.1.163:30010 |
primary |
mongodb主機 2 |
10.10.1.109: 30010 |
secondary |
mongodb主機 3 |
10.10.1.110: 30010 |
secondary |
二、 安裝mogodb
2.1 建立mongo使用者
略(如果root啟動,可忽略本步驟,啟動使用者是mongo就必須叢集目錄授權mongo使用者)
2.2 叢集目錄
建立mongo叢集目錄,最好三臺配置都一樣,方便維護(以下操作三臺伺服器均一樣);
解壓二進位制壓縮包並複製到/usr/local目錄下
tar xzf mongodb-linux-x86_64-3.4.2.tgz mv mongodb-linux-x86_64-3.4.2 mongodb-3.4.2 ln –s mongodb-3.4.2 mongodb |
建立叢集目錄:
mkdir –p data/mongo_set/$叢集名字/30010 |
配置叢集的配置檔案:
# usercenter replset master bind_ip=10.10.1.163 #指定伺服器監聽的埠,預設是27017 port=30010
#叢集名字 replSet=test_set #以守護程序的方式執行MongoDB fork=true
#一個數據庫一個資料夾 directoryperdb=true
##啟用日誌選項,MongoDB的資料操作將會寫入到journal資料夾的檔案裡 journal = true
# 在收到客戶資料,檢查的有效性 objcheck=true
#操作日誌大小限制2G oplogSize=2000
#pidfile pidfilepath=/data/mongo_set/test_set/30010/mongo_m30010.pid
#指定資料目錄,預設是/data/db/。每個mongod程序都需要獨立的目錄, #啟動mongod時就會在資料目錄中建立mongod.lock檔案,防止其他mongod程序使用該資料目錄。 dbpath=/data/mongo_set/test_set/30010
#指定日誌輸出路徑,如果不指定則會在終端輸出。每次啟動都會覆蓋原來的日誌,如果不想覆蓋就要用--logappend選項 logpath=/data/mongo_set/test_set/30010/mongo30010.log
logappend=true #auth=true
#0:關閉,不收集任何資料。1:收集慢查詢資料,預設是100毫秒。2:收集所有資料 profile=2 slowms=100 #.禁止HTTP狀態介面 nohttpinterface=true #.禁止REST介面-在生產環境下建議不要啟用MongoDB的REST介面 rest=false |
2.3 三臺主機分別啟動mongodb
Primary啟動: /usr/local/mongodb/bin/mongod –f /data/mongo_set/test_set/30010/mongodb_m30010.conf Secondary1: /usr/local/mongodb/bin/mongod –f /data/mongo_set/test_set/30010/mongodb_s30010.conf Secondary2: /usr/local/mongodb/bin/mongod –f /data/mongo_set/test_set/30010/mongodb_s30010.conf |
三、 配置副本集
3.1 配置主primary
此時我們並沒有配置任何認證賬戶,我們登入主庫:
[email protected]:~#mongo 10.10.1.163:30010 MongoDB server version: 3.4.2 Server has startup warnings: 2017-03-10T20:08:31.847+0800 I STORAGE [initandlisten] 2017-03-10T20:08:31.847+0800 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2017-03-10T20:08:31.847+0800 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem 2017-03-10T20:08:32.115+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2017-03-10T20:08:32.115+0800 I CONTROL [initandlisten] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** WARNING: You are running on a NUMA machine. 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** We suggest launching mongod like this to avoid performance problems: 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** numactl --interleave=all mongod [other options] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 65535 processes, 655350 files. Number of processes should be at least 327675 : 0.5 times number of files. 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] test_set:PRIMARY> test_set:PRIMARY> use admin switched to db admin |
3.2 配置副本幾點及權重
test_set:PRIMARY> config_test={_id : 'usercenter',members : [{_id : 0, host : '10.10.1.1.163:30010'},{_id : 1, host : '10.10.1.109:30010'},{_id : 2, host : '10.10.1.110:30010'}]} #初始化副本集 test_set:PRIMARY> rs.initiate(config_ test); { "ok" : 1 } |
3.3檢視副本叢集狀態
test_set:PRIMARY> rs.status() { "set" : "test_set", "date" : ISODate("2017-03-11T08:25:02.832Z"), "myState" : 1, "term" : NumberLong(5), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "appliedOpTime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "durableOpTime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) } }, "members" : [ { "_id" : 0, "name" : "10.10.1.163:30010", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 72991, "optime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "optimeDate" : ISODate("2017-03-11T08:24:54Z"), "electionTime" : Timestamp(1489147722, 1), "electionDate" : ISODate("2017-03-10T12:08:42Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "10.10.1.109:30010", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 72980, "optime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "optimeDurable" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "optimeDate" : ISODate("2017-03-11T08:24:54Z"), "optimeDurableDate" : ISODate("2017-03-11T08:24:54Z"), "lastHeartbeat" : ISODate("2017-03-11T08:25:02.583Z"), "lastHeartbeatRecv" : ISODate("2017-03-11T08:25:01.359Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.10.1.163:30010", "configVersion" : 1 }, { "_id" : 2, "name" : "10.10.1.110:30010", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 72971, "optime" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "optimeDurable" : { "ts" : Timestamp(1489220694, 1), "t" : NumberLong(5) }, "optimeDate" : ISODate("2017-03-11T08:24:54Z"), "optimeDurableDate" : ISODate("2017-03-11T08:24:54Z"), "lastHeartbeat" : ISODate("2017-03-11T08:25:02.442Z"), "lastHeartbeatRecv" : ISODate("2017-03-11T08:25:01.007Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.10.1.163:30010", "configVersion" : 1 } ], "ok" : 1 } test_set:PRIMARY> |
3.4 檢視副本同步狀態
test_set:PRIMARY> db.printSlaveReplicationInfo(); source: 10.10.1.109:30010 syncedTo: Sat Mar 11 2017 16:25:24 GMT+0800 (CST) 0 secs (0 hrs) behind the primary source: 10.10.1.110:30010 syncedTo: Sat Mar 11 2017 16:25:24 GMT+0800 (CST) 0 secs (0 hrs) behind the primary |
一切ok,該副本集搭建完成。目前副本集架構如下所示:
四、 增加安全認證機制KeyFile
4.1 叢集之間的安全認證
叢集之間的複製增加keyFile認證
#生成key openssl rand -base64 745 > /data/mongo_set/usercenter/30010/mongodb-keyfile chmod 600 /data/mongo_set/usercenter/30010/mon-keyfile # 該key的許可權必須是600 |
將該key放到叢集中機器的每一臺上,記住必須保持一致,許可權設定成600;
4.2 修改配置
在mongodb.conf啟動配置檔案中增加配置項
#安全認證機制 keyFile=/data/mongo_set/test_set/30010/mon-keyfile |
4.3 主庫配置使用者
也可後面配置,開啟keyfile認證就預設開啟了auth認證了,為了保證後面可以登入,我提前建立了使用者:
先建立管理員賬戶 db.createUser( { user:"admin", pwd:"xxxxxx", roles:[{role:"userAdminAnyDatabase",db:"admin"}] } ); db.createUser( { user: "root", pwd: "xxxxxxx", roles: [ { role: "root", db: "admin" } ] }); #認證使用者 db.auth("admin","xxxxxxx") db.auth("root","xxxxxxx") |
4.4 重啟進入
重新啟動mongodb,記住重新啟動時候,keyfile的指定如果沒有在配置檔案中配置,就必須啟動時候使用引數keyfile指定,關閉順序注意下,mongodb叢集有自動切換主庫功能,如果先關主庫,主庫就切換到其它上面去了,這裡預防主庫變更,從庫關閉後再關閉主庫。
mongo 10.10.1.163:30010/admin -u root –p 2017-03-10T20:08:32.116+0800 I CONTROL [initandlisten] test_set:PRIMARY> use admin switched to db admin |
重新檢視從庫和叢集狀態都是正常。
五、 建立使用者和使用者資料庫
5.1 啟動認證
開啟了安全認證就可以開始對每個資料庫進行安全認證了,首先給使用者建立一個數據庫:
test_set:PRIMARY> use user_test switched to db user_test mongodb建立資料庫直接use即可,此時show dbs是看不到該庫的,需要插入一條資料才會現實出來,這裡不演示; |
建立使用者資料庫的使用者:
db.createUser( { user: “test_user", pwd: "xxxxxx", roles: [ { role: "readWrite", db: "user_test" } ] } ); |
建立完成會顯示成功,可以用db.system.users.find()檢視所有使用者驗證使用者是否存在;
5.2 驗證使用者登入
#client操作 mongo 10.10.1.163:30010/user_test –u user_test –p MongoDB shell version v3.4.2 Enter password: connecting to: mongodb://192.168.1.163:30010/user_center MongoDB server version: 3.4.2 user_test:PRIMARY> |