上週寫了個簡短的新聞《MongoDB裸奔,2億國人求職簡歷洩漏!》:
根據安全站點HackenProof的報告,由於MongoDB資料庫沒有采取任何安全保護措施,導致共計202,730,434份國人求職簡歷洩漏。
然後很多人評論說MongoDB躺槍了。
MongoDB確實躺槍了,因為這事的責任當然不在資料庫,而在於使用資料庫的人沒有做必要的安全配置。
那麼我們應該如何保證MongoDB的安全性?下面我將介紹保護MongoDB的3個簡單的方法:
- 繫結區域網IP,杜絕網際網路訪問
- 配置防火牆,保護27017埠
- 配置賬號密碼,對資料庫進行訪問控制
本教程所使用的系統配置如下:
- Ubuntu 16.04
- mongodb 4.0.5
Ubuntu 16.04安裝MongoDB
參考MongoDB文件:Install MongoDB Community Edition on Ubuntu
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org=4.0.5 mongodb-org-server=4.0.5 mongodb-org-shell=4.0.5 mongodb-org-mongos=4.0.5 mongodb-org-tools=4.0.5
sudo service mongod start
複製程式碼
1. 繫結區域網IP,杜絕網際網路訪問
話說MongoDB被黑了這麼多年,自身確實有一定的責任。版本3.6之前,MongoDB預設繫結的居然是0.0.0.0,這就意味著我們可以通過網際網路訪問MongoDB,那黑客當然也可以。這樣的預設配置是一個很大的安全漏洞,很多MongoDB初學者都栽在這一點。關於這個問題,MongoDB的文件說得很委婉:
Default Bind to Localhost
Starting with MongoDB 3.6, MongoDB binaries, mongod and mongos, bind to localhost by default. From MongoDB versions 2.6 to 3.4, only the binaries from the official MongoDB RPM (Red Hat, CentOS, Fedora Linux, and derivatives) and DEB (Debian, Ubuntu, and derivatives) packages would bind to localhost by default.
也就是說,從3.6開始,MongoDB預設繫結localhost,這就意味著我們只能在本機訪問MongoDB。至於2.6到3.4,只有從MongoDB RPM與DEB下載的安裝包才預設繫結localhost,換句話說,其他方式下載的安裝包則預設繫結0.0.0.0。因此,如果你使用的MongoDB是3.6之前的版本,就要特別注意這一點了。
在開發環境下,MongoDB繫結localhost沒毛病。但是,在生產環境下,我們通常會有多個節點,這時需要修改MongoDB繫結的IP,通過配置net.bindIp可以實現。
如果為了省事,直接把net.bindIp配置為0.0.0.0,那就不太妙了。正確的做法應該是繫結區域網IP,這樣只有區域網內的節點可以訪問MongoDB。除非黑客端掉了你的伺服器,否則他是沒法訪問你的MongoDB的。
哪些IP是區域網的呢?按照標準,有下面這些網段:
- 10.0.0.0 – 10.255.255.255
- 172.16.0.0 – 172.31.255.255
- 192.168.0.0 – 192.168.255.255
最常用的區域網網段就是192.168.0.0到192.168.255.255了。
修改MongoDB的配置檔案
vim /etc/mongod.conf
複製程式碼
將net.bindIp設為區域網IP地址192.168.59.99:
net:
port: 27017
bindIp: 192.168.59.99
複製程式碼
重啟MongoDB
sudo service mongod restart
複製程式碼
2. 配置防火牆,保護27017埠
MongoDB預設使用的是27017埠,我們應該配置本地防火牆把這個埠保護起來,禁止外部IP訪問。
在MongoDB繫結0.0.0.0,且沒有配置防火牆的情況下,使用nmap命令遠端掃描27017埠,結果如下:
nmap -p 27017 113.207.35.149
Starting Nmap 6.49BETA3 ( https://nmap.org ) at 2019-01-19 14:17 CST
Nmap scan report for 113.207.35.149
Host is up (0.042s latency).
PORT STATE SERVICE
27017/tcp open mongod
Nmap done: 1 IP address (1 host up) scanned in 14.34 seconds
複製程式碼
可知,27017埠是"open"的,這就意味著我們可以遠端訪問MongoDB資料庫。
配置UFW防火牆
Ubuntu上預設的防火牆軟體是UFW,配置起來非常簡單。預設情況下,ufw並沒有啟用:
sudo ufw status
Status: inactive
複製程式碼
執行以下命令,即可配置ufw規則,並啟動防火牆:
sudo ufw default deny incoming // 預設禁止訪問本機所有埠
sudo ufw default allow outgoing // 允許本機訪問外部網路
sudo ufw allow 22/tcp // 允許SSH登陸
sudo ufw allow from 192.168.59.100 to any port 27017 // 僅允許區域網內IP為192.168.59.100的伺服器訪問mongodb
sudo ufw enable
複製程式碼
我所配置的規則也非常容易理解,根據命令就能看出來。這時,再檢視ufw的狀態,可以發現防火牆已經啟用了:
sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
27017 ALLOW 192.168.59.100
22/tcp (v6) ALLOW Anywhere (v6)
複製程式碼
這時,再使用nmap命令遠端掃描27017埠,結果如下:
nmap -p 27017 113.207.35.149
Starting Nmap 6.49BETA3 ( https://nmap.org ) at 2019-01-19 14:40 CST
Nmap scan report for 113.207.35.149
Host is up (0.053s latency).
PORT STATE SERVICE
27017/tcp filtered mongod
Nmap done: 1 IP address (1 host up) scanned in 13.68 seconds
複製程式碼
可知,27017埠的狀態為"filtered",已經被防火牆保護起來了,更加安全。
Linux上常用的防火牆工具還有iptables,這裡就不再贅述了。
另外,雲伺服器都支援配置防火牆,也有必要配置一下,它們與本機的防火牆是獨立的,可以共同來保證資料庫的安全。
3. 配置賬號密碼,對資料庫進行訪問控制
預設情況下,MongoDB並沒有配置賬號和密碼,黑客只要登陸你的伺服器之後可以直接檢視資料庫。給MongoDB配置賬號密碼,可以有效解決這個問題。
連線mongodb
mongo
複製程式碼
配置賬號密碼
賬號為"myUserAdmin",密碼為"abc123"。
use admin
db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)
複製程式碼
修改MongoDB的配置檔案
vim /etc/mongod.conf
複製程式碼
將security.authorization設為"enabled":
security:
authorization: enabled
複製程式碼
重啟MongoDB
sudo service mongod restart
複製程式碼
連線mongodb
再次連線mongodb時,則需要指定賬號與密碼。
mongo -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"
複製程式碼
如果不提供賬號密碼,則無法檢視資料庫,會出現如下這種錯誤:
show dbs
2019-01-20T22:13:53.477+0800 E QUERY [js] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "command listDatabases requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
複製程式碼
另外,MongoDB還支援配置多個許可權不同的賬號,針對性地對特定資料庫的讀寫許可權進行配置。這樣更加細緻的訪問控制可以增強安全性,舉個不太恰當的例子,對於團隊中的實習生,應該只給他們讀許可權,這樣可以有效防止出現誤操作導致刪庫等極端情況。
總結
可以發現,本文介紹的方法都非常簡單,屬於常識,但是都是必要的。作為資料庫管理者,如果這些都沒有配置,那顯然是非常不專業的,責怪MongoDB也沒有用,因為換個資料庫也會有同樣的問題。
根據MongoDB文件提供的Security Checklist,我們還可以使用TLS/SSL來加密MongoDB連線,這樣做會在一定程度上犧牲效能,大家可以根據需要來配置。
另外,保證資料庫的訪問安全非常重要,同時也需要保證資料的安全性,做好必要的資料備份。關於如何保護資料的安全性,可以參考我們的部落格《Fundebug是這樣備份資料的》。
參考
關於Fundebug
Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,付費客戶有Google、360、金山軟體、百姓網等眾多品牌企業。歡迎大家免費試用!
版權宣告
轉載時請註明作者Fundebug以及本文地址: blog.fundebug.com/2019/01/21/…