编者按

2022年5月,由网络安全研究国际学术论坛(InForSec)汇编的《网络安全国际学术研究进展》一书正式出版。全书立足网络空间安全理论与实践前沿,主要介绍网络和系统安全领域华人学者在国际学术领域优秀的研究成果,内容覆盖创新研究方法及伦理问题、软件与系统安全、基于模糊测试的漏洞挖掘、网络安全和物联网安全等方向。全书汇总并邀请了近40篇近两年在网络安全国际顶级学术议上发表的论文(一作为华人),联系近百位作者对研究的内容及成果进行综述性的介绍。从即日起,我们将陆续分享《网络安全国际学术研究进展》的精彩内容。

本文根据论文原文“Automatic Policy Generation for Inter-Service Access Control of Micro- services.”整理撰写。原文发表于USENIX Security 2021,作者在完成论文工作时为浙江大学在读博士生。本文较原文有所删减,详细内容可参考原文或作者的博士学位论文。

01 研究背景

随着云计算技术的发展,云应用的架构也在不停地演进,云应用架构的演进如图1所示。起初,云应用采用传统的单体架构,所有模块被作为一个整体打包并部署在云端,用户无须在本地部署程序,便可以通过浏览器和网络访问云服务。那时云应用程序的结构相对简单,这种单体架构十分高效。但随着云应用的复杂性逐步增加,这一架构变得十分不灵活:修改单个模块的代码需要重新测试、重新打包和重新部署整个应用;当需要对系统瓶颈进行弹性伸缩时,需要伸缩整个应用程序,包括那些目前压力并不大的模块。

因此,为了灵活地开发和维护复杂的云应用程序,微服务架构出现了。它将一个庞大的云应用程序沿业务边界拆分为多个微服务,它们运行在不同的物理机、虚拟机或容器上,每个微服务都可以被独立地开发、部署、升级和伸缩,这极大地提高了软件开发和维护的灵活性。然而,随着微服务数目的增加,服务间通信的复杂性增长迅速,服务变得极难管理。为了解决这一问题,服务网格出现了,它作为一个专用的基础设施层增强了微服务架构。它使用边车代理管理微服务之间的全部网络流量,并在服务间通信中透明地加入了访问控制、流量管理、监控追踪等一系列通用功能。得益于此,微服务应用的业务逻辑和对服务间通信的管理分离开来,研发人员可以全心专注于业务逻辑的开发,极大地提升了微服务的开发效率。

微服务的生命周期非常灵活,使用了持续集成/持续部署(CI/CD)的理念,通过一系列自动化工具构建了一个能够自动测试、打包和部署服务的管道,实现了高效的程序构建和发布。为了防止服务中断,在实际应用中,微服务通常采用一种渐进式的更新方式。管理员首先在系统中部署新版本的微服务,然后,把一部分业务流量导入新版本。当确认新版本的微服务工作正常后,所有的流量将逐渐被迁移到新版本,旧版本随之下线。如果新版本微服务出现了异常,也会用同样方式回滚到旧版本。

图1

目前,微服务在产业界获得了广泛应用,2018年的一项调研显示,有91%的公司正在使用或计划使用微服务架构,Kubernetes和Istio是最流行的基础设施平台。

02 研究动机

这种分布式的软件组织方式带来了新的安全问题。在微服务架构下,各个服务相对独立,与传统单体应用的各模块通过本地调用进行通信相比,微服务通过网络API调用进行交流,这就带来了潜在的攻击面。2018年的一项研究显示,超过92%的容器镜像中包含未被修补的软件漏洞,说明部署在生产环境中的容器存在被渗透的可能。

一旦有微服务被渗透,它可以通过向其他微服务发送恶意请求来窃取信息或发起攻击,因为微服务通过服务间合作共同完成业务流程,这种相互间的天然信任使整个应用非常容易因为单个或少量被渗透的微服务实例而受损。

一个典型微服务应用的架构及微服务越权攻击示例如图2所示。正常情况下,用户可以通过前端服务访问后端服务,进而访问数据库并记录日志。但是,一旦日志服务被渗透,它可能直接向数据库服务发送请求,从而获取保存在其中的敏感信息。因为攻击者位于服务内,仅通过身份认证和信道加密是无法防御这种攻击的。

对于此类攻击,当前的解决方案是在微服务间进行细粒度的访问控制。通过访问控制策略,管理员可以指定各个微服务的权限,从而约束微服务的行为,防止恶意服务对敏感资源的非法访问。在示例中,管理员可以配置只有后端服务能访问数据库服务的API,这样就阻止了来自日志服务的攻击。

目前,这些基于策略的访问控制机制都设计得非常精巧,提供了很高的管理灵活性和很细的授权粒度。但是,微服务应用具有规模庞大、频繁更新的特点,而当前对访问控制策略的配置仍然依赖管理员人工进行。这不仅容易出错,非常耗时,而且十分不灵活。推特后端在2016年就已经包含了103级别的微服务,服务实例更是高达105级别。通过人工的方法细致地配置和管理数以千计的微服务的访问控制策略并不可行。更糟糕的是,微服务频繁迭代的特点要求这些访问控制策略能被快速及时地更新,这对人工配置方法来说也同样是无法完成的任务。因此,要想让强大的微服务间访问控制机制在生产中真正发挥作用,必须探索自动化的策略生成方案,否则一切只能是空中楼阁。

图2

现有的分布式系统安全策略的自动化方案主要可以被分为三类。第一类是基于文档的方法,它们使用自然语言处理技术,从应用的文档中推理安全策略。虽然文档确实能够很好地反映开发人员的高层次管理意图,但是文档并不总是存在,把这些意图从文档中精确地提取出来也并不容易。这类方法通常准确率不高,且粒度较粗。第二类是基于历史的方法,它们致力于在历史操作中挖掘安全策略。但是,这类方法非常依赖训练数据的质量,只有充足的历史数据才能导出完备的安全策略。在生产环境中,这一点也很难保证。最后一类是基于模型的方法,它们对系统行为进行形式化建模,然后据此生成安全策略。但对于微服务应用这种频繁迭代的大规模分布式系统,这类人工建模的方法在敏捷性和可伸缩方面都存在短板,因而也并不适用。

实际上,不同于其他分布式系统,微服务应用有其独有的特点可以被我们利用。首先,微服务相对较小,这意味着单个服务具有较低的内部复杂度。其次,根据我们对流行的开源微服务应用的调研,在单个应用内,微服务间的调用方式相对统一,涉及的服务间调用协议和调用库数量也十分有限,这就给了我们通过静态分析从微服务代码中提取正常系统行为进行服务间访问控制的机会。

03 研究思路

总的来说,我们的目标是自动生成、维护和更新微服务间的访问控制策略。具体来说,我们试图应对云服务间访问控制自动化的两个关键挑战:

■ 如何获取完整的、细粒度的服务间调用逻辑;

■ 如何有效生成和更新服务间访问控制策略。

对于第一个挑战,我们设计了一个请求提取阶段,利用静态分析从微服务的代码和配置文件中提取服务间的调用逻辑。对于第二个挑战,我们设计了一个策略管理阶段,使用基于图的方法,将服务间调用逻辑转换成相应的服务间访问控制策略,并进行维护和更新。设计思路如图3所示。

图3

根据这一思路,我们提出了AutoArmor,一个微服务间访问控制策略自动化工具。AutoArmor的系统架构和服务E的部署过程如图4所示,AutoArmor包括3个主要组件:1个离线的静态分析引擎,负责提取微服务代码中的服务间调用请求;1个权限引擎,负责维护和更新权限图,描述服务间的调用逻辑;1个策略生成器,负责将权限图及其中的改变翻译成相应的访问控制策略。

图4

我们可以通过服务E的部署过程了解AutoArmor的工作流程。首先,服务E的源代码被提交到CI服务器进行自动审计和测试。静态分析引擎在CI服务器对服务E的源代码进行分析,并生成一个清单文件来指出服务E能够发起哪些服务间调用。在服务E部署时,权限引擎调取了静态分析引擎生成的清单文件,为服务E生成了一个权限节点,插入当前的权限图中。感知到权限图中发生了修改后,策略生成器根据权限图的变化计算出应该添加或修改的服务间访问控制策略,然后下发到微服务基础设施中,进行后续的策略实施。

由于AutoArmor的系统架构与CI/CD工作流结合在了一起,这样当后续E的服务更新,也就是代码修改的时候,它也可以自动地根据新的代码对访问控制策略进行更新。

04 设计细节一:请求提取阶段

在请求提取阶段,主要的技术方案是基于静态分析的服务间调用请求提取。这里,我们需要克服静态分析方法的固有局限性,也就是说,要尽量减少状态空间,减少静态分析的复杂度。因为微服务之间通过网络API调用相互通信,如HTTP、gRPC等,我们可以不用对微服务的完整代码进行分析,而是只关注那些与网络API调用相关的代码。

具体来说,我们的技术方案主要分为3步,如图5所示。

图5

(1) 扫描微服务的代码,找出网络API调用语句,也就是发起服务间调用的关键语句。在扫描代码的过程中,对于用静态语言编写的微服务,因为有函数签名对方法进行唯一标识,所以可以直接找到调用关键方法的语句。但对动态语言来说,当发现一个方法调用语句时,无法确定当前方法是否是我们关注的服务间调用方法。因此,对于这类微服务,我们从源文件的“import”语句出发,扫描方法使用的完整过程,从而判断当前语句是否是我们需要识别的关键语句。

(2)从第(1)步中获得的关键语句出发,沿数据流反向进行污点传播,获得与该服务间调用相关的程序切片。为了进一步减少静态分析的复杂性,我们不需要追踪所有变量的定义和使用,可以只关注那些能被用于服务间访问控制的关键变量。当遇到控制流分支时,如果控制流的多条分支中都包含被污染的变量,我们需要创建程序切片副本,分别跟踪不同的控制流。这种情况一般出现在一个条件分支语句产生的多个路径中都有变量被污染,或者一个服务间调用语句所在的方法被多个其他方法调用的时候。它代表了可能有多个不同的服务间调用通过同一条语句被发起了,因此要分别对它们进行程序切片。通过这一步,静态分析引擎为每个服务间调用请求提取了一个精简的程序切片,其中包含对访问控制来说足够充足的信息。

(3) 通过语义分析在程序切片中提取服务间调用的详细属性。因为有的属性,例如URL可能在定义后进行了多次修改,涉及一系列字符串操作,所以需要对这种属性变量进行重构。在这个过程中,我们从污点传播的终点出发,沿数据流的正向扫描整个程序切片,完成变量的构建,将一个服务间调用和它的详细属性提取出来。

在知道了每个微服务能够发起哪些服务间调用后,我们就能构建整个应用内部的服务间调用逻辑,进行访问控制。

05 设计细节二:策略管理阶段App分析

在运行时,微服务实例的边车代理会将输入请求与安装在代理上的访问控制策略一一对比,从而完成策略实施。这意味着边车代理上安装的策略数目可能是影响策略实施的性能的一项重要指标。我们测量了这一影响,结果显示,运行时的策略检查时间随着安装的服务间访问控制策略数目线性增加,这意味着冗余的服务间访问控制策略会造成整个微服务应用的性能下降。

在微服务应用中,同一个微服务可能同时存在多个版本,它们可能有不同的服务间依赖关系,因此需要在授权时进行区分。微服务应用的权限图构建示例如图6所示。在图6中,服务A的V1、V2和V3这3个版本都可以向服务B发起r1请求,但V2版本还能够向服务C和服务D分别发起r3和r2请求。但在实际应用中,因为属于同一个微服务,它们的职责和功能是相似的,发起的服务间调用也大多是一致的。因此,为各个版本分别生成访问控制策略会带来冗余。

在策略管理阶段,我们设计了一个权限图来描述应用中各个服务的权限,并将同一服务各个版本共有的权限进行整合,用于生成优化的访问控制策略集,尽可能地减少冗余策略的出现。它包含两类节点,一类是“服务节点”,用来描述同一个服务的各个版本共有的权限;另一类是“版本节点”,描述各个版本独有的权限。这样,一方面消除了冗余,减少了策略总数;另一方面,当服务更新不涉及独特的权限时,无须进行实际的策略更新,减少了对性能的影响。

图6

因为微服务采用渐进式的版本更新和版本回滚,版本更新可以被转化为版本节点的添加和删除,版本回滚可以被转化为版本节点的删除和添加。因此,在服务更新时,只需要处理这两类原子操作即可。为了保证服务节点包含的权限集合是该微服务的各个版本所共有的权限的最大子集,在添加和删除某个版本节点时,可能涉及对服务节点的拆分和更新。这里限于篇幅,就不详细展开相应的算法了。根据权限图及其变化,AutoArmor对访问控制策略集不断进行维护和更新。

06 实验评估

我们实现了AutoArmor的原型系统,并基于5个流行的开源微服务应用对它的功能和性能进行了评估,如表1所示。这些应用中有3个是多语言微服务应用,还有1个是工业级应用,一共包含64个微服务。

表1

请求提取的有效性可以由两个指标度量,一是它是否能在微服务代码中识别出服务间调用请求,二是它是否能够提取出这些服务间调用请求的详细属性信息。实验结果如表2所示,对755个服务间调用请求的识别率是100%,而对这些服务间调用请求的参数的提取率是99.5%。这是因为有一个微服务直接访问了它所收到的请求中包含的URL。这些URL直接来自输入请求,在它的代码中并不存在,因此无法被静态地提取出来。

表2

在静态分析时间方面(评估结果如表2所示),因为我们的设计极大地减少了静态分析的搜索空间,所以对每个微服务的平均分析时间仅为57秒。这对一个离线过程来说是完全可以接受的。

为了评估策略生成的正确性,我们模拟了3种越权攻击,并在部署和未部署生成的策略集这两种情况下进行了测试。同时,我们使用了这些应用自带的负载生成器来触发合法的服务间调用。实验表明,全部的合法请求都通过了,全部的越权攻击都被阻挡住了。基于提取出的微服务间调用逻辑,我们也可以进一步绘制出微服务应用的实际系统行为模型,帮助管理员更好地理解微服务应用的实际运行逻辑,及时地识别和定位那些与设计不一致的系统行为。

为了评估策略管理的性能(评估结果如图7所示),我们分别测试了策略生成、更新和移除的时间延迟。为了衡量权限图的使用给策略管理带来的优势,我们实现了“分别为每个微服务版本生成访问控制策略”的策略管理机制,并将其作为基准方法,和我们的解决方案在同一情况下进行测量和比较。实验表明,在初始部署阶段,由于权限图的构建,我们的方案相对基准方法略慢。但在策略更新和策略移除时,我们的方案有显著的性能提升。

在具体的时间延迟方面,对于包含200个以上服务间访问控制请求的单个微服务,策略生成的时间小于540毫秒。有研究显示,一个微服务的部署通常需要40秒到1分钟,与此相比,我们在策略管理阶段引入的运行时开销几乎是可以忽略不计的。

为了评估我们的技术方案是否能被应用于大规模的微服务应用上(评估结果如图8所示),我们利用了Istio的性能和可伸缩性测试工具——Istio load tests mesh生成大规模的微服务应用。实验结果显示,策略生成、更新和移除的时间随微服务应用的规模增大而线性增加。不过,即使面对包含1000个微服务的大型云应用,它也能在12秒内生成全部的访问控制策略。这证明了它具有在大规模微服务应用中实际应用的潜力。

图7

图8

为了验证权限图确实可以生成优化的访问控制策略集,减少服务间访问控制对微服务应用性能的影响,我们分别测试了在部署基线方法生成的策略集和我们的方法生成的策略集时整个应用的端到端性能。结果显示,在部署了基线方法生成的策略集后,各应用整体的端到端时间延迟均有提升;当用我们生成的优化的策略集替换基线方法的策略集之后,各应用的端到端时间延迟呈现下降的趋势。这说明通过减少冗余的访问控制策略,权限图可以加速微服务基础设施在运行时的策略检查,使微服务应用实现更好的整体性能。

07 总结

总的来说,AutoArmor是第一个微服务间访问控制策略自动生成解决方案,它包含两个关键技术,一个是基于静态分析的微服务间调用请求提取机制,用于提取服务间的调用逻辑;另一个是基于图的微服务间访问控制策略管理机制,用于为各个服务生成访问控制策略,并随着云应用的变化进行策略更新。实验表明,它可以有效地实现微服务间访问控制策略的自动生成、维护和更新,并且仅引入极小的性能开销。

作者简介

李星,浙江大学计算机科学与技术学院博士。他的研究方向为云计算系统中的自动化安全管控,包括对SDN等新型云网络架构和服务网格、无服务器等新型云应用架构的安全性与可靠性研究。

(未完待续……)

版权声明:本研究报告由网络安全研究国际学术论坛(InForSec)汇编,人民邮电出版社出版,版权属于双方共有,并受法律保护。转载、摘编或利用其它方式使用本研究报告文字或者观点的,应注明来源。

声明:本文来自网安国际,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。