云MongoDB网络安全策略和权限管理体系

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 阿里云MongoDB在市场上实际使用时,如何保障数据库安全性?又是如何防止数据库受到攻击?本文将带领你了解云数据库MongoDB云环境的网络安全策略和MongoDB自身的权限管理体系。
本次直播视频精彩回顾,戳这里!
直播涉及到的PPT,戳这里!

演讲嘉宾简介:
朱一聪(花名:一聪),2017年6月加入阿里云MongoDB组,目前主要参与阿里云MongoDB云数据库内核相关的开发。

以下内容根据演讲嘉宾视频分享以及PPT整理而成。

本次的分享主要分为以下三个部分:
一、阿里云网络安全策略
二、鉴权
三、Role-Based Access Control

回顾2017年,发生了一个比较著名的事件--MongoDB赎金事件,也暴露出MongoDB存在很大的安全问题。事件的截图如下图所示,可以看到,黑客非常嘲讽地在用户的数据库内留言并索要赎金。
2ceb0840f0350fb2fcf9d087cce0fd2cecc396e0

这个事件主要归责自然是行径恶劣的黑客,但实际上黑客攻击的手段并不高明,他们只是扫描了在互联网公网上能访问到的MongoDB,并且仅仅扫描了MongoDB默认的端口—27017,然后就直接连进了目标MongoDB。同时他们发现这并不是个例,有很多MongoDB都可以通过这种方式连上。

从客观上来说,用户和社区自己也负有一定责任:首先,把一个数据库直接开放到公网上是非常不安全的,这就相当于打开家门让大家进来;其次,还使用着默认的端口;最要命的是还没有开启鉴权。MongoDB官方默认不开启鉴权的设定确实不太合理,但它也有一些历史的原因的考虑。用户在自己使用的时候,建议是一定要开启鉴权。

一、阿里云网络安全策略
对于阿里云的MongoDB的用户来说,不存在上述的这些问题:首先,阿里云的MongoDB就是默认开启鉴权的。其次,阿里云的MongoDB本身在阿里云的网络上会带有以下安全的措施:
f61f296b94d10f655a4917aa05b0ab5d0d56dabd

1、默认公网无法访问。就算有人申请了可公网访问的ip,它也有白名单机制的保护,即它只接受你指定过的来自于ECS的访问。
2、阿里云现在大部分产品是支持VPC的,这就代表即使是在阿里云内网跟其他网络是隔离的,用户处于自己的专有虚拟网络下。 所以在网络上阿里云的MongoDB是相对比较安全的。

云MongoDB的一些安全措施主要包含四个方面:
1、鉴权[Authentication]
2、授权[Authorization]
3、审计日志
4、TLS/SSL
99b03f5a4c574c9dcf9eb62d7753f5ab5ce23124

审计日志其实是云MongoDB才提供的一个功能。对于MongoDB来说,它的社区版是不提供这个功能的,只有企业版才提供这个功能。从安全性来讲,这个功能的好处在于,万一真的有人恶意的操作了数据库,例如黑客通过一些间接手段直接把用户的用户名、密码给盗取了,那黑客的异常操作和访问是会有记录的,这就相当于他犯罪留下了证据,让用户日后也有迹可查。

TLS/SSL的是指在连接数据库的时候不是使用明文而是进行加密处理。这个能力MongoDB社区版是支持的,企业版在这个方面更强,云MongoDB由于一些原因暂时还没有开放,但未来也可能支持这个功能。

另外两块是鉴权和授权。它们的英文单词在拼写上非常接近,但实际上却是两个完全不同的意思。通俗一点来说,鉴权可以认为是识别[你的客户端]。在MongoDB中鉴权是以user为单位的,鉴权的真正含义是指鉴定这个user有没有资格、或者说认不认可这个user来连上服务器。而授权的含义是指定义这个user用户可以在服务器上做哪些动作。

二、鉴权
MongoDB的鉴权主要分为两种类型,一种是外部鉴权,就是用户以客户端访问mongodb时的鉴权。还有一种是内部鉴权,是指replSet的节点之间的相互鉴权和sharding模式下,mongos和shard节点之间鉴权。对于云MongoDB来说,它的外部鉴权和内部鉴权都是默认开启的。
53c73b5de7f2432bf9b19fd952a6ff7d0d8ca68a

鉴权方式也主要有两种。一种是在连接客户端的时候,添加一个参数用于开启鉴权,把用户名、密码代入进去。另一种是在连接上之后,调用db.auth()方法进行鉴权。

在云MongoDB上两种都支持,用法也十分简单。有一点需要注意的是鉴权这个行为是对于一个db的某个用户而言的,所以大家一定要注意db和user的匹配关系。在现实案例中,很多用户之所以无法访问数据库,往往是因为用户的用户名和用户指定的数据库不匹配导致的。比如下图中MongoDB默认给用户的超级权限用户root,其对应的数据库是admin,只有两者匹配才能成功访问,这个需要大家注意一下。
67361827c5e3c7d7f415fc68ef92f605b565745d

接下来看看MongoDB的鉴权策略,前面提到过,MongoDB是支持多种鉴权方式的,目前推荐的一种方式是SCRAM-SHA-1,并且在云MongoDB上也是采用的这种方式。以往一种可行的方式是直接把用户名、密码(无论是明文还是加密过的hash值)放在客户端进行比较,如果跟客户端保存的那个密码一致,即认为检验通过。相对于这种方法,SCRAM-SHA-1的方式更加先进。
477f7ea2e874de4da76a70543048d3b1ef1a235c

SCRAM-SHA-1是一个双向鉴定机制,不仅客户端在访问服务端的时候,服务端要鉴定客户端是否有资格进行连接,而且客户端本身也要鉴定所连接的服务端是不是正确的。相对于单单只是建立客户端的鉴权,这样的双向鉴权话就比较安全。如果不使用双向鉴权,客户端连上了一个不该连上的Server进行操作,并且Server记录了客户端的操作,会形成带有风险性的行为。

这种鉴权方式的实现比较简单。与传统的方式一样,Server端需要保留一些内容,但它不像传统的方式把密码给保存下来,而是针对密码做一次加盐哈希,即加一个salt和iteration-count做一个哈希得到password[s],然后通过password[s]得到两个key,一个是key[c],另一个是key[s],它们是password[s]直接通过HMAC和”Client Key”和”Server Key”进行哈希得到的,服务端只保存了用户名、H(key[c])、 key[s]、 salt和iteration-count,没有保存真正的password,甚至它没有保留key[c],这也是出于安全考虑。
5e8dc8792bbc094dd0eca011d080d9f197b7f03b

SCRAM-SHA-1的具体流程是这样的:
1、客户端先发送用户名和一个client-nonce(即客户端生成的随机数)。
2、然后服务端返回salt和iteration-count,并生成一个server-nonce,与client-nonce做一个异或返回给客户端。
3、客户端根据这些信息进行计算得到Auth。Auth就是根据服务端返回的结果算出来的,这时候关键操作是它需要证明自己是客户端,具体的和服务端的准备工作一样根据password计算得到key[c],然后key[c]跟Auth使用HMAC再做一次hash,最后再跟key[c]做一次异或,得到_proof[c],粗略来说就是根据password和步骤2中服务端返回的信息计算得到proof[c]。
4、客户端返回proof[c]和client-nonce|server-nonce。
5、服务端对_proof[c]是否合法进行验证,粗略来说就是通过一些计算将_proof[c]还原出key[c],然后校检H(key[c])和本地保存的值,如果它们一样,则客户端鉴权成功。
6、由于是双向鉴权,服务端也要进行鉴权,它使用步骤3的方法计算出_proof[s]并返回给客户端。
7、客户端也用和服务端校检类似的方式对_proof[s]进行验证。
92c7279b7f0ba113474568668038790fee5d9917

可以看到,整个鉴权流程还是比较冗长,而每次建立一个新的连接都要走一次这样的流程。而且在服务端鉴权的时候,需要生成随机数做一些计算,这些计算本身耗费的cpu不是太大,但MongoDB实现里面随机数是通过系统调用去取的(通过访问Linux的dev/urandom来获取随机数),系统调用的开销就不小了;此外为了使得系统调用取到的随机数不重复,这个系统调用还处在一个spinlock的保护下。这样当用户使用大量并发的短链接去连接的时候,所有链接都要做并发的鉴权,而鉴权会去进行系统调用,系统调用还加锁,性能上就会产生问题。所以在短链接的情况下,社区版MongoDB的性能并不好,而瓶颈就在于鉴权环节上。这个问题可以通过改用长连接来解决,实际上MongoDB官方也是推荐大家使用长链接的,因为长链接相对于短链接来说省去了反复链接和鉴权的开销,然而对于某些高级语言(比如PHP)来说,它没有办法只能够使用短链接,或者总有一些场景短连接更适合。而对于云MongoDB来说,短链接是可以放心食用的,因为云MongoDB的内核做了一个优化,它不再通过系统调用去获取Linux的默认的随机数,而是做了一个用户态随机数,这样就把鉴权的瓶颈给取消掉了,所以短链接的性能也非常好。这个问题在云MongoDB也就不存在了。

三、Role-Based Access Control
MongoDB的权限管理,顾名思义,是根据role这个角色来管理的。意思是说,在db下面创建了一个user(创建user需要指定一个db,实际上是通过db.createUser()这个方法创建,这个时候的user即为当前db下创建的),一个user有多个role,一个role又定义了多组权限(权限是指有权对一个resource做某个action操作),因此用户就可以通过组合多个role的方式来得到多种权限的组合,MongoDB还支持role的继承,总的来说role-based access control的是一种非常灵活、强大的方式。
1ce92d5847990fa49b77ad09bf2177b267e3079a

首先讲解一些基本概念,位于最底部的Privileges层涉及到两个概念:Resource和Action。Resource其实就是指一组资源,具体分为三种:collection resource、database resource和cluster resource。如下图中的{ db:”products”, collection:”inventory” }是指数据库products下的名为inventory集合的资源。当然resource也可以不用这么细致,也可以把一个database当成一个resource,即如下图中的{ db:”test”, collection:”” }把collection处置为空,表示对于所有的collection都有权限。还有一种cluster resource,如下图中的{ resource:{ cluster:true }  actions:{ “shut down” } }表示当前role拥有向集群发送shut down的action的权限。

Action其实也是一个封装过的概念,对于MongoDB来说,它的命令的基本单位是command,比如在shell上无论我们使用db.runCommand()的方式还是直接调用db.insert()这样的方法,最终在server端转都是赚化为command来执行。Action其实是一类相似的command的组合,比如以insert这个action为例,它其实是代表了insert和create这两个command,所以如果对一个db有insert的权限(这个insert是action),或者说一个insert权限的source是某个db,这就意味着用户拥有对数据库insert和create这两个command的权限。
8a2093d0094a32c5f1aff27931269e911854f84d

MongoDB的role是支持用户自定义的,功能非常强大。可以通过createRole()方法指定任意的role,如下图中的例子:
f80a1d2bf92fad20b18661cbe1c0592a254dec59

自定义一个role,实际上就是定义一组权限。可以看到上图中有一个字段privileges,它是一个数组,里面包含着若干自定义的权限,每个权限内又具体细分为resource和actions两部分。下方还有一个字段roles,它也是一个数组,里面包含了一个名为read的role,意思是自定义的role继承了名为read的role,这里的继承和面向对象中的继承非常类似,即表示当前名为myClusterwideAdmin的role继承了名为read的role的所有权限。

自定义的方式功能上非常强大的,用户几乎可以根据自己的喜好定义任意一种role,即对任何资源的任意操作的任意组合。但是有的时候,用户不想麻烦地自己进行定义,因此MongoDB也提供了一些内置的role。这样用户就可以通过组合这些内置的role或者直接使用这些内置的role达到自己权限管理的目的。

如下图所示,这些内置的role也分为好几类,比如Database User Roles和Database Administration Roles。大家都知道在MongoDB里面数据库分为两种,一种是Admin数据库,这个数据库是在MongoDB Server启动时就存在的,无需自己创建。还有一种是用户在使用时,自己创建的数据库。特别值得注意的是内置role中有一类Superuser Roles,它实质上就是root,即用户拥有对所有资源的所有权限,在理论上这类用户可以干任何他想干的事情。
8f53afae3737b1a041cca87819564614ab7967a4

在MongoDB中,user是在database下创建的,在鉴权的时候也需要指定当前user属于哪个database。虽然user是在database下创建的,但是它的权限可以跨越它所属的database。如下图创建user的例子:这里使用的是products这个database,但是我们在给这个user指定roles的时候,指定的两个role的权限都是作用在数据库admin下,这种写法在MongoDB里面是允许的,这样写也比较灵活。实际上可以在创建一个用户的时候给它指定任意的role,也就是说可以把对其它数据库的权限通过role赋予给它。
b9e46cc76de6f4ad776c482b82bc640394a77242

MongoDB还提供了一组管理接口,可以让用户可以很方便地管理user、管理role,之前介绍的最简单、最基础的两个db.createUser()和db.createRole()方法就在这组接口中。除此之外,如果想创建完一个用户之后更改这个用户的role,即通过更改用户的role来更改用户的权限,那么可以调用db.updateUser()的方法来进行重置;如果想进行查看的话,也可以调用db.revokeRolesFromUser()。这里就不进行一一介绍了。对于用户的一些修改操作和对权限的一些操作,它都封装了相应的方法以方便用户。
09056d042f3c759a748c71f1e9830c06c05ee9bf

我们知道在MongoDB的数据库里,数据包含三个基础概念:database、collection和document。在进行权限管理的时候,相关数据的存储其实跟普通数据的存储没有什么差别,MongoDB几乎把它所有的信息数据,包括它内部的信息、用户自定义或自己插入的一些数据,都是以document的模式放在某个db的collection里面,只不过像role、user这些信息,它是放在admin数据库下,即便role和user是创建在非admin数据库区,它们的信息也是统一集中存储在admin这个数据库下admin.system.role或admin.system.user这两个collection里面。从下图的储存实例中可以看到,system.role这个collection下存放的一个document展开项跟使用createRole()这个function时传入的document一模一样,其实在使用createRole()时,系统就是往system.role的collection里面直接插入一个document,所以才会导致它们内容一模一样。
655029ce5f229cc34494f2fd4e66819e72088e19

User信息的存储也是类似的,在使用createUser()时,系统也是往system.user的collection里面直接插入了一个document。
2e520fae6355213b24d522d848989eefb5a6d136

虽然从原理上,大家可以发现,直接对system.role和system.user两个collection进行curd操作也可以进行权限管理,但是强烈不推荐这么做,强烈推荐使用上面介绍的像createUser()这样的权限管理的接口。因为mongodb的document事物schema的,是自由的,可以是任意的格式,这是它的特色,那么好了假如system.role插入了一个奇怪的文档怎么办,如果修改某个role的document的时候字段由于失误写错了怎么办。Curd操作是不会对这些做校检的,但是调用接口就会。使用mongodb提供的接口管理权限更方便也更不容易出错。
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
5天前
|
人工智能 搜索推荐 决策智能
不靠更复杂的策略,仅凭和大模型训练对齐,零样本零经验单LLM调用,成为网络任务智能体新SOTA
近期研究通过调整网络智能体的观察和动作空间,使其与大型语言模型(LLM)的能力对齐,显著提升了基于LLM的网络智能体性能。AgentOccam智能体在WebArena基准上超越了先前方法,成功率提升26.6个点(+161%)。该研究强调了与LLM训练目标一致的重要性,为网络任务自动化提供了新思路,但也指出其性能受限于LLM能力及任务复杂度。论文链接:https://arxiv.org/abs/2410.13825。
31 12
|
9天前
|
人工智能 运维 监控
超越传统网络防护,下一代防火墙安全策略解读
超越传统网络防护,下一代防火墙安全策略解读
40 6
|
25天前
|
存储 安全 网络安全
云计算与网络安全:探索云服务的安全挑战与策略
在数字化的浪潮下,云计算成为企业转型的重要推手。然而,随着云服务的普及,网络安全问题也日益凸显。本文将深入探讨云计算环境下的安全挑战,并提出相应的防护策略,旨在为企业构建安全的云环境提供指导。
|
27天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
68 7
|
1月前
|
分布式计算 运维 API
针对MaxCompute经典网络域名下线,Dataphin应对策略的公告
针对MaxCompute经典网络域名下线,Dataphin应对策略的公告
245 7
|
1月前
|
存储 安全 网络安全
云计算时代的网络安全挑战与策略
随着云计算的广泛应用,企业和个人越来越依赖云服务来存储和处理数据。然而,这也带来了新的网络安全威胁和挑战。本文将深入探讨云计算环境中的网络安全问题,包括数据泄露、恶意软件攻击、身份盗窃等风险,并提供有效的安全策略和技术解决方案,以保护云环境免受网络攻击。
|
1月前
|
SQL 安全 算法
网络安全漏洞与防御策略:深入加密技术和安全意识的培养
在数字化时代,网络安全的重要性日益凸显。本文将深入探讨网络安全的多个维度,包括常见的网络漏洞类型、加密技术的应用以及如何培养强大的网络安全意识。通过分析这些关键要素,读者将获得保护个人和组织数据免受威胁所需的知识。
|
1月前
|
SQL 安全 算法
数字时代的守护者:网络安全与信息安全的现代策略
在数字化浪潮中,网络安全与信息安全如同航船上不可或缺的罗盘和舵。本文将探讨网络安全漏洞的成因、加密技术的重要性以及安全意识的培养,旨在为读者提供一套完整的网络自我保护指南。从基础概念到实用策略,我们将一起航行在安全的海洋上,确保每一位船员都能抵达信息保护的彼岸。
|
1月前
|
安全 网络安全 数据安全/隐私保护
访问控制列表(ACL)是网络安全管理的重要工具,用于定义和管理网络资源的访问权限。
访问控制列表(ACL)是网络安全管理的重要工具,用于定义和管理网络资源的访问权限。ACL 可应用于路由器、防火墙等设备,通过设定规则控制访问。其类型包括标准、扩展、基于时间和基于用户的ACL,广泛用于企业网络和互联网安全中,以增强安全性、实现精细管理和灵活调整。然而,ACL 也存在管理复杂和可能影响性能的局限性。未来,ACL 将趋向智能化和自动化,与其他安全技术结合,提供更全面的安全保障。
102 4
|
1月前
|
监控 安全 网络安全
云计算环境下的网络安全防护策略
在云计算的浪潮下,企业和个人用户纷纷将数据和服务迁移到云端。这种转变带来了便利和效率的提升,同时也引入了新的安全挑战。本文将探讨云计算环境中网络安全的关键问题,并介绍一些实用的防护策略,帮助读者构建更为安全的云环境。

热门文章

最新文章