高度安全环境下的Docker和Kubernetes

你可以在这里找到笔者完整的论文,它是公开可以访问的:http://kth.diva-portal.org/smash/record.jsf?pid=diva2:1231856。
近年来,容器编排和云原生计算获得了许多人的关注。行业内的采用率甚至已经高到金融、银行和国企单位都感兴趣的程度。与其他企业相比,他们在信息安全和IT安全方面有着更为广泛的要求。
其中一个重点在于如何在生产环境中使用容器的同时保持应用程序之间的系统隔离性。由于这类企业以前使用的是由裸金属虚拟化驱动的私有云,迁移到容器编排环境造成的隔离方面的损失不容忽视。这也正是笔者论文研究的范畴,它是以瑞典警察局为目标客户编写的。
论文里具体研究的问题如下:
相比于通过裸金属hypervisor ESXi驱动的虚拟机而言,Docker和Kubernetes是如何实现瑞典警察局应用程序之间的系统隔离?
这个问题有很多需要展开的地方。首先,我们先来看一下它们共同关注的对象 - 应用程序。
混乱的Web应用

David Gilbertson[3]撰写了一篇关于如何通过分发恶意软件包(以Node.js应用为例的话就是NPM)来实现代码注入的精彩故事。尽管依赖扫描程序能够用来发现漏洞,但是它只能降低风险,并不能完全消除这一风险。
即便用户构建了一个没有第三方依赖的应用程序,但是想要做到应用程序永远不会受到攻击仍然是不现实的。
由于这些风险的客观存在,我们无法假定Web应用是安全的。
相反,我们必须采取纵深防御策略[4]。那么,让我们一起来看看应用的下一层——容器和虚拟机!
容器与虚拟机——一个关于隔离的故事

在虚拟机的世界里,隔离可以通过像Intel VT这样的实际硬件实现。另外一方面,Docker容器依赖于Linux内核进行隔离。在考虑底层攻击( layer-below attacks)时,它们之间的这一差异就显得尤为突出。
如果攻击者能够在虚拟机或容器中执行代码,那么攻击者可以通过攻击底层实现 逃逸攻击。
图1 根据使用的是容器还是裸金属虚拟机,隔离的实现层次也各不相同 在Pwn2Own 2017黑客大赛以及GeekPwn2018大会期间,裸金属hypervisor VMware ESXi验证了这类攻击。结果便是爆出了好几个CVE(例如CVE-2017-4902[5],CVE-2018-6981[6]),它们可用于底层攻击以实现 虚拟机逃逸。尽管裸金属虚拟机使用的是硬件级别的隔离技术,但是它并不能确保它们是绝对安全可靠的。
另外一方面,如果我们考虑裸金属 hypversior 与 Linux 内核相比,谁的攻击面更广的话,很显然是后者,因为它更为庞大,涉及的功能范围也更广。而更大的攻击面则意味着依赖于容器隔离的云存在更多潜在的攻击目标。这反映在对 容器逃逸攻击的日益关注,这类攻击已经通过一些内核漏洞被验证是可行的(例如CVE-2016-5195[7],CVE-2017-1000405[8])。
要提高容器 内部的隔离性的话,我们可以使用SELinux或AppArmor等安全模块。不幸的是,这种基于内核的安全机制并不能阻止基于内核的逃逸攻击。即便没有逃脱,它也只会限制攻击者的行为。如果我们想要真正解决容器逃逸攻击问题的话,我们需要在容器 外部甚至内核中使用一些隔离机制。比如一个沙盒!
gVisor是一个由Google开源的容器运行时沙盒,它在容器和操作系统内核之间添加了一个额外的内核。这种类型的沙盒可以缓解基于内核的容器逃逸攻击。但是对于攻击者而言,内核漏洞攻击只是工具箱里的其中一个手段而已。
要了解攻击者的其他手段,我们必须站在更高层面看待容器在云原生时代的使用方式。
集装箱编排对隔离的影响

Tim Allclair在KubeCon 2018大会上给我们做了一次精彩的演讲,这里面他着重提到了几个攻击面。在他的演讲中,他提到了一个关于编排错误如何影响隔离的案例(CVE-2017-1002101[9]),在这种情况下,攻击者通过在Pod外部挂载存储卷实现逃逸攻击。这一类型的漏洞很有问题,因为它也可能会绕过包装容器的沙盒。
在引入Kubernetes之后,我们又多了一个被攻击的对象。Kubernetes Master的几个系统服务就是其中之一。一个例子便是Kubernetes APIServer,最近发现存在一个权限提升的漏洞(CVE-2018-1002105[10])。由于 Kubernetes Master 的攻击面超出笔者论文讨论的范畴,这里先不考虑这类特定的漏洞。
那么,为什么说逃逸攻击是一个大问题呢?容器引入了在同一个宿主操作系统上运行多个共址应用程序的能力。这带来了应用程序隔离的风险。如果一个关键业务的应用程序和另一个易受攻击的应用程序运行在同一台宿主机上,那么攻击者可以通过攻击易受攻击的应用程序来获取对关键应用程序的访问权限。
根据企业处理的数据类型的不同,数据泄露可能还会损害除了企业自身以外的个人和国家。别忘了,我们的客户都是一些国企单位、金融、银行等,如果出现异常可能会严重影响人们的生活。
那么,在这样的环境下还能使用容器编排吗?在我们进一步研究这个思路之前,我们需要先做一些风险评估。
什么是可接受的风险?

正确的说 - 为了在一台使用容器沙盒进行加固过的配置好的主机上实施容器逃逸攻击,攻击者必须:
例如通过代码注入或使用应用程序代码中的现有漏洞来执行容器中的代码;
尽管存在容器沙盒,但是可以利用另一个0day或者未修补的漏洞实现容器逃逸。
你懂的,对于上述这些场景,从事数据处理或者是提供对 机密性, 完整性以及/或者是 可用性方面要求很高的服务的企业断然是无法接受的。
笔者论文是将这些客户的情况考虑在内的,而容器逃逸造成的系统隔离性的损失显然是无法接受的,因为这样造成的后果非常严重。那么,我们可以采取哪些措施来进一步地提高容器的系统隔离性呢?想要在隔离性上面迈出一步的话,我们不妨考虑一下包装了操作系统内核的沙盒 - 虚拟机!
尽管利用受托管的hypervisor的虚拟化技术可以带来一些提升,但是我们希望能够进一步限制攻击面。因此,让我们利用一下裸金属hypervisor,看看他们能够为我们带来什么。
裸金属hypervisor

在这方面,我们不妨假定我们在国防工业中(在某种程度上)已经使用了虚拟化技术,因为它带来的风险是 可以接受的。由于国防工业中的代理商和企业是IT安全领域里要求最苛刻的客户之一,我们也可以说,对他们来说可接受的风险,也是本论文范畴内的其他客户可以接受的。我们之前也讨论过虚拟机逃逸的可能性,它其实也是这样。
如果我们决定将容器搭配这种类型的沙盒一起使用的话,我们还需要将一些因素考虑在内,让它变得更具备云原生的特性。
虚拟机沙盒节点

这种类型的沙盒与前面提到的容器沙盒之间的一个重要关注点在于,这种方案允许将多个容器放在同一个沙盒里。和每个容器都有自己的沙盒相比,这种灵活的实现方式减少了一些性能开销,由于每个沙盒都带有自己的操作系统,我们希望在保持隔离性的同时尽量减少沙盒的数量。
图2 裸金属虚拟机节点充当容器的沙盒。在不同的虚拟机中运行的容器之间系统隔离方面的风险是可以接受的。然而,在同一台虚拟机中运行的容器则不是。 然而,由于 Kubernetes 可能出于种种原因将pod重新调度到其他节点上,这可能会破坏沙盒,我们需要对pod调度寻址机制添加一些限制。这一点可以通过多种方式实现。
截至本文撰写时,Kubernetes(v1.13)支持3种主要方法来控制Pod的调度和/或执行。
NodeSelector & NodeAffinity
Taints & Tolerations
PodAffinity & PodAntiAffinity
表达共址需求

出于简单性和复用性的设计考虑,我们通过以下3个步骤进行系统的分类。
O类:应用程序不敏感,对隔离性方面没有要求。它可以在任何不属于其他类的节点上进行调度。
PG类:该应用程序与一组其他应用程序一起形成一个私有组,并且该组需要一个专属节点。因此,应用程序只能调度到带有对应私有组标识符的PG类节点上。
P类:应用程序需要私有和专属节点,并且只能在P类的空节点上进行调度。
这个简化的例子展示了如何使用taint和toleration来实现共址控制。
视频 Pod 2和3包含来自同一个私有组的应用程序,而Pod 4中的应用程序更敏感并且需要专属节点
但是,对于P类和PG类应用程序而言,我们需要给它们设置额外的Affinity规则以确保在集群及其托管的应用程序增长的同时仍然满足隔离需求。让我们看看我们如何为不同的分类实现关联规则:
P类应用程序的Affinity规则需要专属节点。在这种情况下,如果没有 non-existing-key的话不会调度pod。如果没有pod有这个key的话它会一直尝试下去。
# Class Paffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- topologyKey: "kubernetes.io/hostname"namespaces: ["default"]labelSelector:matchExpressions:- key: non-existing-keyoperator: DoesNotExist
对于PG类应用程序,关联规则将和具有组标识符 class-pg-group-1的pod和没有标识符的pod的节点共同寻址。
# Class PGaffinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- topologyKey: "kubernetes.io/hostname"labelSelector:matchLabels:class-pg-group-1: foobarpodAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- topologyKey: "kubernetes.io/hostname"labelSelector:matchExpressions:- key: class-pg-group-1operator: DoesNotExist
这使得我们可以通过基于分类的系统,根据容器化应用程序的隔离需求来分离容器。
那么这又为我们带来了什么呢?
小结

它的一个重要卖点就是隔离策略可以限制容器逃逸攻击的传播。换句话说—— 容器逃逸本身并没有减轻,但是因此可能造成的后果得到了缓解。显然,这带来了更多的复杂性,需要多加权衡考虑。
另外,为了以可扩展的方式在云中使用它,它还必须额外满足自动化的一些需求。例如,自动创建虚拟机,将它们添加到Kubernetes集群。最重要的是,我们还必须实现并验证应用程序分类机制 始终如期望的那样运行。
以上几乎包含了我的论文中涉及 容器化应用程序隔离的部分。
然而,为了防止在一个节点上实现容器逃逸的攻击者攻击其他节点上的服务,我们需要考虑 网络传播攻击。为了尝试化解这些风险,笔者的论文里进一步提出了 集群网络分段的方案,并且给出了一些云架构,其中一个功能就是用到 硬件防火墙。
限于篇幅,你可以阅读笔者的论文了解更多详情,Container Orchestration in Security Demanding Environments at the Swedish Police Authority[12]。
码的开心!
相关链接:
https://www.owasp.org/index.php/Top102013
https://www.owasp.org/index.php/Category:OWASPTopTen2017Project
https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5
https://searchsecurity.techtarget.com/definition/defense-in-depth
https://nvd.nist.gov/vuln/detail/CVE-2017-4902
https://www.vmware.com/security/advisories/VMSA-2018-0027.html
https://nvd.nist.gov/vuln/detail/CVE-2016-5195
https://nvd.nist.gov/vuln/detail/CVE-2017-1000405
https://nvd.nist.gov/vuln/detail/CVE-2017-1002101
https://access.redhat.com/security/cve/cve-2018-1002105
https://www.foi.se/en/foi/news-and-pressroom/news/2017-12-04-virtualized-it-systems-require-risk-assessment.html
http://kth.diva-portal.org/smash/record.jsf?pid=diva2:1231856

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
