MongoDB 安全权限访问控制
1.按照http://www.yeayee.com/article-6671969-1.html后半部分,采用正确的安装姿势,可能在子进程过程中会出现错误,但是不影响配置;
2.按照下面红色流程,逐一进行配置,则可行,否则,嘿嘿嘿…,倒腾了一天,就为了设一道门,值得!
遇到类似问题搞不定的可以加群询问哦!
1.查看mongodb服务是否开启
ps -ef | grep mongod
没有开启的话你就自己开启吧
sudo service mongod start
查看服务的状态:sudo service mongod status
实在不行的话就用这种方式: sudo mongod -f /etc/mongod.conf
创建管理员角色
管理员角色必须在你添加–auth认证参数之前创建,不然之后你就没有权限可操作了。如果你之前已经有了用户,那么就删除用户吧。
use admin
db.system.users.remove({}) –> 删除所有用户
db.system.version.find() –> 查看当前的authSchema(认证模式),默认的为5是SCRAM-SHA-1模式,当然你可以改为3是MONGODB-CR模式
更改认证模式:db.system.version.remove({}) –> 删除当前认证模式。
db.system.version.insert({ “_id” : “authSchema”, “currentVersion” : 3 }) –> 添加当前的认证模式为3
然后添加管理员角色吧
use admin
db.createUser({
user: “root”,
pwd: “root”,
roles: [ { role: “userAdminAnyDatabase”, db: “admin”} ]})
重启服务登录认证
sudo pkill mongod –> 杀死服务,很方便。
sudo mongod -f /etc/mongod.conf –fork –auth –> 以认证模式启动服务
然后ps -ef | grep mongod查看服务是否启动
用户登录
mongo
use admin
show dbs; –> 出错,因为你没有权限
db.auth(‘root’,’root’); –> 登录认证
show dbs; –> ok
db.system.users.find() –> 显示用户信息,你可以看看authSchema后面事那种模式
解决启动mongod 时,出现addr already in use错误
启动mongod root@wangyuyu-Vostro-1440:/usr/bin# ./mongod
错误提示:
Sat Aug 17 09:02:02 [initandlisten] ERROR: listen(): bind() failed errno:98 Address already in use for socket: 0.0.0.0:27017
Sat Aug 17 09:02:02 [initandlisten] ERROR: addr already in use
原因是启动mongod时端口被占用。
解决办法:
使用命令 root@wangyuyu-Vostro-1440:/usr/bin# netstat -anp|more
可以看到客户端还保持着与服务器的连接
Proto Recv-Q Send-Q Local Address Foreign Address State
PID/Program name
tcp 0 0 127.0.0.1:28017 0.0.0.0:* LISTEN
953/mongod
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
1546/dnsmasq
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
653/cupsd
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN
953/mongod
tcp 1 0 192.168.5.124:56874 91.189.89.144:80 CLOSE_WAIT
1913/ubuntu-geoip-p
tcp 0 1 192.168.5.124:45890 220.181.111.24:80 FIN_WAIT1
–
tcp 0 0 192.168.5.124:44867 219.148.35.218:80 ESTABLISHED
2219/firefox
杀死953进程root@wangyuyu-Vostro-1440:/usr/bin# kill -9 953
再次察看服务器链接状态:
Proto Recv-Q Send-Q Local Address Foreign Address State
PID/Program name
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
1546/dnsmasq
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
653/cupsd
tcp 0 0 192.168.5.124:60805 61.172.207.130:80 TIME_WAIT
–
tcp 1 0 192.168.5.124:56874 91.189.89.144:80 CLOSE_WAIT
1913/ubuntu-geoip-p
tcp 0 0 192.168.5.124:54370 117.79.157.237:80 TIME_WAIT
–
OK已经成功杀掉进程。
root@wangyuyu-Vostro-1440:/usr/bin# ./mongod
Sat Aug 17 09:32:25 [initandlisten] waiting for connections on port 27017
Sat Aug 17 09:32:25 [websvr] admin web console waiting for connections on port 28017
mongoDB 3.0 访问控制改了很多,需要你老老实实的去看文档去验证,谷歌百度出来的多半就是错误的。 还需要注意这个参数authenticationMechanisms。
为了兼用2.6版本,我直接指定下面的参数:
1
2
|
setParameter:
authenticationMechanisms: MONGODB–CR
|
下面看看如何创建访问控制权限
不使用 —auth 参数,启动 mongoDB
1
|
mongodb–linux–i686–3.0.0/bin/mongod –f mongodb–linux–i686–3.0.0/mongodb.conf
|
此时你 show dbs 会看到只有一个local数据库,那个所谓的admin是不存在的。
mongoDB 没有超级无敌用户root,只有能管理用户的用户 userAdminAnyDatabase。
添加管理用户
1
2
3
4
5
6
7
8
|
use admin
db.createUser(
{
user: “buru”,
pwd: “12345678”,
roles: [ { role: “userAdminAnyDatabase”, db: “admin” } ]
}
)
|
roles 中的 db 参数是必须的,不然会报错:Error: couldn’t add user: Missing expected field “db”。另外,有很多文章记录的是使用 db.addUser(…) 方法,这个方法是旧版的,3.0中已经不存在,详见:http://docs.mongodb.org/manual/reference/method/js-user-management。
切换到admin下,查看刚才创建的用户:
1
2
3
4
|
show users
或
db.system.users.find()
{ “_id” : “admin.buru”, “user” : “buru”, “db” : “admin”, “credentials” : { “SCRAM-SHA-1” : { “iterationCount” : 10000, “salt” : “gwVwuA/dXvxgSHavEnlyvA==”, “storedKey” : “l2QEVTEujpkCuqDEKqfIWbSv4ms=”, “serverKey” : “M1ofNKXg2sNCsFrBJbX4pXbSgvg=” } }, “roles” : [ { “role” : “userAdminAnyDatabase”, “db” : “admin” } ] }
|
怎么关闭 mongoDB?千万不要 kill -9 pid,可以 kill -2 pid 或 db.shutdownServer()
下面使用 —auth 参 数,重新启动 mongoDB:
1
2
3
4
5
6
7
|
mongodb–linux–i686–3.0.0/bin/mongod —auth –f mongodb–linux–i686–3.0.0/mongodb.conf
mongodb–linux–i686–3.0.0/bin/mongo
use admin
db.auth(“buru”,“12345678”) #认证,返回1表示成功
或
mongodb–linux–i686–3.0.0/bin/mongo –u buru –p 12345678 —authenticationDatabase admin
|
此时 show collections 报错
1
2
3
4
5
6
7
8
9
10
11
12
|
2015–03–17T10:15:56.011+0800 E QUERY Error: listCollections failed: {
“ok” : 0,
“errmsg” : “not authorized on admin to execute command { listCollections: 1.0 }”,
“code” : 13
}
at Error (<anonymous>)
at DB._getCollectionInfosCommand (src/mongo/shell/db.js:643:15)
at DB.getCollectionInfos (src/mongo/shell/db.js:655:20)
at DB.getCollectionNames (src/mongo/shell/db.js:666:17)
at shellHelper.show (src/mongo/shell/utils.js:625:12)
at shellHelper (src/mongo/shell/utils.js:524:36)
at (shellhelp2):1:1 at src/mongo/shell/db.js:643
|
因为,用户buru只有用户管理的权限。
下面创建用户,用户都跟着库走,创建的用户都是
1
2
3
4
5
6
7
8
9
10
11
|
use tianhe
db.createUser(
{
user: “bao”,
pwd: “12345678”,
roles: [
{ role: “readWrite”, db: “tianhe” },
{ role: “read”, db: “tianhe2” }
]
}
)
|
查看刚刚创建的用户。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
show users
{
“_id” : “tianhe.bao”,
“user” : “bao”,
“db” : “tianhe”,
“roles” : [
{
“role” : “readWrite”,
“db” : “tianhe”
},
{
“role” : “read”,
“db” : “tianhe2”
}
]
}
|
查看整个mongoDB全部的用户:
1
2
3
4
5
|
use admin
db.system.users.find()
{ “_id” : “admin.buru”, “user” : “buru”, “db” : “admin”, “credentials” : { “SCRAM-SHA-1” : { “iterationCount” : 10000, “salt” : “gwVwuA/dXvxgSHavEnlyvA==”, “storedKey” : “l2QEVTEujpkCuqDEKqfIWbSv4ms=”, “serverKey” : “M1ofNKXg2sNCsFrBJbX4pXbSgvg=” } }, “roles” : [ { “role” : “userAdminAnyDatabase”, “db” : “admin” } ] }
{ “_id” : “tianhe.bao”, “user” : “bao”, “db” : “tianhe”, “credentials” : { “SCRAM-SHA-1” : { “iterationCount” : 10000, “salt” : “//xy1V1fbqEHC1gzQqZHGQ==”, “storedKey” : “ZS/o54zzl/FdcXLQJ98KdAVTfF0=”, “serverKey” : “iIpNYz2Gk8KhyK3zgz6muBt0PI4=” } }, “roles” : [ { “role” : “readWrite”, “db” : “tianhe” }, { “role” : “read”, “db” : “tianhe2” } ] }
|
创建完毕,验证一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
use buru
show collections
2015–03–17T10:30:06.461+0800 E QUERY Error: listCollections failed: {
“ok” : 0,
“errmsg” : “not authorized on buru to execute command { listCollections: 1.0 }”,
“code” : 13
}
at Error (<anonymous>)
at DB._getCollectionInfosCommand (src/mongo/shell/db.js:643:15)
at DB.getCollectionInfos (src/mongo/shell/db.js:655:20)
at DB.getCollectionNames (src/mongo/shell/db.js:666:17)
at shellHelper.show (src/mongo/shell/utils.js:625:12)
at shellHelper (src/mongo/shell/utils.js:524:36)
at (shellhelp2):1:1 at src/mongo/shell/db.js:643
|
显然没权限,先auth:
1
2
3
4
5
6
|
db.auth(“bao”,“12345678”)
1
show collections
news
system.indexes
wahaha
|
参考:
Mongo Shell:http://docs.mongodb.org/v2.2/tutorial/getting-started-with-the-mongo-shell
Enable Access Control:http://docs.mongodb.org/manual/tutorial/enable-authentication
Add a User to a Database:http://docs.mongodb.org/manual/tutorial/add-user-to-database
User Methods:http://docs.mongodb.org/manual/reference/method/js-user-management
Role Methods:http://docs.mongodb.org/manual/reference/method/js-role-management
mongodb 3.0 authentication:http://ibruce.info/2015/03/03/mongodb3-auth/
原文链接:https://www.ttlsa.com/mongodb/mongodb-3-0-security-permissions-access-control/
老的文章:
一、关于权限的默认配置
在默认情况下,mongod是监听在0.0.0.0之上的,任何客户端都可以直接连接27017,且没有认证。这样做的好处是,用户可以即时上手,不用担心被一堆配置弄的心烦意乱。然而坏处也是显而易见,如果直接在公网服务器上如此搭建MongoDB,那么所有人都可以直接访问并修改数据库数据了。
默认情况下,mongod也是没有管理员账户的。因此除非你在admin数据库中使用db.addUser()命令添加了管理员帐号,且使用–auth参数启动mongod,否则在数据库中任何人都可以无需认证执行所有命令。包括delete和shutdown。
此外,mongod还会默认监听27017端口,同样是绑定所有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.在mongodb路径的bin目录下,执行mongod –dbpath d:workdatamongodbdb –logpath d:workdatamongodblog -auth -service
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,成功显示结果
例如:mysql安装配置好后,有一个自带的mysql数据库,里面有一张user表,用来存放用户,以及用户权限,而mongodb这个最像关系型的数据库,有没有这样的表呢。
一,掌握权限,理解下面4条基本上就差不多
1,mongodb是没有默认管理员账号,所以要先添加管理员账号,在开启权限认证。
2,切换到admin数据库,添加的账号才是管理员账号。
3,用户只能在用户所在数据库登录,包括管理员账号。
4,管理员可以管理所有数据库,但是不能直接管理其他数据库,要先在admin数据库认证后才可以。这一点比较怪
二,添加管理员账号
- [root@localhost zhangy]# mongo
- MongoDB shell version: 2.4.6
- connecting to: tank
- > use admin //切换到admin数据库
- switched to db admin
- > show collections;
- system.indexes
- system.users //用户表
- > db.system.users.find(); //用户表没有数据
- > db.addUser(‘tank’,‘test’); //添加一个管理员账号
- {
- “user” : “tank”,
- “readOnly” : false,
- “pwd” : “988432606980d0695e4f668f6bbc643a”,
- “_id” : ObjectId(“529e5d543b6a4608ac833429”)
- }
三,开启动用户权限认证
- [root@localhost zhangy]# vim /etc/mongodb.conf //将auth=true前面的注释拿掉
- [root@localhost zhangy]# /etc/init.d/mongod restart //重启生效
四,用户只能在用户所在数据库登录,管理员需要通过admin认证后才能管理其他数据库
- [root@localhost zhangy]# mongo
- MongoDB shell version: 2.4.6
- connecting to: tank
- > show dbs; //显示所有数据库失败,因为还没有认证
- Wed Dec 4 06:39:50.925 listDatabases failed:{ “ok” : 0, “errmsg” : “unauthorized” } at src/mongo/shell/mongo.js:46
- > db.auth(‘tank’,‘test’); //认证失败,因为这个用户不属于tank这个数据库
- Error: 18 { code: 18, ok: 0.0, errmsg: “auth fails” }
- 0
- > use admin //切换到admin数据库
- switched to db admin
- > db.auth(‘tank’,‘test’); //在admin数据库认证成功
- 1
- > use tank; //切换到tank数据库
- switched to db tank
- > show collections; //不会在提示没有权限了
- contact
- system.indexes
- users
五,添加普通用启
- > use tank;
- switched to db tank
- > db.addUser(‘tank1’,‘test’); //为tank数据库添加了一个可读写用户tank1
- {
- “_id” : ObjectId(“529e5f8474b4c660718a70f3”),
- “user” : “tank1”,
- “readOnly” : false,
- “pwd” : “35dd47abff098f5b4f0b567db8edeac5”
- }
- > db.addUser(‘tank2’,‘test’,true); //为tank数据库添加了一个只读用户tank2
- {
- “user” : “tank2”,
- “readOnly” : true,
- “pwd” : “1792916c544d247538ded52e6df7b887”,
- “_id” : ObjectId(“529e67553992b24438d5e315”)
- }
- > exit //退出
- bye
- [root@localhost zhangy]# mongo
- MongoDB shell version: 2.4.6
- connecting to: tank
- > db.auth(‘tank1’,‘test’); //刚添加的用户可以登录。
# 第一步:在CMD下操作,CentOS更简单了
step1 mongo step2 use testmongo # 在CMD下运行并
db.createUser(
{
user: "yeayee",
pwd: "12345",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
# 创建一个用户具有最牛逼的权限
db.auth("yeayee","12345") # 在testmongo下可以看到该用户认证通过,返回值为1
# 第二步,在py文件中操作
from pymongo import MongoClient client = MongoClient('localhost',27017)
db = client.testmongo db.add_user('beam','123456') # 在创建一个数据库的用户,开发人员可能不止一个
cnn = db.collection # 定义一个集合
document = {
'id': 1,
'name': 'Lily',
'sex': 'F',
'age': 20,
'city': 'shanghai',
'skill': ['word', 'excel']
}
cnn.insert(document) # 只有插进去才算创建,没有插进去还是个什么来着的
# 第三步,测试一下链接是否成功
mongo -u yeayee -p 12345 --authenticationDatabase testmongo mongo -u beam -p 123456 --authenticationDatabase testmongo
嗯,下面两条命令是等效的:
mongo localhost:27017 -u yeayee -p 12345 --authenticationDatabase testmongo mongo localhost:27017/testmongo -u yeayee -p 12345
如果还访问不了:说明你的服务器太紧了,需要松一下:
1. 添加管理员账户
> use admin switched to db admin > db.addUser('tank','test');
2. 配置mongodb.conf
#bind_ip = 127.0.0.1 //注释此行 auth = true //将此行前的注释去掉(之后连接数据库需要验证)
3. 重启mongodb
/etc/init.d/mongod
4. 防火墙开放27017端口
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 27017 -j ACCEPT
5. 测试
转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn