Mongodb的安全模式默认是关闭,此时它需要在一个可信任的运行环境中。
在可信任的环境中使用默认的关闭安全模式最简单,但是需要确保可信任的设备访问数据库的TCP端口,
这通常需要隔离数据库所在设备,使其完全无法访问外部网络。
确保网络安全
防火墙策略
以下是数据库必须的默认端口:(sina博客的编辑器很操蛋,表格搞不过来)
参见: http://www.mongodb.org/display/DOCS/Security+and+Authentication#SecurityandAuthentication-RunninginaTrustedEnvironment(without\auth)1, 在分片式环境中
a,集群中的所有的mongodb进程(mongos, mongod, mongod--configsvr)应该是能相互连接的。
b,客户端必须能够连接到mongos进程,但是,它们可以从mongod被阻塞。
2,在非分片式副本环境中
a,所有客户端必须能连接所有非隐藏的副本集成员。
b,副本集的所有成员(mongod进程)需要能够相互通信。
IP 地址绑定
默认情况下,mongod服务器将监听设备上所有可用的IP地址。可以在mongod的"bind_ip"配置项中限制监听的IP地址。
TCP端口号
mongodb默认监听下列端口号:
独立mongod服务:27017
mongos服务: 27017
分片服务(mongod --shardsvr): 27018
配置服务(mongod --configsvr):27019
mongod的网站统计页面端口:通常是28017,即独立mongod服务端口号加1000, 可以用 --nohttpinterface 命令行参数禁止统计页面。
以上端口可以更改但不推荐。
在安全模式下运行(使用 --auth 或者 --keyFile)
mongodb支持身份验证和简单的粗粒度访问控制的"安全模式". 可以通过 --anth和--keyFile命令行参数启用。
一个通过用户名密码认证的特定数据库,一旦通过认证,普通用户能够完全读写数据库。还可以创建只读用户,使其只有读取权限。
admin数据库是一个特殊的库。一些管理命名只能在admin数据库运行(所以只能由admin运行)。
当然,用户能访问admin数据库也能读写在服务或集群中的其他数据库。
注意:即使使用安全模式,也应该设置合理的防火墙策略。
admin身份登录
虽然通常admin账号能访问服务器上的任何数据库,但是必须先使用admin账号登录admin数据库,再use其他数据库,下面的登陆将会成功:
> use admin > db.auth("someAdminUser", password) > // and then if desired switch databases: > use test
下面这个登陆将会失败:
> use test
> db.auth("someAdminUser", password)
启用安全模式
要启用安全模式必须要1,在使用 --auth启动服务前为admin db添加了一个用户。
或2,从本地连接(localhost connection)添加第一个用户(如果不能添加用户,那应该是非本地连接)。
配置
首先要为数据库进程创建一个管理员账户,此用户保存在特殊的admin数据库中。
如果没有admin账户,可以从本地连接访问数据库而不需要验证。因此可以在数据库所在主机运行数据库shell和配置数据库:
$ mongo localhost/admin > // we are using database admin > db.addUser("theadmin", "anadminpassword")
现在创建了一个管理员账户。现在必须要经过验证才能使用:
假如用户已经存在,在shell中执行addUser命令能够更新密码。
一些mongodb驱动也提供了类似shell中addUser的方法。
删除账户
shell中执行
> db.auth("theadmin", "anadminpassword")
现在我们可以为其他数据库配置非管理员账户:
> // give joe read/write access to the projectx database > use projectx > db.addUser("joe", "passwordForJoe")
添加只读账户(1.4+):
修改密码
> use projectx > db.addUser("guest", "passwordForGuest", true)
查看用户列表:
用户信息存储在每个数据库的system.users集合。例如数据库projectX中的用户存储在projectX.system.users集合。
> db.system.users.find()
> db.removeUser( username ) > // or > db.system.users.remove( { user: username } ) > // check it worked: > db.system.users.find() > // check we are on the db we intended: > db
分片式集群和副本集的安全模式
注意:在集群及副本集环境中必须使用keyFile参数,只使用--auth参数将无法工作。
2.2以下的版本不支持集群环境下的只读用户。
客户端在集群中进行认证与在单服务器环境中的认证是一样的,唯一的区别是集群中服务器使用密钥文件进行内部沟通。
密钥文件基本上是一个明文的文件,hash计算后被当做集群的内部密码。
设置副本集 and/or 分片的验证:
a,创建key文件并复制到集合的每个服务器中。密钥文件是字符的base64集,加上空格与换行符。
b,修改密钥文件权限为只能被当前用户读取。
c,启动集群中的服务器时使用命令行参数 --keyFile /path/to/file
d,客户端都必须验证和才能使用
启动时可以不使用 --auth参数,因为使用了 --keyFile就必须验证,也就是隐含了 --auth。但是--auth并不隐含 --keyFile。
密码文件
密钥文件必须至少包含6个base64字符并且不大于1K(B包括空格)。
空格字符将被去除,所以对数据库来说,下面的密钥文件是一样的:
$ echo -e "my secret key" > key1 $ echo -e "my secret key\n" > key2 $ echo -e "my secret key" > key3 $ echo -e "my\r\nsecret\r\nkey\r\n" > key4