MongoDB的安全配置策略

上一次我写了一篇《Linux下安装MongoDB教程》介绍了Linux下如何安装与连接MongoDB教程,默认MongoDB启动后任何机器都能通过默认端口连接上,非常危险,如果来个恶意分子突然把你数据给remove那就哭死了。所以今天来说说MongoDB的安全配置。

MongoDB可以从以下几方面入手解决安全问题

添加用户验证

添加用户

在MongoDB中,用户权限是与库绑定的,需要注意。

添加一个用户

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo 192.168.6.42:27017
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test
> use test1
switched to db test1
> db.addUser('lee','pass')
{
  "user" : "lee",
  "readOnly" : false,
  "pwd" : "e6d78598d0bfe068a43e57a4bc82183f",
  "_id" : ObjectId("515942fa1f46044556f12069")
}
>

我们添加了一个lee的用户,密码为pass,其中有一个字段readOnly表示只读权限,如果字段值为false表示可以增删改读,如果字段值为true只能读取数据。

连接验证

添加用户后,我们可以重新连接看会不会提示输入用户名或其他的

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo 192.168.6.42:27017
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test
> use test1
switched to db test1
> db.test1.find()
{ "_id" : ObjectId("51593aff3ddfad42510c6c7b"), "name" : "lizhong" }
{ "_id" : ObjectId("51593b2f3ddfad42510c6c7c"), "name" : "lizhong8532" }
>

我们发现依然可以不需要用户名密码就能连接MongoDB,其实这里需要重启MongoDB,并且在启动参数加入-auth参数表示验证用户名与密码

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod -dbpath=/root/db -auth
Mon Apr  1 16:24:01.738 [initandlisten] MongoDB starting : pid=14561 port=27017 dbpath=/root/db 64-bit host=lee
Mon Apr  1 16:24:01.739 [initandlisten] db version v2.4.1
Mon Apr  1 16:24:01.739 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 16:24:01.739 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 16:24:01.739 [initandlisten] allocator: tcmalloc
Mon Apr  1 16:24:01.739 [initandlisten] options: { auth: true, dbpath: "/root/db" }
Mon Apr  1 16:24:01.771 [initandlisten] journal dir=/root/db/journal
Mon Apr  1 16:24:01.771 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 16:24:01.953 [initandlisten] waiting for connections on port 27017

客户端再重新空用户连接

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo 192.168.6.42:27017
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test
> use test1
switched to db test1
> db.test1.find()
error: { "$err" : "not authorized for query on test1.test1", "code" : 16550 }

发现能连接上,但查询test1库时提示错误,因为我们之前添加的lee用户是在test1库添加的,所以空用户名连接上服务器后对于需要验证用户名的库没有执行权限

我们使用lee用户登录服务器,如果密码错误会有以下错误提示

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u lee -p passs --port 27017
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test1
Mon Apr  1 16:50:20.153 JavaScript execution failed: Error: 18 { ok: 0.0, errmsg: "auth fails" } at src/mongo/shell/db.js:L228
exception: login failed

如果密码正确,则可以正常登录并可以操作一切

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u lee -p pass --port 27017 
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test1
> show tables
system.indexes
system.users
test1
> db.test1.find()
{ "_id" : ObjectId("51593aff3ddfad42510c6c7b"), "name" : "lizhong" }
{ "_id" : ObjectId("51593b2f3ddfad42510c6c7c"), "name" : "lizhong8532" }
> db.test1.save({'name':'xiaoli'})
> db.test1.find()
{ "_id" : ObjectId("51593aff3ddfad42510c6c7b"), "name" : "lizhong" }
{ "_id" : ObjectId("51593b2f3ddfad42510c6c7c"), "name" : "lizhong8532" }
{ "_id" : ObjectId("51594adfe74e32e5b6e3431e"), "name" : "xiaoli" }
>

如果用户的readOnly为true那么这个用户只能读取数据,添加一个readOnly用户zhansan

> db.addUser('zhansan','pass',true)
{
  "user" : "zhansan",
  "readOnly" : true,
  "pwd" : "a75df6791f2b0cd2d2913319bfcc042a",
  "_id" : ObjectId("51594b82e74e32e5b6e3431f")
}
> db.system.users.find()
{ "_id" : ObjectId("515942fa1f46044556f12069"), "user" : "lee", "readOnly" : false, "pwd" : "e6d78598d0bfe068a43e57a4bc82183f" }
{ "_id" : ObjectId("51594b82e74e32e5b6e3431f"), "user" : "zhansan", "readOnly" : true, "pwd" : "a75df6791f2b0cd2d2913319bfcc042a" }
>

使用zhansan登录并且添加数据,提示:not authorized for insert on test1.test1

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u zhansan -p pass --port 27017   
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test1
> db.test1.save({'name':'laoliu'})
not authorized for insert on test1.test1
> db.test1.find()
{ "_id" : ObjectId("51593aff3ddfad42510c6c7b"), "name" : "lizhong" }
{ "_id" : ObjectId("51593b2f3ddfad42510c6c7c"), "name" : "lizhong8532" }
{ "_id" : ObjectId("51594adfe74e32e5b6e3431e"), "name" : "xiaoli" }
> 

删除用户

当然,用户可以添加,也可以删除

删除zhansan用户

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u lee -p pass --port 27017       
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test1
> db.system.users.remove({user:"zhansan"})
> db.system.users.find()
{ "_id" : ObjectId("515942fa1f46044556f12069"), "user" : "lee", "readOnly" : false, "pwd" : "e6d78598d0bfe068a43e57a4bc82183f" }
>

再使用zhansan用户登录提示验证失败

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u zhansan -p pass --port 27017   
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:27017/test1
Mon Apr  1 17:00:38.194 JavaScript execution failed: Error: 18 { ok: 0.0, errmsg: "auth fails" } at src/mongo/shell/db.js:L228
exception: login failed
[root@DELL113 mongodb-linux-i686-2.4.1]#

更改端口

MongoDB默认启动的端口是27017,其实很多程序都有默认端口比如ftp、ssh、memcache等等,更改默认端口是安全策略中不可缺少的一部。

MongoDB其实在启动的时候,加入监听端口号即可,当然最好这个端口好不要被占用。

监听8532端口

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod -dbpath=/root/db --auth --port 8532
Mon Apr  1 17:04:21.353 [initandlisten] MongoDB starting : pid=14633 port=8532 dbpath=/root/db 64-bit host=lee
Mon Apr  1 17:04:21.354 [initandlisten] db version v2.4.1
Mon Apr  1 17:04:21.354 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 17:04:21.354 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 17:04:21.354 [initandlisten] allocator: tcmalloc
Mon Apr  1 17:04:21.354 [initandlisten] options: { auth: true, dbpath: "/root/db", port: 8532 }
Mon Apr  1 17:04:21.369 [initandlisten] journal dir=/root/db/journal
Mon Apr  1 17:04:21.369 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 17:04:21.503 [websvr] admin web console waiting for connections on port 9532
Mon Apr  1 17:04:21.503 [initandlisten] waiting for connections on port 8532

用户端按8532端口连接

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo test1 --host 192.168.6.42 -u lee -p pass --port 8532
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:8532/test1
>

同一个服务器,可以运行多个MongoDB进程监听不同的端口,但要注意制定--dbpath数据库路径与--logpath路径不能与其他正在运行的进程冲突

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod --dbpath=/root/db1 --port 8533       
Mon Apr  1 17:14:12.322 [initandlisten] MongoDB starting : pid=14696 port=8533 dbpath=/root/db1 64-bit host=lee
Mon Apr  1 17:14:12.322 [initandlisten] db version v2.4.1
Mon Apr  1 17:14:12.322 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 17:14:12.322 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 17:14:12.322 [initandlisten] allocator: tcmalloc
Mon Apr  1 17:14:12.322 [initandlisten] options: { dbpath: "/root/db1", port: 8533 }
Mon Apr  1 17:14:12.338 [initandlisten] journal dir=/root/db1/journal
Mon Apr  1 17:14:12.338 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 17:14:12.599 [websvr] admin web console waiting for connections on port 9533
Mon Apr  1 17:14:12.600 [initandlisten] waiting for connections on port 8533
Mon Apr  1 17:14:18.854 [initandlisten] connection accepted from 192.168.4.86:46289 #1 (1 connection now open)

客户端连接8533端口

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo 192.168.6.42:8533
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42:8533/test
> show dbs
local   0.078125GB
>

IP限制

IP限制几乎是所有互联网安全策略的最后一道墙了。

我们绑定一个IP 127.0.0.1运行

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod -dbpath=/root/db --auth --port 8532 --bind_ip 127.0.0.1
Mon Apr  1 17:22:16.534 [initandlisten] MongoDB starting : pid=14713 port=8532 dbpath=/root/db 64-bit host=lee
Mon Apr  1 17:22:16.535 [initandlisten] db version v2.4.1
Mon Apr  1 17:22:16.535 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 17:22:16.535 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 17:22:16.535 [initandlisten] allocator: tcmalloc
Mon Apr  1 17:22:16.535 [initandlisten] options: { auth: true, bind_ip: "127.0.0.1", dbpath: "/root/db", port: 8532 }
Mon Apr  1 17:22:16.541 [initandlisten] journal dir=/root/db/journal
Mon Apr  1 17:22:16.541 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 17:22:16.664 [websvr] admin web console waiting for connections on port 9532
Mon Apr  1 17:22:16.664 [initandlisten] waiting for connections on port 8532

使用本机连接

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod --dbpath=/root/db --bind_ip 127.0.0.1
Mon Apr  1 17:35:38.128 [initandlisten] MongoDB starting : pid=14829 port=27017 dbpath=/root/db 64-bit host=lee
Mon Apr  1 17:35:38.128 [initandlisten] db version v2.4.1
Mon Apr  1 17:35:38.128 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 17:35:38.128 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 17:35:38.128 [initandlisten] allocator: tcmalloc
Mon Apr  1 17:35:38.128 [initandlisten] options: { bind_ip: "127.0.0.1", dbpath: "/root/db" }
Mon Apr  1 17:35:38.133 [initandlisten] journal dir=/root/db/journal
Mon Apr  1 17:35:38.133 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 17:35:38.265 [initandlisten] waiting for connections on port 27017
Mon Apr  1 17:35:38.266 [websvr] admin web console waiting for connections on port 28017
Mon Apr  1 17:36:54.385 [initandlisten] connection accepted from 127.0.0.1:30636 #1 (1 connection now open)

使用别的机器连接提示连接失败

[root@DELL113 mongodb-linux-i686-2.4.1]# ./bin/mongo 192.168.6.42
MongoDB shell version: 2.4.1
connecting to: 192.168.6.42/test
Mon Apr  1 17:38:34.171 JavaScript execution failed: Error: couldn't connect to server 192.168.6.42:27017 at src/mongo/shell/mongo.js:L114
exception: connect failed

绑定其它IP

[root@lee mongodb-linux-x86_64-2.4.1]# ./bin/mongod --dbpath=/root/db --bind_ip 192.168.4.86
Mon Apr  1 17:52:57.127 [initandlisten] MongoDB starting : pid=15031 port=27017 dbpath=/root/db 64-bit host=lee
Mon Apr  1 17:52:57.128 [initandlisten] db version v2.4.1
Mon Apr  1 17:52:57.128 [initandlisten] git version: 1560959e9ce11a693be8b4d0d160d633eee75110
Mon Apr  1 17:52:57.128 [initandlisten] build info: Linux ip-10-2-29-40 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_49
Mon Apr  1 17:52:57.128 [initandlisten] allocator: tcmalloc
Mon Apr  1 17:52:57.128 [initandlisten] options: { bind_ip: "192.168.4.86", dbpath: "/root/db" }
Mon Apr  1 17:52:57.145 [initandlisten] journal dir=/root/db/journal
Mon Apr  1 17:52:57.145 [initandlisten] recover : no journal files present, no recovery needed
Mon Apr  1 17:52:57.388 [initandlisten] preallocateIsFaster=true 2.16
Mon Apr  1 17:52:57.583 [initandlisten] ERROR: listen(): bind() failed errno:99 Cannot assign requested address for socket: 192.168.4.86:27017
Mon Apr  1 17:52:57.583 [initandlisten] now exiting
Mon Apr  1 17:52:57.583 dbexit: 
Mon Apr  1 17:52:57.583 [initandlisten] shutdown: going to close listening sockets...
Mon Apr  1 17:52:57.583 [initandlisten] shutdown: going to flush diaglog...
Mon Apr  1 17:52:57.583 [initandlisten] shutdown: going to close sockets...
Mon Apr  1 17:52:57.584 [initandlisten] shutdown: waiting for fs preallocator...
Mon Apr  1 17:52:57.584 [initandlisten] shutdown: lock for final commit...
Mon Apr  1 17:52:57.584 [initandlisten] shutdown: final commit...
Mon Apr  1 17:52:57.588 [websvr] ERROR: listen(): bind() failed errno:99 Cannot assign requested address for socket: 192.168.4.86:28017
Mon Apr  1 17:52:57.592 [initandlisten] shutdown: closing all files...
Mon Apr  1 17:52:57.592 [initandlisten] closeAllFiles() finished
Mon Apr  1 17:52:57.592 [initandlisten] journalCleanup...
Mon Apr  1 17:52:57.592 [initandlisten] removeJournalFiles
Mon Apr  1 17:52:57.595 [initandlisten] shutdown: removing fs lock...
Mon Apr  1 17:52:57.595 dbexit: really exiting now
[root@lee mongodb-linux-x86_64-2.4.1]#

出错,不知道为什么?目前正在找问题中。。。

虽然在bind_ip 192.168.4.86后面加上其它端口号能成功运行,但发现bind_ip参数不能阻止其它非指定ip的连接。

其实在绑定IP这一块可以借助iptables完成,iptables还可以指定范围!

分享

TITLE: MongoDB的安全配置策略

LINK: https://www.qttc.net/299-mongodb-security-policy.html

NOTE: 原创内容,转载请注明出自琼台博客