2018/07 作者:ihunter 0 次 0
一、关于权限的默认配置
在默认情况下,mongod是监听在0.0.0.0之上的,任何客户端都可以直接连接27017,且没有认证。这样做的好处是,用户可以即时上手,不用担心被一堆配置弄的心烦意乱。然而坏处也是显而易见,如果直接在公网服务器上如此搭建MongoDB,那么所有人都可以直接访问并修改数据库数据了。
默认情况下,mongod也是没有管理员账户的。因此除非你在admin数据库中使用db.addUser()命令添加了管理员帐号,且使用–auth参数启动mongod,否则在数据库中任何人都可以无需认证执行所有命令。包括delete和shutdown。
此外,mongod还会默认监听28017端口,同样是绑定所有ip。这是一个mongod自带的web监控界面。从中可以获取到数据库当前连接、log、状态、运行系统等信息。如果你开启了–rest参数,甚至可以直接通过web界面查询数据,执行mongod命令。
其实MongoDB本身有非常详细的安全配置准则,显然开发者也是想到了,然而他是将安全的任务推给用户去解决,这本身的策略就是偏向易用性的,对于安全性,则得靠边站了。
二、MongoDB用户类型
MongoDB的用户分为两种,一种是admin用户,另一种是特定数据库用户。admin用户拥有最高的权限,而特定数据库用户则只能访问特定的数据库。当MongoDB的admin库里没有任何用户的时候,也就是说整个MongoDB没有一个MongoDB用户的时候,即便–auth权限需求打开了,用户还是可以通过localhost界面进入MongoDB进行用户设置,否则的话整个MongoDB就完全没法访问了。而当这个用户创建完成之后,之后的用户登录和操作就需要授权了,不是直接登录就能使用的了。
MongoDB有一个比较奇怪的设置是,即便是一个admin用户,授权也必须在admin数据库下进行,而不能在其他数据库下进行。而授权之后admin用户就可以在任何数据库下进行任何操作了。当然数据库级别的用户在他自己的数据库下授权之后是不能到其他数据库进行操作的。举例来说:
> use test
> db.auth(“someAdminUser”, password)
操作失败,提示还没有在admin数据库下对afmin用户进行授权。
三、操作实例
启动MongoDB,在cmd命令框里进入数据库的bin目录;
1. 输入命令:show dbs,你会发现它内置有两个数据库,一个名为admin,一个名为local;本文只对admin库进行描述
2. 输入命令:use admin,你会发现该DB下包含了一个名为system.user的collection,这是用户表,用来存放超级管理员的
备注:本文使用的数据库版本是2.0.1,没有默认的admin数据库,但是在执行第二步之后自动创建了一个admin库; 当然也没有默认的system.user表,运行后面的第三步后会自动创建 system.user和system.indexes )
3. 输入命令:db.addUser('root','root'),这里我添加一个超级管理员用户,username为root,password也为root。先退出 (ctrl+c)程序,测试重启服务后再次连接MongoDB是否需要按提示输入用户名、密码进行操作。
4. 输入命令:use admin
5. 输入命令:show collections,查看该库下所有的表,你会发现,MongoDB并没有提示你输入用户名、密码,原因是,在文章最开始提到了,MongoDB默认设置为无权限访问限制,我们需要先把它设置成为需要权限访问
6.从新打开cmd,在mongodb路径的bin目录下,执行mongod --dbpath d:\work\data\mongodb\db --auth
7. 输入命令:use admin
8. 输入命令:show collections,提示:"$err" : "unauthorized db:admin lock type:-1 client:127.0.0.1"
显然,已经提示没有权限;用刚才设置的用户名、密码来访问集合
9. 输入命令:db.auth(“root”,”root”),输出一个结果值为1,说明这个用户匹配上了,如果用户名、密码不对,输出为0
10. 输入命令:show collections,将成功显示结果
继续操作,可以访问已经存在的数据库,但对于新建的数据库仍然没有权限;继续操作,先退出(ctrl+c)服务
11. 输入命令:mongo TestDB
12. 输入命令:show collections,提示:没有权限
13. 输入命令:db.auth(“root”, “root”),输出结果为0,说明用户名或者密码有问题,刚刚前面才创建,怎么会不对呢?原因在于:当我们单独访问MongoDB的数据库时,需要权限访问的情况下,用户名密码并非超级管理员,而是该库的system.user表中的用户,注意,我这里说的是单独访问的情况,什么是不单独访问的情况呢?后面再讲。针对上述情况,接下来操作:
14. 输入命令:db.addUser('test','111111'),仍然提示没有权限,新的数据库使用超级管理员也无法访问,创建用户也没有权限,不过即然设定了超级管理员用户,那它就一定有权限访问所有的库
15. 输入命令:use admin
16. 输入命令:db.auth(“root”, “root”)
17. 输入命令:use TestDB
18. 输入命令:show collections,之后可以利用超级管理员用户访问其它库了,这个就是不单独访问的情况。在上述操作过程中,我们是先进入admin库,再转到其它库来的,admin相当于是一个最高级别用户所在的区域,对数据库操作,需要经过最高级别用户,之后可以创建每个数据库的用户。
19. 输入命令:db.addUser('test','12345'),我们给TestDB库添加一个用户,以后每次访问该库,我都使用刚刚创建的这个用户,我们先退出(ctrl+c)
20. 输入命令:mongo TestDB
21. 输入命令:show collections,提示没有权限
22. 输入命令:db.auth('test','12345'),输出结果1,用户存在,验证成功
23. 输入命令:show collections,成功显示结果
四、启动和关闭MongoDB的各种参数
mongod的启动和关闭
1. 缺省的启动方式
./mongod
缺省的启动方式,数据存储目录里是/data/db,监听端口是27017
2. 带基本参数的启动方式
./mongod --port 51017 --dbpath /home/mongo/data --logpath /home/mongo/log/log.log --logappend --fork --journal 1000
基本参数:
-f 指定配置文件 (参考:http://www.mongodb.org/display/DOCS/File+Based+Configuration)
--port 指定端口,默认是27017
--dbpath 数据目录路径
--logpath 日志文件路径
--logappend 日志append而不是overwrite
--fork 以创建子进程的方式运行
--journal 日志提交间隔,默认100ms
--nojournal 关闭日志功能,2.0版本以上是默认开启的
3. 带安全参数的启动方式
./mongod ---keyFile /home/mongodb/key/keyfile --nohttpinterface --bind_ip localhost,svr1 --nounixsocket
安全参数:
--auth 开启安全验证
--keyfile 副本集和分片环境下开启安全机制
--noauth 关闭安全验证
--nohttpinterface 关闭http页面接口,缺省的会在监听+1000的端口上开一个http端口(控制home页)
--rest 开启restful http interface,默认是关闭的(控制restful查询接口)
--bind_ip 指定监听的ip
--nounixsocket 关闭unix socket 监听
4. 一个启动参数配置的例子(副本集)
./mongod --port 51017
--dbpath /home/mongodb/data
--oplogSize 100
--logpath /home/mongodb/log/log.log
--logappend
--nohttpinterface
--bind_ip localhost,svr1
--keyFile /home/mongodb/key/keyfile
--fork
5.关闭
> use admin
> db.shutdownServer()
> db.shutdownServer({force : true}) 强制关闭Mongod,应对副本集中主从时间差超过10s时不允许关闭主库的情况
不要使用kill直接杀mongo进程的方式关闭数据节点,会造成数据损坏
mongos的启动和关闭
1.启动(基本和mongod相同)
示例:mongos
--configdb svr1:43000,svr2:43000,svr3:43000
--port 42000
--chunkSize 5
--logpath /home/mongodb/log/mongos.log
--logappend
--nohttpinterface
--keyFile /home/mongodb/key/keyfile
--fork
2.关闭
因为mongos是无状态的节点,直接kill掉Mongos进程jike
副本集(Replica Set)环境中的启动和关闭
1.启动
分别启动每个mongod加入到副本集,最后rs.initiate()就可以了
2.关闭
分别关闭每个mongod,关闭primary的时候如果所有secondary和primary的时间差都大于10s,则primary会
拒绝关闭,如果没有密集写操作可以db.shutdownServer({force : true}) 强制关闭。
分片(Shard)环境中的启动和关闭
1.启动
这个具体的参照分片的配置,启动的顺序是副本集->config server->mongos
2.关闭
因为mongos是分片架构最前端的入口,所以关闭顺序:mongos->config server->副本集
比如要改变MongoDB的默认端口,则可以这样使用--port参数:
打开cmd,在mongodb路径的bin目录下,执行mongod --port 50107 --dbpath d:\work\data\mongodb\db --auth
这样访问MongoDB就是以50107的端口访问了
上篇:
MySQL添加用户、删除用户与授权
下篇:
Yearning SQL审核平台