mondoDB安全认证

发布于:2025-07-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

MongoDB的用户和角色权限简介

默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随意连接到实例进行各种操作,MongoDB不会对连接客户端进行用户验证,这是非常危险的。

mongodb官网上说,为了能保障mongodb的安全可以做以下几个步骤:

1)使用新的端口,默认的27017端口如果一旦知道了ip就能连接上,不太安全。

2)设置mongodb的网络环境,最好将mongodb部署到公司服务器内网,这样外网是访问不到的。公司内部访问使用vpn等。

3)开启安全认证。认证要同时设置服务器之间的内部认证方式,同时要设置客户端连接到集群的账号密码认证方式。为了强制开启用户访问控制(用户验证),则需要在MongoDB实例启动时使用选项--auth或在指定启动配置文件中添加选项 auth=true。

在开始之前需要了解一下概念

1)启用访问控制:

MongoDB使用的是基于角色的访问控制(Role-Based Access Control,RBAC)来管理用户对实例的访问。

通过对用户授予一个或多个角色来控制用户访问数据库资源的权限和数据库操作的权限,在对用户分配角色之前,用户无法访问实例。

在实例启动时添加选项--auth或指定启动配置文件中添加选项 auth=true。

2)角色:

在MongoDB中通过角色对用户授予相应数据库资源的操作权限,每个角色当中的权限可以显式指定,也可以通过继承其他角色的权限,或者两都都存在的权限。

3)权限:

权限由指定的数据库资源(resource)以及允许在指定资源上进行的操作(action)组成。

1. 资源(resource)包括:数据库、集合、部分集合和集群;

2. 操作(action)包括:对资源进行的增、删、改、查(CRUD)操作。

在角色定义时可以包含一个或多个已存在的角色,新创建的角色会继承包含的角色所有的权限。在同一个数据库中,新创建角色可以继承其他角色的权限,在 admin数据库中创建的角色可以继承在其它任意数据库中角色的权限。

关于角色权限的查看,可以通过如下命令查询(了解):

// 查询所有角色权限(仅用户自定义角色)
> db.runCommand({ rolesInfo: 1 })


// 查询所有角色权限(包含内置角色)
> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })


// 查询当前数据库中的某角色的权限
> db.runCommand({ rolesInfo: "<rolename>" })


// 查询其它数据库中指定的角色权限
> db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }

常用的内置角色:

数据库用户角色:read、readWrite;

所有数据库用户角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

数据库管理角色:dbAdmin、dbOwner、userAdmin;

集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

备份恢复角色:backup、restore;

超级用户角色:root

内部角色:system

单实例环境

【补充】

如果一旦是因为数据损坏,则需要进行如下操作(了解):

1)删除lock文件:

rm -f /mongodb/single/data/db/*

.lock

2)修复数据:

/usr/local/mongodb/bin/mongod --repair --dbpath=/mongodb/single/data/db

(2)标准的关闭方法(数据不容易出错,但麻烦):
目标:通过mongo客户端中的shutdownServer命令来关闭服务
主要的操作步骤参考如下:
//客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
//#切换到admin库
use admin
//关闭服务
db.shutdownServer()

先按之前未开启认证的方式(不添加--auth参数)来启动MongoDB服务:

/usr/local/mongodb/bin/mongod -f /mongodb/single/mongod.conf

/usr/local/mongodb/bin/mongo  --port 27017

//切换到admin库
use admin


//创建系统超级用户 myroot,设置密码123456,设置角色root
db.createUser({user:"myroot",pwd:"123456",roles:[ { "role" : "root",""db":admin" }]})
//或
 db.createUser({user:"myroot",pwd:"123456",roles:["root"]})



//创建专门用来管理admin库的账号myadmin,只用来作为用户权限的管理
> db.createUser({user:"myadmin",pwd:"123456",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})

//查看已经创建了的用户的情况:
db.system.users.find()


//删除用户
> db.dropUser("myadmin")
true
> db.system.users.find()
//修改密码
> db.changeUserPassword("myroot","123456")

提示:

1)本案例创建了两个用户,分别对应超管和专门用来管理用户的角色,事实上,你只需要一个用户即可。如果你对安全要求很高,防止超管泄漏,则不要创建超管用户。

2)和其它数据库(MySQL)一样,权限的管理都差不多一样,也是将用户和权限信息保存到数据库对应的表中。Mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名、密码和数据库信息。

3)如果不指定数据库,则创建的指定的权限的用户在所有的数据库上有效,如 {role:"userAdminAnyDatabase", db:""}

(5)认证测试

测试添加的用户是否正确
断开连接,重新连接

use admin
db.auth("myroot","12345")
Error: Authentication failed.
0
> db.auth("myroot","123456")
1

(6)创建普通用户创建普通用户可以在没有开启认证的时候添加,也可以在开启认证之后添加,但开启认证之后,必须使用有操作admin库的用户登录认证后才能操作。底层都是将用户信息保存在了admin数据库的集合system.users中。

//创建(切换)将来要操作的数据库articledb,
> use articledb
switched to db articledb


//创建用户,拥有articledb数据库的读写权限readWrite,密码是123456

 db.createUser({user: "bobo", pwd: "123456", roles: ["readWrite"]})


db.auth("bobo","123456")

提示:

如果开启了认证后,登录的客户端的用户必须使用admin库的角色,如拥有root角色的myadmin用

户,再通过myadmin用户去创建其他角色的用户

服务端开启认证和客户端连接登录

需要几个条件:

必须是在admin库下执行该关闭服务命令。

如果没有开启认证,必须是从localhost登陆的,才能执行关闭服务命令。

非localhost的、通过远程登录的,必须有登录且必须登录用户有对admin操作权限才可以。

-u:用户名

-p:密码数据库!

--authenticationDatabase:指定连接到哪个库。当登录是指定用户名密码时,必须指定对应的

副本集环境

对副本集执行访问控制需要配置两个方面:

1)副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书。密钥文件比较简单,本文使用密钥文件,官方推荐如果是测试环境可以使用密钥文件,但是正式环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问

2)使用客户端连接到mongodb集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。

在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。

主节点添加普通用户


网站公告

今日签到

点亮在社区的每一天
去签到