写这篇博客是为了纪念最近闹的沸沸扬扬的大规模mongodb库被黑的事件,我自己也不幸中招,索性被黑的数据都是自己做试验的一些数据,并不是很重要。

可能是mongodb为了让人更加容易上手,默认情况下不用验证就可以操作数据库。但是如果想要确保自己mongodb的安全,可以通过多种方式来实现。 其中最简便的是通过用户名和密码来验证。

新增用户

在对mongodb增加验证使用之前,需要增加一个admin用户:

1
2
3
4
5
6
7
8
9
./bin/mongo
use admin
db.createUser(
  {
    user: "admin",
    pwd: "abc@123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

上边这段命令指的是在admin库中增加管理员admin用户,他的密码是abc@123。有了admin账户之后,可以增加其他的用户:

1
2
3
4
5
6
7
8
db.createUser(
  {
    user: "eclipse",
    pwd: "abc@123",
    roles: [ { role: "readWrite", db: "Douyudata" },
             { role: "readWrite", db: "Pandata" } ]
  }
)

而上边这些命令就是对具体操作数据库的用户:创建用户eclipse,密码abc@123,拥有对库Douyudata和Pandata的读写权限。 新增用户之后,可以在mongodb在启动的时候,通过加入–auth参数即可启动安全验证功能。例如:./bin/mongod --dbpath ./db --auth

shell操作

在通过上边的命令运行mongod之后,使用./bin/mongo打开shell连接mongodb。 连接之后看下数据库列表:

1
2
3
4
5
6
7
> show dbs
2017-02-17T11:09:43.539+0800 E QUERY    [main] Error: listDatabases failed:{
	"ok" : 0,
	"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
	"code" : 13,
	"codeName" : "Unauthorized"
}

发现已经受到mongodb权限认证机制的保护。 先用admin登录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
> use admin
switched to db admin
> db.auth('admin','abc@123')
1
> show dbs
Douyu        0.180GB
Douyudata    0.001GB
admin        0.000GB
lagou        0.000GB
local        0.000GB
test         0.000GB
userManager  0.001GB

需要注意的是,这个admin目前只是个用户管理员的角色,他对具体的数据库没有读写权限:

1
2
3
4
5
6
7
8
9
> use Douyu
switched to db Douyu
> show tables
2017-02-17T11:15:17.279+0800 E QUERY    [main] Error: listCollections failed: {
	"ok" : 0,
	"errmsg" : "not authorized on Douyu to execute command { listCollections: 1.0, filter: {} }",
	"code" : 13,
	"codeName" : "Unauthorized"
}

如果要向对数据库进行读写,需要切换到对应的用户:

1
2
3
4
5
6
7
8
9
> use admin
switched to db admin
> db.auth('eclipse','abc@123')
1
> use Douyudata
switched to db Douyudata
> show tables
Catalog
Roominfo

pymongo中的认证方法

我一般使用pymongo来连接mongodb,通过pymongo连接的方式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import os
from pymongo import MongoClient
class DB(object):
    """docstring for DB"""
    def __init__(self, host='localhost', port=27017):
        self.cli = MongoClient(host=host, port=port)
    def switch_db(self, database):
        '''
        切换到目标数据库,并进行权限验证
        '''
        if database and isinstance(database, str):
            name = os.getenv('mongo_name')
            pasw = os.getenv('mongo_pswd')
            authdb = self.cli['admin']
            try:
                authdb.authenticate(name=name, password=pasw)
            except Exception as e:
                print("Erro accured during db authenticate:{}".format(str(e)))
            self.db = self.cli[database]