关于MongoDB数据库未授权访问漏洞的解决方案

前两天云盾给了我一个漏洞警告,表示在服务器上的MongodDB存在未授权访问的漏洞。主要原因是因为默认安装完MongoDB后,都有一个空的admin数据库,即使启动时添加认证参数,也不存在任何权限验证,登录的用户可以通过MongodDB的默认端口无需密码对数据库任意操作,包括远程访问数据库,存在较大的安全隐患。

根据阿里云给的漏洞指南,主要有两种解决方法,我分别做了尝试:

(1) 在MongodDB的admin数据库中添加认证用户,并在启动MongodDB是添加认证参数(-auth)。

1
./mongod --dbpath=/var/mongodb/data --logpath=/var/mongodb/logs/log.log -auth -fork

我也这么做了,并且很快修复了漏洞。可新的问题也随之而来,当我再次启动nodejs时,连接MongodDB的node_model报错了。我采用了 mongodb 作为nodejs对于MongodDB的驱动,顺便吐槽一下,这个包名和数据库名字一样真有点蛋疼。。。。然后通过 connect-mongo 在mongodb中存储session,应该这两个模块访问MongodDB时都需要进行认证。

connect-mongo 需要在new MongoStore时设置url参数

1
2
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
example: mongodb://root:123456@localhost/test

mongodb new DB() 后db.open(‘collection’),用db.authenticate(‘username’,’password’)进行认证,这样就需要更改很多源码了。其实应该采用 class MongoClient,它就可以采用url格式进行连接,有时间用MongoClient重写一下吧,估计也不需要更改太多地方。

(2) 利用iptables,限制ip对MongoDB默认设置端口的访问。这里需要注意一下,CentOS7默认采用firewall作为防火墙,需要停止它并禁止开机启动。然后安装iptables,编辑配置文件

1
2
3
4
5
//只有本地可以访问27017端口
-A INPUT -s 127.0.0.1 -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
//禁止 TCP or UDP 对于27017端口的访问
-A INPUT -p tcp --dport 27017 -j DROP
-A INPUT -p udp --dport 27017 -j DROP

保存,重启防火墙即可。空的iptables是不做任何限制的,所以想禁止的端口务必要drop掉。iptables的执行顺序应该从上往下,遇到匹配规则就执行本规则,所以务必把 accept localhost 27017 放置于 drop all 27017 之前,不然本地的nodejs也会无法连接MongoDB。

参考资料

Configure Linux iptables Firewall for MongoDB

MongoDB数据库未授权访问漏洞

MongoDB安全配置