【编者的话】Docker Hub是一个供Docker开发者用来上传/下载容器镜像的地方。为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究。结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风险。
Docker Hub是一个供Docker开发者用来上传/下载 容器镜像的地方。为了认识其应对安全风险的能力如何,我们对其中的镜像进行了一次细致的研究。结果我们惊奇的发现,超过三成的官方仓库包含的镜像疑有高安全风险(如:Shellshock、Heartbleed、Poodle等)。对于普通的镜像,即那些被Docker用户上传的,没有经过任何权威机构验 证过的镜像,这个比例高达40%(样本的错误大约在3%)。
[图:多姿多彩的容器,图片来源自VSMagazine]
为了开展这次研究,我们下载了Docker Hub中的的镜像,然后分析其中的软件包和版本。然后我们使用来自Mitre、NVD(美国国家漏洞数据库)和Linux发行版自己的数据库来分析哪些镜 像易于受到攻击。我们开发一个开源的工具 Banyan Collector,并且使用一个叫做Banyan Insights的服务来生成这个研究中的数据。
尽管我们的分析是基于公共的Docker Hub进行的,我们预估这结果与那些使用私有容器注册中心的企业会类似。企业通常会不断基于那些口碑较好镜像来部署容器,依赖这些镜像的周期更新来获取最 新的软件包。尽管有这些措施,企业仍然有漏洞的威胁;更加严格的运维管理加上实时的监控对于保证安全必不可少。
在本文的剩余部分,我们简单的从高层次介绍下安全漏洞是如何分类,描述基于分析Docker Hub上官方和普通镜像中漏洞得到的结果,然后讨论下这份研究对于运维管理的意义。
安全漏洞的指定和分类
Mitre作为一个不以盈利为目的机构,指定并维护一份CVE(常见安全漏洞和威胁)的列表,每一个 CVE描述了在广泛发布的软件中的漏洞。由美国政府维护的NVD数据库列出了每一个CVE的影响,包含其波及的软件和相应的修复措施(或者尚未采取修复措 施的)。每一个Linux发行版也都维护了一个发行版特定的影响和提供修复该漏洞的软件包版本。
每一个漏洞都会被NVD和Linux的发行版指定一个分值。分值的范围从0到10,7.0到10.0属于高危漏洞,4.0-6.9之间的属于中危 漏洞,0-3.9的属于低危漏洞。这个分类考虑了一系列因素,包括利用该漏洞攻破系统所需要的复杂度(复杂度越低,分数越高)和该漏洞可能会造成的影响 (影响越大,分值越高)。下面是一些例子:
- 高危漏洞:如:ShellShock(bash)、Heartbleed(OpenSSL)
- 中危漏洞:如:Poodle(OpenSSL)
- 低危漏洞:如内存中数组的内存的分配可能会导致整形溢出
把漏洞划分为高中低漏洞的做法带有主观性,一些公司也可能会根据自己的情况来重新分类。而且,NVD指定的分值可能跟Linux发行版中的分值不 一致,并且可能会随着时间推移而更改。我们的研究中使用的漏洞的分值来源于Ubuntu和CentOS发行版指定的分值,对于Debian我们直接使用了 NVD数据库中分值,因为我们找不到任何关于Debian发行版对漏洞分类比较好的数据源。我们对Docker Hub在2015的5月20日的镜像做了一个快照,然后进行分析。我们也试了一下其他日期,得出的结论十分相近。
对于Docker Hub中官方仓库的评估
Docker维护着一个官方的仓库的列表,为软件厂商和机构(如Canonical、Debian、Redhat等)提供了一个即时更新它们最新容器镜像的渠道。官方仓库可以从他们的路径体现出来,他们的路径在library
的命名空间下。举几个例子:library/ubuntu
,library/redis
等。Docker Hub包含大约75个官方的仓库(在我们写这篇文章的时候),大概包含约1600的不同的标签,指向约960个不同的镜像。
[图一:官方有漏洞的镜像]
图一展示了根据分析Docker Hub上所有官方的镜像的得出的主要结果。超过1/3的镜像有高危漏洞,接近2/3的有高或中级危漏洞。这些统计数据让人无法平静,因为这些镜像中一些也是下载量最多的镜像(一些有几十万的下载量)。
如果我们只看今年创建的镜像,有高危漏洞的镜像的比例仍然超过1/3,但是含有高和中级危漏洞的镜像接近了75%。换句话说,今年创建的镜像,每四个中就有三个存在较容易被利用的漏洞,并且潜在影响非常大。
如果我们将范围缩小到哪些标注了lastest
(最新)的镜像,这比例分别下降到了23%和47%,这比例显然还是很高。这更小的数据说明,Docker的用户和维护者们,倾向于将镜像保持到最新,但是老一些的镜像却被忽略;创建容器数量之大和速度之快,让老的镜像在更新的时候被忽略。
为了理解这些漏洞,特别是排名靠前的,我们做了一个详细的影响Docker Hub的镜像漏洞的分析:
[图二: Docker Hub官方镜像中有高危漏洞的镜像]
图二展示了该分析的主要结果,并且表一列举了跟这些软件包相关的主要的CVE。最近发布的存在于mercuarial的漏洞在很多镜像中都有(大 约20%)。著名的OpenSSL漏洞如Heartbleed和Poodle,在近10%的官方镜像中存在。一些镜像还包含bash的 ShellShock(如Centos5.11镜像中)漏洞,这个漏洞在7个月前就被发布了。即便一些机构不使用这些包,但是如果不手动将这些包从容器中 移除掉也会成为恶意攻击的羔羊。
对于Docker Hub中普通仓库的评估
除了一些官方的仓库,Docker Hub包含了一大部普通仓库(在写本文的时候大约有95000个),并且有数十万不一样的镜像。我们实验中随机选择了1700个镜像,然后对他们的内容的内容进行分析(误差约百分之三)。
[图三:有漏洞的普通镜像]
图三显示了在分析了普通镜像后得到的主要结果。大体上,漏洞的出现概率比官方镜像的相比大很多。这个结果合乎预期,因为目前尚没有措施可以在将镜像上传到Docker Hub前可以过滤并检查这些普通的镜像。
大约40%的普通镜像有高危的漏洞。即便我们只是看今年创建的镜像,并且只看那些有latest
标 签的,包含漏洞威胁的镜像的比例仍然在30-40%之前徘徊。如果我们包含那些含有中危漏洞的镜像,比例会迅速升到70%以上,不管哪个时间段都是如此。 尽管你可能会说,这些镜像比起官方镜像下载次数太少了,但是考虑到它们庞大的数量(几十万的规模)可以预想它们跟官方镜像一样使用甚广。
我们又分析了影响普通镜像中的高危漏洞,图4展示了主要的结果:
[图四:普通镜像中含有高危漏洞的软件包]
有趣的是,不同于官方镜像中首要祸源在于mercurial,在这些普通的镜像中,openSSL、bash、和apt成了祸源的榜首。我们怀疑 官方的和普通这种数字上的差异来源于发行版的差异,他们占据了这些镜像的大部分。官方镜像通常基于Debian,并且其中一一大部分包含 mercurial包。而普通的镜像,却通常基于Ubuntu因而有bash、apt和/或openssl相关的漏洞。
延伸
容器技术带来软件开发中的变革,它提供了一个十分高效的方法,可以将开发者开发的软件在数分钟或者几小时内搬上生产环境运 行,而传统的方式可能需要几天甚至数月。但是我们的数据显示这种优势有其弊端,没有谨慎的运维和安全管理的措施,我们冒着让我们的软件生态环境更容易被攻 击的危险。
容器为运行于不同容器之间的运行程序提供了一层安全隔离,因而提高了安全性。然而容器还是需要和其他的容器和系统进行通讯,因此,由于镜像中存在 的安全漏洞,它们还是很容易被远程攻击,包含那些我们没有分析到的漏洞。再者,在多种多样的环境中启动大量的容器的轻便与快捷,如在你的共有云上,私有云 上,笔记本上,都让追踪和防护有安全漏洞的容器变得更加困难。部署容器的高效性,大大的加速了部署软件的多样性,结果让环境中的新的漏洞越来越多。
使用容器的另外一个根本点在于,包管理已经被转移到了容器的内部,而传统的方式是仅仅是基于安装在虚拟或者实体机的操作系统层面上。这种改变主要 根源于虚拟机和容器提供的抽象处于不同的层面。虚拟机提供的是以主机为中心的抽象,其特点是长期不停机一直运行,包含的软件包供不同应用所需。与之相对 的,容器提供的是一个更加以进程为主的抽象,其特点是短暂性,可以到处运行,构建后不会改变,仅仅包含运行一个应用所必须的软件包。任何更新都需要重新构 建容器,从而保持容器的不可修改性,这让任何的漏洞同时被复制。
另外,向DevOps模式的转变,开发者开始为他们开发的应用的软件包负责,这意味着现在开发者开始负起了维护软件包的责任。除了操作系统的软件 包,开发者在容器中可以包含应用层面中的模块,如pip(Python)、npm(Node.JS)和maven(Java)等,而这些都在我们的研究之 外,然而它们也可能带来新的安全问题。因为开发者更加关注快速的开发出新的功,这让保持老的镜像更新变得更加困难,正如我们的研究呈现的一样(如官方的与 201年4月发布的CentOS 5.11镜像仍然包含Shellshock漏洞,该漏洞是八个月前,2014年9月被爆出的)。
一个很好的避免这些问题的方式是经常用最新的更新重新构建镜像。重新构建的过程必须使用发布商发布的最新的基础镜像,并且不能使用任何缓存的镜像层(如:使用在apt-get upgrade的时候加上-no-cahce
)。 但是在一旦发现漏洞从头重新构建,并且重新部署所有的容器的开销太大,十分不切实际了—— 漏洞出的频率太高,每天都会爆出好几次,并且很难评估每一个安全漏洞的的影响范围。加之,更新容器的软件包很可能给容器中的应用带来负面影响和不稳定性, 而这即使用复杂的测试也未必能捕捉到,这让人更加不情愿经常更新。
结论
我们的研究结果鼓励使用严格的运维管理流程,实时的分析镜像中的内容,清楚其中的内容和包含的漏洞。镜像应该经过安全漏洞 的扫描,并且根据漏洞的严重程度来标记是否需要更新。任何重大的漏洞都应该被及时的发现,并且应该可以触发对这些有隐患的镜像进行隔离机制。镜像不仅仅应 只从操作系统层面进行扫描,也应从应用的层面的安全漏洞进行扫描。这些流程应该被集成到持续构建的框架中,这样在享受容器带来的全面福利的同时,仍然保持 着好的安全实践。