【摘 要】 云原生场景下服务架构的变化,也会引发相关的安全机制出现变化。本文从微服务架构下的应用安全、无服务器计算安全提出了云原生安全防护见解及思考,以提升业界对云原生应用防护的认识。
【关键词】 云原生应用 API安全 无服务器运算安全微服务应用安全
1 引言
2022年4月,云安全联盟大中华区(CSA GCR)发布了《云原生安全技术规范》,针对云原生环境下面临的风险提出了体系化的安全能力要求。如图1所示,云原生应用安全不仅包括容器基础设施和容器编排平台安全,还包括上层的云原生应用安全。云原生场景下服务被拆分成众多微服务,有些通过服务网格形成了点对点(Ad-hoc)的连接模式,相关的安全机制也出现一些变化,而无服务计算(Serveless)作为云原生场景下的一种创新的计算模式,对应的安全机制与传统应用、微服务应用也有所不同,因此对应的防护方式相对传统应用需要做思路上的转变。
2 微服务架构下的应用安全
应用的微服务化带来的新风险主要包含数据泄露、未授权访问、被拒绝服务3种。
(1)数据泄露的风险
云原生环境中,虽然造成应用数据泄露风险的原因有很多,但都离不开以下几个因素。
应用漏洞:通过资产漏洞对应用数据进行窃取。
密钥不规范管理:通过不规范的密钥管理对应用数据进行窃取。
应用间通信未经加密:通过应用间通信未经加密的缺陷对传输中数据进行窃取,进而升级到对应用数据的窃取。
(2)未授权访问的风险
在云原生环境中,应用未授权访问的风险多是由于应用自身漏洞或访问权限错误配置而导致。
(3)被拒绝服务的风险
被拒绝服务是应用程序面临的常见风险。造成拒绝服务的主要原因包括两方面:一方面是由于应用自身漏洞所致,如ReDoS漏洞、Nginx拒绝服务漏洞等;另一方面是由于访问需求与资源能力不匹配所致,例如某电商平台的购买API由于处理请求能力有限,因而无法面对突如其来的大量购买请求,导致平台资源(CPU、内存、网络)的耗尽甚至崩溃,这种场景往往不带有恶意企图。而带有恶意企图的则主要以ACK、SYNC泛洪攻击及挑战黑洞(Challenge Collapsar ,CC)等攻击为主,其最终目的也是应用资源的耗尽。
针对以上提到的风险,相应的防护也应从以上3个方面去考虑,作者通过调研和实践发现使用传统的防护方法是可行的,但当服务随业务的增多而逐渐增多时,传统的防护方法由于需要开发人员进行大量配置而变得非常复杂。例如,用户的应用部署在K8s上,该应用包含上百个服务,做访问控制时可以依托K8s的基于角色的权限访问控制(Role-Based Access Control,RBAC)机制对目的服务进行授权,进而就需要依赖K8s的API以完成配置。每次配置都会耗费一定时间,因此需要大量服务授权时,开发者往往感到力不从心,为解决诸如以上服务治理带来的难题,可以使用微服务治理框架进行相应防护。
综上所述,面向微服务架构下的应用安全,可以采用传统的防护方式或微服务治理框架进行防护,具体的防护措施包含认证服务、授权服务、数据安全防护等。
2.1 认证服务
由于攻击者在进行未授权访问前首先需要通过系统的认证,因而确保认证服务的有效性非常重要,尤其在微服务应用架构下,服务的不断增多将会导致其认证过程变得更为复杂。微服务架构下,服务可以采用JSON Web令牌(JSON Web Token,JWT)或基于Istio的认证方式,下面作者将分别进行说明。
2.1.1 基于JWT的认证
微服务架构下,每个服务是无状态的,传统的服务状态认证方式(Session)由于服务端需要存储客户端的登录状态,因此在微服务中不再适用。理想的实现方式应为无状态登录,流程通常如下所示:
(1)客户端请求某服务,服务端对用户进行登录认证;
(2)认证通过,服务端将用户登录信息进行加密并形成令牌,最后返回至客户端,作为登录凭证;
(3)在步骤(2)之后,客户端每次请求都需携带认证的令牌;
(4)服务端对令牌进行解密,判断是否有效,若有效,则认证通过,否则返回失败信息。
为了满足无状态登录,我们可通过JWT实现。JWT是JSON轻量级认证和授权规范,也就是上述流程中提到的令牌,主要用于分布式场景,其使用流程如图2所示。
从图2我们可以看出,JWT交互流程与上述提到的理想流程基本相似,需要注意的是,JWT令牌中会包含用户敏感信息,为防止被绕过的可能,JWT令牌采用了签名机制。此外,传输时需要使用加密协议。
2.1.2 基于Istio的认证
Istio的安全架构,如图3所示。
Istio包括认证和授权两部分,安全机制涉及诸多组件,控制平面由核心组件Istiod提供,其中包含密钥及证书颁发机构(CA)、认证授权策略、网络配置等;数据平面则由透明代理(Envoy)、边缘代理(Ingress和Egress)组件构成。
借助控制平面Istiod内置的CA模块,Istio可实现为服务网格中的服务提供认证机制,该认证机制工作流程包含提供服务签名证书,并将证书分发至数据平面各个服务的Envoy代理中。当数据平面服务间建立通信时,服务旁的Envoy代理会拦截请求并采用签名证书和另一端服务的Envoy代理进行双向(Mutual Transport Layer Security,TLS)认证,从而建立安全传输通道,保障数据安全。
下文介绍Istio的2种主要认证类型。
2.1.2.1对等认证
对等认证(Peer authentication)主要用于微服务应用架构中服务到服务的认证,从而可验证所连接的客户端。针对此类型的认证,Istio提供了双向TLS解决方案,该解决方案提供以下功能:
(1)确保服务到服务之间的通信安全;
(2)提供密钥管理系统,从而自动进行密钥及证书的生成、分发和轮换;
(3)为每个服务提供一个代表其角色的身份,从而可实现跨集群的互操作性。
具体我们可以通过使用传输认证策略为Istio中的服务指定认证要求,例如,命名空间级别TLS认证策略可以指定某命名空间下所有Pod(K8s的最小单位,里面包含一组容器)间的访问均使用TLS加密,Pod级别TLS认证策略可以指定某具体Pod被访问时需要进行TLS加密等。
2.1.2.2请求级认证
请求级认证(Request authen-tication)是Istio的一种认证类型,主要用于对终端用户的认证,与传输认证的主要区别为,请求级认证主要用于验证用户请求服务时携带的凭据,而非服务到服务的认证。
请求级认证主要通过JWT机制实现,实现原理与前面“基于JWT的认证”小节中提到的内容类似,区别为Istio在其基础上进行了一层封装,使用户可以以yaml的方式进行策略配置,用户体验更为友好。
Istio的JWT认证主要依赖于JSON Web密钥组(JSON Web Key Set,JWKS)。JWKS是一组密钥集合,其中包含用于验证JWT的公钥。在实际应用场景中,运维人员通过为服务部署JWT认证策略实现请求级认证,为方便理解,下面展示了JWT认证策略的核心部分配置:
issuer:https://example.com
jwksUri:https://example.com/.well-known/jwks.json
triggerRules:
-excludedPaths:
-exact:
/status/version
includedPaths:
- prefix: /status/
其中:
issuer:代表发布JWT的发行者。
jwksUri:代表JWKS获取的地址,用于验证JWT的签名,jwksUri可以为远程服务器地址,也可以为本地地址,其通常以域名或URL形式展现。
triggerRules(重要):为使用JWT验证请求的规则触发列表,如果满足匹配规则就进行JWT验证。此参数使得服务间的认证变得弹性化,用户可以按需配置下发规则。上述策略中triggerRules的含义为对于任何带有“/status/”前缀的请求路径,除了/status/version,都需要JWT认证。
当JWT认证策略部署完成后,外部对某服务有新的请求时,请求级认证会根据策略内容验证请求携带的令牌(Token),若与策略内容匹配,则返回认证失败,反之认证成功。
2.2 授权服务
授权服务是针对未授权访问风险最直接的防护手段,微服务应用架构下,由于服务的权限映射相对复杂,因而会导致授权服务变得更难。授权服务可以通过基于角色的授权以及基于Istio的授权实现。
2.2.1 基于角色的授权服务
RBAC通过角色关联用户,角色关联权限的方式间接赋予用户权限。在微服务环境中作为访问控制被广泛使用,RBAC可以增加微服务的扩展性。例如,微服务场景中,每个服务作为一个实体,若要分配服务相同的权限,使用RBAC时只需设定一种角色,并赋予相应权限,再将此角色与指定的服务实体进行绑定即可。若要分配服务不同的权限,只需为不同的服务实体分配不同的角色,而无须对服务具体的权限进行修改。这种方式不仅可以大幅提升权限调整的效率,还降低了漏调权限的概率。
如果用户选择在K8s中部署微服务应用,则可以直接使用K8s原生的RBAC策略。
2.2.2 基于Istio的授权服务
Istio还提供授权机制,其主要用于对服务进行授权。在Istio 1.4版本之前,授权机制依赖于K8s的RBAC策略,相比K8s的原生RBAC策略,Istio对其进行了进一步的封装,可让用户直接通过Istio的声明式API对具体的服务进行授权。不过为了更好的用户体验,Istio在其1.6版本中引入了授权自定义策略(AuthorizationPolicy Custom Resource Definition,CRD),相比1.4版本,CRD带来了更多的优势:一方面,该CRD将RBAC的配置变得更为简化,从而大幅改善了用户体验;另一方面,该CRD支持更多的用例,例如对Ingress/Egress的支持,且不会增加复杂性。
此外,Istio的授权模式也是基于其提供的授权策略实现的。
如图4所示,Istio授权流程可以归纳总结为以下内容:
管理员(Administrator)使用yaml文件指定Istio授权策略并将其部署至Istiod核心组件中,Istiod通过K8s的API服务端组件(API Server)监测授权策略变更,若有更改,则获取新的策略,Istiod将授权策略下发至服务的边车(Sidecar)代理,每个Sidecar代理均包含一个授权引擎,在引擎运行时对请求进行授权。
以下是一个简单的Istio授权策略:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/sleep"]
to:
- operation:
methods: ["GET"]
when:
- key: request.headers[version]
values: ["v1", "v2"]
可以看出,以上策略适用于foo命名空间下,且满足标签为app: httpbin和version: v1的目标Pod, 并设置授权规则为当访问源为“cluster.local/ns/default/sa/sleep”的服务,且请求头中包含v1或v2的version字段时,才允许访问。默认情况下,任何与策略不匹配的请求都将被拒绝。
2.3 数据安全
在微服务应用架构下,服务间通信不仅使用HTTP协议,还会使用gRPC协议等,数据安全防护尤为必要。可以通过安全编码、使用密钥管理系统和安全协议的方式防止数据泄露,在微服务应用架构中,可以考虑使用K8s原生的安全机制或微服务治理框架的安全机制进行防护。
针对K8s原生的安全机制,例如密钥机制(Secret),我们可以使用其进行密钥存储,从而规避了敏感信息硬编码带来的数据泄露风险。
针对微服务治理框架的安全机制,如Istio支持服务间的TLS双向加密、密钥管理及服务间的授权,可以有效规避由中间人攻击或未授权访问攻击带来的数据泄露风险。
2.4 其他防护机制
通过以上介绍,我们可以看出采用微服务治理框架的防护方式可在一定程度上有效规避云原生应用的新风险,但其防护点主要针对微服务架构下应用的东西向流量,针对南北向的流量防护稍显脆弱。由于微服务架构下的应用防护应当是全流量防护,因而针对南北向所存在的问题,我们可以考虑将微服务治理框架与API网关和WAF防火墙相结合,从而提升南北向的防护能力。
本节将以微服务治理框架Istio为例,介绍Istio和API网关协同的全面防护以及Istio与WAF结合的深度防护。
2.4.1 Istio和API网关协同的全面防护
针对应用的南北流量而言,Istio采取的解决方案为使用边缘代理Ingress与Egress分别接管用户或外界服务到服务网格内部的入/出站流量,Ingress与Egress实则为Istio部署的两个Pod,Pod内部为一个透明代理(Envoy),借助Envoy代理的安全过滤(Filter)机制,在一定程度上可对恶意Web攻击进行相应防护。但现有的Envoy安全Filter种类相对较少,面对复杂变化场景下的Web攻击仍然无法应对,可行的解决方案为在服务网格之外部署一层云原生API网关,具体如图5所示。
安全功能上,云原生API网关可提供全方位的安全防护,例如访问控制、认证授权、证书管理、机器流量检测(Bot)、数据丢失防护、黑白名单限制等,在这些有效防护基础之上,应用的南北向得到了控制。
此外,该解决方案的好处还在于应用内部的东西流量不需通过外部网关层,这样可以从边缘到端点进行一站式防护。
2.4.2 Istio与WAF结合的深度防护
WAF作为抵御常见Web攻击的主流安全产品,可以有效对Web流量进行深度防护,并且随着云原生化概念的普及,国内外安全厂商的容器化WAF产品也在迅速落地,未来容器化WAF与Istio的结合将会在很大程度上提升微服务安全。
根据近期市场调研,已有几家公司有了各自的容器化WAF解决方案。以其中一款方案为例,其设计如图6所示,该方案主要运用了Envoy的过滤器机制(Filter),通过外部授权HTTP过滤器(External Authorization HTTP Filter)可以将流经业务容器的东西/南北向流量引流至WAF容器,从而阻断恶意请求,保护微服务的安全。
此方案的优势是对业务入侵较小,实现较为容易,且容器化WAF规模不会随用户业务更改而更改。但同时也有一些弊端,比如需要单独部署容器化WAF、Envoy引流模块的性能问题、引流方式对WAF处理的延迟等。
另一种解决方案是K8s WAF方案。该方案基于Istio实现,其中WAF被拆分为代理程序(Agent)和后端服务两部分,Agent程序作为Sidecar容器置于Pod的Envoy容器和业务容器间,该Sidecar的主要作用为启动一个反向代理,以便将外部请求流量代理至Pod外部的WAF后端服务中,如图7所示。该套方案的好处是无须关心外部请求如何路由至Pod,与Istio结合的理念更接近云原生化,实现了以单个服务为粒度的防护。但同时存在不足,例如,流量到达业务容器前经历了两跳,这在大规模并发场景下可能影响效率。
此外,由于Istio的数据平面为微服务应用安全防护提供了引擎,而数据平面默认采取Envoy作为Sidecar,因此Envoy自身的扩展性成为了安全厂商较为关心的问题。近些年Envoy也在不断提升着其适配性,例如Envoy提供Lua过滤器和Wasm过滤器,以便安全厂商将WAF的能力融入Envoy,从而对微服务应用进行防护。
3 无服务计算安全防护
3.1 无服务计算应用安全防护
针对Serverless应用安全访问控制,除了使用基于角色的访问控制,针对Serverless云计算模式带来的变化,还需要进行更深层次的防护,作者认为函数隔离及底层资源隔离是较为合适的防护方法。
3.1.1 函数隔离
函数间进行隔离可有效降低安全风险。一个函数即服务(Function as a Service,FaaS)应用通常由许多函数以既定的序列和逻辑组成,每个函数可以独立进行扩展、部署,但同时可能被攻破,如果安全团队没有对函数进行有效隔离,那么攻击者也可同时访问应用中的其他函数。再如随着应用设计的不断变化,这些函数更改了执行序列,从而使攻击者有机可乘并发起业务逻辑攻击,这些是FaaS产生的碎片化问题。正确的做法应当是将每个函数作为边界,使得安全控制粒度细化至函数级别,这对于创建能够长期保持安全的FaaS应用是非常必要的。
为了更好地将函数进行隔离,作者认为应当从以下4个方面进行考虑。
(1)不要过度依赖函数的调用序列,因为随着时间推移调用序列可能会改变。如果序列发生了变化,要进行相应的安全审查。
(2)每个函数都应当将任何事件输入视为不受信任的源,并同时对输入进行安全校验。
(3)开发标准化的通用安全库,并强制每个函数使用。
(4)使用FaaS平台提供的函数隔离机制,例如AWS Lambda采用亚马逊弹性计算云(Elastic Compute Cloud,EC2)模型和安全容器Firecracker模型机制进行隔离。
3.1.2 底层资源隔离
仅仅对函数层面进行访问控制是不够的,例如攻击者仍可以利用函数运行时环境的脆弱性以获取服务端的运行权限,从而进行滥用,为了预防上述场景的发生,我们应当从底层进行资源隔离,例如可通过开源安全容器Kata Container从上至下进行防护,再如可通过K8s的网络策略(Network Policy)实现由左至右的网络层面隔离。
3.2 无服务计算平台安全防护
针对无服务计算平台安全防护,可以考虑通过以下几种方式进行相应缓解。
3.2.1 使用云厂商提供的存储最佳实践
为了尽量避免用户在使用云厂商提供的Serverless平台时因不安全的错误配置造成数据泄露的风险,主流云厂商均提供了相应的存储最佳实践供各位开发者参考,例如How to secure AWS S3 Resources、Azure Storage Security Guide、Best Practices for Google Cloud Storage等。
3.2.2 使用云厂商的监控资源
现今各大云厂商均为Serverless配备了相应的监控资源,例如Azure Monitor、AWS CloudWatch、AWS CloudTrail等,使用云这些监控资源可以识别和报告异常行为,例如未授权访问、过度执行的函数、过长的执行时间等。
3.2.3 使用云厂商的账单告警机制
针对拒绝钱包服务(A denial-of-wallet,DoW)攻击,公有云厂商提供了账单告警机制进行缓解,如AWS开发者可通过在Lambda控制台为函数调用频度和单次调用费用设定阈值进行告警;或提供资源限额的配置,主流的云厂商已提供了以下资源选项供开发者配置:
(1)函数执行内存分配;
(2)函数执行所需临时的磁盘容量;
(3)函数执行的进程数和线程数;
(4)函数执行时常;
(5)函数接收载荷大小;
(6)函数并发执行数。
通过上述选项的合理配置可以在一定程度上缓解DoW攻击。
3.3 无计算服务被滥用的防护措施
针对Serverless被滥用的风险,我们可以采取以下方式进行防护。
(1)通过入侵检测系统(Intrusion Detection Systems,IDS)等安全设备监测木马在本机的出口流量,诸如“/pixel”“/utm.gif”“ga.js”等URL的流量应进行重点监测。
(2)确认自己的资产中是否有云厂商提供的Serverless函数业务,如果没有可以通过浏览器禁用相关云厂商的子域名。
(3)采取断网措施,从根源上直接禁止所有网络访问。
3.4 其他防护机制
由于云厂商通常缺乏一套自动化机制对现有Serverless应用中包含的函数、数据及可用API进行分类、追踪、评估等操作,因此开发者在不断完善应用的同时,可能疏于对应用数据及API的管理,从而导致攻击者利用敏感数据、不安全的API发起攻击。为了避免这种情况,开发者需要在应用的设计阶段对资产业务进行详细梳理。其中包括但不限于以下4个部分:
(1)确认应用中函数间的逻辑关系;
(2)确认应用的数据类型及数据的敏感性;
(3)评估Serverless数据的价值;
(4)评估可访问数据API的安全。
有了一个较为全面的应用全景图,便可在一定程度上降低应用被攻击的风险。
由于Serverless应用通常遵循微服务的设计模式,因此一套完整的工作流应由许多函数组成,而开发者可能部署了非常多的Serverless应用,在这些应用中,必定存在一些长时间不被调用的实例,为了避免被攻击者利用,应当定期对Serverless应用进行检测,清理非必要的实例,从而降低安全隐患。
开发者首先应当限制函数策略,给予其适当的访问权限,删除过于宽松的权限,这样即便攻击者拿到了访问凭证也无法对所有资源进行访问。
4 结语
由于应用架构的变化是带来新风险的主要原因,鉴于此,本文作者针对具体的风险提出了防护方法。其中,使用微服务治理框架Istio可以在一定程度上缓解应用架构带来的风险,此外,也介绍了Istio与API网关和WAF结合的业界方案,从而实现微服务应用的全流量防护。此外,作者较为系统地从Serverless应用及平台两方面对前述提到的Serverless风险进行了相应防护介绍。可以看出,与传统安全防护不同的是Serverless模式带来的是新型云原生下的应用安全场景。因而,我们需要适应云计算模式的不断变化,并不断总结新场景下的防护方法,才能最终将安全落实到底。
(原载于《保密科学技术》杂志2022年7月刊)