部署有身份验证的mongoDB

mongoDB默认情况下是不需要身份认证的,但是处于生产环境安全的考虑,还是不能省去这一步的。本文将在这篇文章所述环境下部署带身份认证的mongoDB双副本集系统,具体内容包括了:

  • 配置用户和身份验证
  • 配置内部验证到副本集
  • mongo-connector的验证方法

1. 配置用户和身份认证

Web开发中,确保系统的安全也是后端开发任务之一。而确保mongoDB安全的最好方法就是在一个可信环境中运行实例,并且确保只有可信机器能过连接到服务器。在当前开发环境下,我们还需要远程连接数据库,所以不太适合选择绑定ip等方式来限制网络访问。但我们可以通过验证和授权的方式来提供安全可靠的数据库使用。monogDB提供的验证机制有很多种,我们使用的2.6版本采用MONGODB-CR机制,该机制通过用户名、密码和验证数据库来识别用户。而授权方面,mongoDB采用的是基于角色的访问控制(Role-Based Access Control, RBAC)。一个角色被授予针对数据库、集合、集群相应的权限,使得该角色能够针对资源进行操作。需要注意的是,除了在admin数据库,设置权限的用户角色只能作用于该用户所在的数据库。这些都是验证的依据原理,下面才是描述如何配置身份验证。

我们首先配置用户信息,然后再运行开启访问控制功能的mongod实例。mongoDB提高db.createUser()和db.updateUser()等方法来管理用户。顾名思义,db.createUser()提供创建数据库用户的功能,其第一个参数为用户对象,第二个参数为write Concern(指定写操作的确认方式)。我们需要从第一个参数定义user(用户名)、pwd(密码)、roles(角色)字段,并可以从中定义customData(自定义数据)字段。用户角色分为mongoDB内建角色和用户定义角色。内建角色又分为数据库用户角色和数据库管理角色,可以通过官网看到详细信息

针对当前应用的环境,我们需要readWrite角色来读取数据集合,userAdmin角色来管理用户信息,clusterAdmin角色来管理分片、副本集群,dbAdmin角色来管理数据库。我们首先在无访问控制的情况下运行mongoDB来创建用户。在shell中输入如下命令(注意密码的设置)即可创建不同角色的用户,其中clusterAdmin还需指定针对config、local数据库的权限。这里之所以使用了AnyDatabase是处于方便操作全体数据库,在生产环境应该严格限制作用的数据库。

use admin
db.createUser({ user: "gossip", pwd: "yourpassword", roles: [ "readWriteAnyDatabase" ]})
db.createUser({ user: "dbAdmin", pwd: "yourpassword", roles: [ "dbAdminAnyDatabase" ]})
db.createUser({ user: "clusterAdmin", pwd: "yourpassword", roles: [ "clusterAdmin", { role: "read", db: "config" }, { role: "read", db: "local"} ]})
db.createUser({ user: "superuser", pwd: "yourpassword", roles: [ "userAdminAnyDatabase" ]})

建立好这3个用户后,可以通过show users来检查用户设置的正确性。最后通过重启mongoDB来应用访问控制,输入命令 mongod admin --auth 来限定需要验证才能成功连接数据库。

而验证连接数据库的目录参数如下, mongo --port 27001 admin -u username -p 。其表示连接admin数据库来验证username用户,接下来再输正确的密码即进入mongo shell。

2. 配置内部验证到副本集

当在多节点环境(副本、分片)下启用身份验证时,mongoDB强制副本成员必要提供节点间验证的凭证才能相互通信。我们采用keyfile(使用SCRAM-SHA-1的验证机制)来进行内部验证。文档中采用的方法是生产一个较长的随机数来充当密码,不同节点直接需要相互验证这个密码文件。这里使用官网的方法,使用openssl命令的方法来生产随机数,并以文件形式保存。并将生成的文件提供给各个节点即可。具体命令如下:

# open rand -base64 741 > /opt/mongo-keyfile` 
# chmod 600 mongo-keyfile
# mongod --keyfile /opt/mongo-keyfile

如果我们不进行内部验证会出现什么情况呢?当我们直接采用-auth启动两个副本时,mongoDB副本会一直处于recovering的状态,无法正常工作。

3. mongo-connector的验证方法

mongo-connector工具可以实时从oplog中获取数据库的变动并通过pipiline的方式传递给其他系统,比如solr搜索引擎之类的系统。mongo-connector支持mongoDB所有的验证机制,并提供多种验证方式。简单的可以通过自身的参数来进行验证,但这种方法下,密码参数是可见的,使用ps命令就可以看到。在生产环境推荐使用其他方式,比如通过密码文件的方式。命令直接验证的参数为 --admin-username <administrator username> --password <administrator password>

当然,在实际使用中我们针对针对不同的需求,添加mongo-connector使用的用户角色的修改。具体如下图:

在我们的系统中直接将mongo-connector可能需要的权限全部提供,整个系统当前的用户角色信息如下图:


参考:

  1. mongoDB安全认证

  2. 配置副本集的身份验证

  3. mongo-connector

  4. 官方3.*文档

  5. 书籍:《mongoDB权威指南》。