在前文[15分鐘從零開始搭建支持10w+用戶的生產環境(二)]中提了一句MongoDB的安全,有小夥伴留心了,在公衆號後臺問。因此今天專門開個文,寫一下關於MongoDB的安全。html
近幾年,MongoDB應用愈來愈多,MongoDB也愈來愈火。web
從2015年開始,MongoDB被一些「非法組織/黑客」盯上了。他們的作法也很簡單,連到你的數據庫上,把你的數據拿走,而後把你的庫清空,留一個消息給你,索要比特幣。mongodb
跟最近流行的勒贖病毒一個套路。shell
我在某個雲上有一臺服務器,主要用來作各類研究和測試,隨時能夠格了重裝的那種。上面跑着一個MongoDB,是用默認的參數簡單啓動的一個單實例。數據庫
早上起來,跑程序測試時,程序直接報錯。安全
跟蹤代碼,發現是頭天寫進去的數據不見了。bash
進到數據庫,發現數據庫都在,但裏面的表全被清空了,多了一個Readme的表。查看這個表的內容:服務器
> db.Readme.find().pretty()
{
"_id" : "5c18d077fd42b92d8f6271c3",
"BitCoin" : "3639hBBC8M7bwqWKj297Jc61pk9cUSKH5N",
"eMail" : "mongodb@tfwno.gf",
"Exchange" : "https://localbitcoins.com",
"Solution" : "Your database is downloaded and backed up on our secured servers. To recover your lost data: Send 0.2 BTC to our BitCoin address and Contact us by eMail with your server IP address and a proof of Payment. Any eMail without your IP address and a proof of Payment will be ignored. Your are welcome!"
}
簡單來講,這是一個通知:你的數據被咱們綁架了,想要贖回去,須要0.2個比特幣。微信
一身冷汗。若是這是一個生產環境,若是這是一個系統的運營數據,後果不堪設想。app
究其緣由,這個數據庫在啓動時,用了默認的參數,未加任何防禦。
因此,
必定不要用默認的設置運行MongoDB數據庫!
必定不要用默認的設置運行MongoDB數據庫!
必定不要用默認的設置運行MongoDB數據庫!
MongoDB啓動時,使用了幾個默認的端口:
27017: 用於通常的單實例(mongod),或者集羣中路由服務器(mongos)
27018: 用於集羣中的分片服務器
27019: 用於集羣中的配置服務器
實際佈署時能夠把默認端口換成別的端口。
命令行:
$ ./mongod --port port_number
配置文件:
port=port_number
這個要區分一下MongoDB的版本。
查詢MongoDB版本的命令:
$ ./mongod --version
在MongoDB Version 3.6以前,MongoDB啓動時默認綁定到服務器的全部IP上。換句話說,經過全部的IP均可以訪問數據庫,這兒的安全隱患在於外網IP。
在3.6以後,MongoDB啓動默認綁定127.0.0.1,從外網沒法訪問,去掉了這個隱患。
設置綁定IP,命令行:
$ ./mongod --bind_ip your_ip #單IP綁定
或
$ ./mongod --bind_ip your_ip1,your_ip2 #多IP綁定
配置文件:
bind_ip=your_ip #單IP綁定
或
bind_ip=your_ip1,your_ip2 #多IP綁定
MongoDB還提供了一個一次綁定全部IP的參數。命令行:
$ ./mongod --bind_ip_all
配置文件:
bind_ip_all=true
另外,綁定時,your_ip也能夠換成域名your_host,效果是同樣的。
在生產環境中,出於安全的須要,一般能夠設置數據庫綁定到服務器的內網IP,供數據層操做數據庫就好。若是有特殊須要,能夠臨時綁定到外網IP,操做完成後再去掉。
數據庫切換綁定IP和端口,對數據庫自己沒有任何影響。
數據庫服務器的內部身份認證,是更高一個層次的安全策略,用於保證主從/複製集/集羣中各個數據庫服務器的安全合法接入。
內部身份認證,首先須要有一個數字密鑰。
數字密鑰可使用機構簽發的證書來生成,也可使用自生成的密鑰。
固然在低安全級別的狀況下,你也能夠隨手寫一個密鑰來使用。
自生成密鑰的生成命令:
$ openssl rand -base64 756 > path_to_keyfile
而後設置密鑰文件的讀寫權限:
$ chmod 400 path_to_keyfile
看一下密鑰文件:
$ ls -l
-rw-r--r-- 1 test test 1024 5 10 17:51 test.key
下面,爲數據庫啓用密鑰文件。命令行:
$ ./mongod --keyFile path_to_keyfile
配置文件:
keyFile=path_to_keyfile
注意:
內部認證用在多於一個服務器的狀況,例如:主從/複製集/集羣上,作服務器之間的互相認證。單個服務器可作可不作,實際上無效。
內部認證要求認證的服務器使用相同的密鑰文件。也就是說,全部的服務器使用同一個密鑰文件。
密鑰文件有安全要求,文件權限必須是400,不然數據庫啓動時會有報錯。
MongoDB支持爲數據庫建立用戶和分配角色,用用戶和角色來管理和使用數據庫。
MongoDB建立用戶操做和上面不一樣。上邊的內容,是在數據庫運行之前進行,而建立用戶,是在數據庫運行之後。
$ ./mongo your_ip:your_port
> use admin
switched to db admin
> db.createUser({"user" : "user_name", "pwd" : "user_password","roles" : [{"role" : "userAdminAnyDatabase", "db" : "admin"}]})
Successfully added user: {
"user" : "user_name",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
這樣咱們就加入了一個用戶。
MongoDB內建的角色分如下幾類:
角色不詳細解釋了,角色名稱的英文寫的很明白。
在實際操做中,一般會將用戶建在admin中,用roles裏的db來指定用戶可使用或管理的數據庫名稱。
經過這一通操做,咱們已經在數據庫中建立好了用戶。下面須要服務器啓用鑑權。
命令行:
./mongod --auth
配置文件:
auth=true
這個用於mongod啓動的數據庫。對於集羣的router,即mongos,會默認啓用auth,因此不須要顯式啓用。
當MongoDB啓用鑑權後,再用mongo客戶端鏈接數據庫,就須要輸入用戶賬號信息了。
$ ./mongo -u user_name -p user_password your_ip:your_port/admin
或
$ ./mongo -u user_name -p your_ip:your_port/admin #提示輸入密碼
一樣,在代碼中,數據庫鏈接串也同步變成了:
"MongoConnection": "mongodb://user_name:user_password@localhost:27017/admin?wtimeoutMS=2000"
通常來講,作完上面的安全處理,就能夠徹底知足生產環境的安全要求了。
再高的要求,能夠經過啓用TLS來強化。這會是另外一個文章。
微信公衆號:老王Plus 掃描二維碼,關注我的公衆號,能夠第一時間獲得最新的我的文章和內容推送 本文版權歸做者全部,轉載請保留此聲明和原文連接 |