本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
将所有微服务视为易受攻击的 —— 并监控其行为
这篇文章提醒开发运维人员(Devops)警惕一种虚假的安全感。在开发和配置微服务时遵循安全最佳实践,并不能保证微服务无懈可击。文章指出,尽管所有已部署的微服务都存在漏洞,但仍有很多措施可以确保微服务不被利用。文章解释了如何从安全角度分析客户端和服务的行为,即本文所称的**“安全行为分析”**,从而保护已部署的存在漏洞的微服务。文章还介绍了一个开源项目 Guard,该项目为假定存在漏洞的 Kubernetes 微服务提供安全行为监控和控制。
随着网络攻击的复杂程度不断加剧,部署云服务的组织持续增加其网络安全投资,旨在打造安全无漏洞的服务。然而,网络安全投资的逐年增长并未带来网络安全事件的相应减少。相反,网络安全事件的数量仍在逐年增加。显然,组织在这场斗争中注定会失败——无论付出多少努力来检测和消除已部署服务中的网络弱点,攻击者似乎总是占上风。
考虑到当前攻击工具的泛滥、攻击者的复杂性以及攻击者不断增长的网络犯罪经济收益,任何依赖于在 2023 年构建一个无漏洞、无弱点服务的网络策略都显得过于天真。似乎唯一可行的策略是:
➥ 承认你的服务存在漏洞!
换句话说,要清醒地认识到你永远无法创造出完全无懈可击的服务。如果你的对手找到哪怕一个弱点作为入口,你就输了!承认尽管你尽了最大努力,所有服务仍然存在漏洞,这是重要的第一步。接下来,这篇文章将讨论你可以为此做些什么……
如何保护微服务免遭利用
存在漏洞并不一定意味着你的服务会被利用。虽然你的服务在某些你未知的地方存在漏洞,但攻击者仍需要识别这些漏洞然后加以利用。如果攻击者未能利用你服务的漏洞,你就赢了!换句话说,一个无法被利用的漏洞,代表着一个无法成为现实的风险。
图 1. 攻击者在易受攻击的服务中获得立足点
上图显示了一个示例,其中攻击者尚未在服务中获得立足点;也就是说,假定你的服务在第一天没有运行受攻击者控制的代码。在我们的示例中,服务向客户端暴露的 API 存在漏洞。为了获得初步立足点,攻击者使用恶意客户端尝试利用服务 API 的某个漏洞。恶意客户端发送一个利用程序(exploit),触发服务的某些非预期行为。
更具体地说,我们假设服务存在 SQL 注入漏洞。开发人员未能正确清理用户输入,从而允许客户端发送会改变预期行为的值。在我们的示例中,如果客户端发送一个键为 “username” 值为 *“tom or 1=1”* 的查询字符串,客户端将收到所有用户的数据。利用此漏洞需要客户端发送一个不规则的字符串作为值。请注意,善意用户不会发送带有空格或等号字符的字符串作为用户名,他们通常会发送合法的用户名,例如,这些用户名可能被定义为由 a-z 组成的短字符序列。任何合法的用户名都无法触发服务的非预期行为。
在这个简单的例子中,我们已经可以发现几个机会来检测和阻止利用开发人员(无)意中留下的漏洞的企图,从而使该漏洞无法被利用。首先,恶意客户端的行为与善意客户端的行为不同,因为它发送了不规则的请求。如果这种行为变化被检测并阻止,利用程序将永远不会到达服务。其次,服务对利用程序的响应行为与对常规请求的响应行为不同。这种行为可能包括对其他服务(如数据存储)进行后续的异常调用、响应时间异常,和/或向恶意客户端返回异常响应(例如,与善意客户端发出常规请求时相比,包含的数据量要大得多)。如果检测到服务的行为变化,也能够在利用尝试的不同阶段阻止利用程序。
更概括地说
监控客户端的行为有助于检测和阻止针对服务 API 漏洞的利用。实际上,部署高效的客户端行为监控可以使许多漏洞无法被利用,而其他漏洞则变得难以实现。为了成功,攻击者需要创建一个从常规请求中无法检测到的利用程序。
监控服务的行为有助于在服务被利用时检测到它们,无论攻击向量如何。高效的服务行为监控限制了攻击者可能实现的目标,因为攻击者需要确保服务的行为与常规服务行为无法区分。
将这两种方法结合起来,可以为已部署的易受攻击的服务增加一个保护层,从而大大降低任何人成功利用任何已部署的易受攻击的服务的可能性。接下来,让我们确定四种需要使用安全行为监控的用例。
使用场景
从安全角度看,任何服务的生命周期都可以分为以下四个不同阶段。在每个阶段,都需要安全行为监控来应对不同的挑战。
服务状态 | 用例 | 为了应对这个用例,你需要什么? |
---|---|---|
正常 | 无已知漏洞:服务所有者通常不知道服务镜像或配置中存在任何已知漏洞。然而,可以合理地假设该服务存在弱点。 | 提供针对任何未知的、零日服务漏洞的通用保护 - 检测/阻止作为客户端传入请求一部分发送的可能被用作利用程序的异常模式。 |
易受攻击 | 一个适用的 CVE 被公布:服务所有者需要发布一个新的、不易受攻击的服务修订版。研究表明,在实践中,移除一个已知漏洞的过程可能需要数周时间才能完成(平均为 2 个月)。 | 基于 CVE 分析添加保护 - 检测/阻止包含可能用于利用已发现漏洞的特定模式的传入请求。尽管服务存在已知漏洞,仍继续提供服务。 |
可利用 | 一个已知的利用程序被公布:服务所有者需要一种方法来过滤包含已知利用程序的传入请求。 | 基于已知的利用程序签名添加保护 - 检测/阻止携带识别该利用程序签名的客户端传入请求。尽管存在利用程序,仍继续提供服务。 |
被滥用 | 攻击者滥用支持该服务的 Pod:攻击者可以遵循一种攻击模式,使其能够滥用 Pod。服务所有者需要重启任何受损的 Pod,同时使用未受损的 Pod 继续提供服务。请注意,一旦 Pod 被重启,攻击者需要重复攻击模式才能再次滥用它。 | 识别并重启被滥用的组件实例 - 在任何给定时间,一些支持的 Pod 可能被攻破和滥用,而其他 Pod 则按设计运行。检测/移除被滥用的 Pod,同时允许其他 Pod 继续为客户端请求提供服务。 |
幸运的是,微服务架构非常适合进行安全行为监控,如下文所述。
微服务与单体应用的安全行为对比
Kubernetes 通常用于支持采用微服务架构设计的工作负载。按照设计,微服务旨在遵循 UNIX 的“做好一件事并把它做好”的哲学。每个微服务都有一个有界上下文和一个清晰的接口。换句话说,你可以期望微服务客户端发送相对常规的请求,而微服务则会针对这些请求呈现相对常规的行为。因此,微服务架构是安全行为监控的绝佳候选者。
图 2. 微服务非常适合安全行为监控
上图阐明了将单体服务划分为一组微服务如何提高了我们执行安全行为监控和控制的能力。在单体服务方法中,不同的客户端请求交织在一起,导致识别异常客户端行为的能力减弱。在没有先验知识的情况下,观察者很难区分交织的客户端请求的类型及其相关特征。此外,内部客户端请求对观察者是不可见的。最后,单体服务的聚合行为是其许多不同内部组件行为的复合体,这使得识别异常服务行为变得困难。
在微服务环境中,每个微服务按设计都应提供更明确定义的服务,并服务于更明确定义的请求类型。这使得观察者更容易识别异常的客户端行为和异常的服务行为。此外,微服务设计暴露了内部请求和内部服务,这为观察者识别异常提供了更多的安全行为数据。总的来说,这使得微服务设计模式更适合进行安全行为监控和控制。
Kubernetes 上的安全行为监控
寻求添加安全行为监控的 Kubernetes 部署可以使用 Guard,它是在 CNCF 项目 Knative 下开发的。Guard 集成在运行于 Kubernetes 之上的完整 Knative 自动化套件中。或者,你可以将 Guard 部署为一个独立的工具,以保护 Kubernetes 上任何基于 HTTP 的工作负载。
请参阅
- GitHub 上的 Guard,了解如何将 Guard 作为独立工具使用。
- Knative 自动化套件 - 在博文 Opinionated Kubernetes 中了解 Knative,该文章描述了 Knative 如何简化和统一在 Kubernetes 上部署 Web 服务的方式。
- 你可以通过 SIG Security Slack 频道或 Knative 社区的 security Slack 频道与 Guard 的维护者联系。Knative 社区频道将很快迁移到 CNCF Slack,频道名称为
#knative-security
。
这篇文章的目标是邀请 Kubernetes 社区采取行动,引入安全行为监控和控制,以帮助保护基于 Kubernetes 的部署。希望社区作为后续行动能够:
- 分析不同 Kubernetes 用例中出现的网络挑战
- 为用户添加关于如何引入安全行为监控和控制的适当安全文档。
- 考虑如何与能够帮助用户监控和控制其易受攻击服务的工具集成。
参与进来
欢迎你参与进来,加入为 Kubernetes 开发安全行为监控和控制的努力;分享反馈并为代码或文档做出贡献;以及提出或建议任何形式的改进。