根据安全站点HackenProof的报告,因为MongoDB数据库没有采起任何安全保护措施,致使共计202,730,434份国人求职简历泄漏。java
而后不少人评论说MongoDB躺枪了。mongodb
MongoDB确实躺枪了,由于这事的责任固然不在数据库,而在于使用数据库的人没有作必要的安全配置。shell
那么咱们应该如何保证MongoDB的安全性?下面我将介绍保护MongoDB的3个简单的方法:数据库
本教程所使用的系统配置以下:ubuntu
Ubuntu 16.04安装MongoDBvim
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 |
话说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是局域网的呢?按照标准,有下面这些网段:
最经常使用的局域网网段就是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 |
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数据库。
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,这里就再也不赘述了。
另外,云服务器都支持配置防火墙,也有必要配置一下,它们与本机的防火墙是独立的,能够共同来保证数据库的安全。
默认状况下,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链接,这样作会在必定程度上牺牲性能,你们能够根据须要来配置。
欢迎学Java和大数据的朋友们加入java架构交流: 855835163 群内提供免费的架构资料还有:Java工程化、高性能及分布式、高性能、深刻浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的免费直播讲解 能够进来一块儿学习交流哦