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

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
云数据库 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
相关文章
|
4天前
|
存储 监控 NoSQL
MongoDB索引解析:工作原理、类型选择及优化策略
MongoDB索引解析:工作原理、类型选择及优化策略
|
2天前
|
存储 安全 网络安全
构筑防御堡垒:云计算环境下的网络安全策略与实践
【5月更文挑战第59天】 随着企业逐渐将数据和服务迁移至云端,云计算的安全性成为不容忽视的关键问题。本文深入探讨了在动态且复杂的云环境中如何有效实施网络安全策略,确保数据的保密性、完整性和可用性。通过分析当前云服务面临的安全威胁,结合最新的信息安全技术和最佳实践,本文提出了一系列切实可行的防御措施,并讨论了如何在保障业务连续性的同时提升系统的整体安全性能。
|
4天前
|
SQL 安全 算法
网络安全漏洞与防御策略:保护信息安全的前沿技术
【6月更文挑战第26天】在数字化时代,网络安全成为维护个人隐私和组织资产的关键防线。本文深入探讨了网络安全中常见的漏洞类型、加密技术的进展以及提升安全意识的重要性。通过分析最新的防御机制和安全实践,旨在为读者提供一套全面的网络安全知识框架,强调预防措施的必要性并促进一个更加安全的网络环境。
8 3
|
6天前
|
云安全 监控 安全
云上防御:云计算时代的网络安全策略
【6月更文挑战第24天】在云计算的浪潮中,企业与个人用户纷纷将数据和应用迁移到云端,享受其带来的便利与效率。然而,伴随而来的网络安全挑战也日益严峻。本文深入探讨了云计算环境下的网络安全问题,分析了云服务模型的安全特性,并提出了相应的安全策略和最佳实践。通过案例分析,文章揭示了在云计算环境中维护信息安全的重要性,并指出了未来云安全技术发展的方向。
|
11天前
|
存储 安全 网络安全
构筑防御堡垒:云计算环境中的网络安全策略
【5月更文挑战第50天】 在数字化转型的浪潮中,云计算已成为支撑企业运营的重要基石。然而,随着数据量的激增和云服务的普及,网络安全威胁也随之增加。本文将深入探讨云计算环境中的网络安全挑战,并提出一系列创新的安全策略来强化信息安全防线。通过分析当前云服务的安全漏洞、网络攻击手段以及合规性要求,我们将探索如何构建一个既灵活又强大的安全框架,以保护云基础设施和敏感数据不受网络威胁影响。
|
9天前
|
SQL 安全 网络安全
网络安全漏洞与防御策略: 从加密技术到安全意识的全方位剖析
【6月更文挑战第20天】在数字化时代,网络安全和信息安全已成为保护个人隐私和企业资产的关键。本文深入探讨了网络安全的薄弱环节,包括常见漏洞及其成因,并详细分析了加密技术在数据保护中的核心作用。同时,强调了提升用户安全意识的重要性,以及如何通过教育和技术手段构建更强大的网络防护体系。
|
11天前
|
存储 安全 网络安全
云端守护:云计算时代的网络安全新策略
【6月更文挑战第18天】随着云计算技术的广泛应用,企业和个人越来越依赖云服务来存储和处理数据。然而,这种转变也带来了新的安全挑战。本文探讨了在云计算环境中维护网络安全的重要性,分析了当前云服务面临的主要安全威胁,并提出了一套综合性的网络安全策略,旨在保护云基础设施免受攻击,同时确保数据的完整性、保密性和可用性。通过深入分析云服务的安全架构、加密技术、访问控制机制以及安全监控和响应措施,本文为读者提供了一份云计算环境下网络安全的实战指南。
|
4天前
|
存储 安全 网络安全
云计算与网络安全的博弈:云服务的安全挑战与应对策略
【6月更文挑战第25天】本文深入探讨了云计算技术在提供便利性与灵活性的同时,所面临的网络安全威胁。文章分析了云服务中常见的安全风险和攻击类型,并提出了相应的防御措施。通过案例分析,本文旨在为读者提供一个关于如何在享受云计算带来的便利的同时,确保数据安全和业务连续性的综合视角。
|
9天前
|
人工智能 安全 网络安全
云计算与网络安全:挑战与应对策略
在数字化转型的浪潮中,云计算作为技术支柱,其安全性成为企业关注的焦点。本文将剖析云计算环境中的安全风险,并探讨有效的安全措施。通过案例分析,揭示云服务供应商和企业在信息安全方面的责任共担模式,同时评估最新安全技术如AI在防御网络攻击中的应用前景。旨在为企业提供战略指导,确保其在享受云计算带来的便利的同时,能够有效管理和降低安全风险。
|
11天前
|
人工智能 运维 安全
现代网络安全挑战与运维策略
在当今数字化快速发展的环境中,网络安全面临着越来越复杂的挑战。本文探讨了现代网络运维中的关键安全问题,并提出了有效的策略和解决方案,帮助组织有效应对各种安全威胁。