3.1.1 容器镜像存在的风险

所有容器都来自容器镜像。因此,我们首先研究容器镜像的风险。

与虚拟机镜像不同的是,容器镜像是一个不包含系统内核的联合文件系统(Unionfs),即为进程的正常运行提供基本、一致的文件环境。另外,容器是动态的,镜像是静态的。考虑到这一特点,我们从镜像的内容和镜像的流通、使用等几方面开展分析。

1.不安全的第三方组件

随着容器技术的成熟和流行,大部分流行的开源软件都提供了Dockerfile和容器镜像。在实际的容器化应用开发过程中,人们很少从零开始构建自己的业务镜像,而是将Docker Hub上的镜像作为基础镜像,在此基础上增加自己的代码或程序,然后打包成最终的业务镜像并上线运行。例如,为了提供Web服务,开发人员可能会在Django镜像的基础上,加上自己编写的Python代码,然后打包成Web后端镜像。

毫无疑问,这种积累和复用减少了造轮子的次数,大大提高了开发效率和软件质量,推动了现代软件工程的发展。如今,一个较为普遍的情况是,用户自己的代码依赖若干开源组件,这些开源组件本身又有着复杂的依赖树,甚至最终打包好的业务镜像中还包含完全用不到的开源组件。这导致许多开发者可能根本不知道自己的镜像中到底包含多少以及哪些组件。包含的组件越多,可能存在的漏洞就越多,大量引入第三方组件的同时也大量引入了风险。2020年,有研究报告[1]显示,在使用最为广泛的镜像仓库Docker Hub中,约有51%的镜像至少包含一个危险(critical)级别的安全漏洞。这意味着,使用这些镜像或基于这些镜像制作目的镜像都将使最终业务面临安全风险——无论业务自身代码程序的安全性如何。

2.大肆传播的恶意镜像

除了有漏洞的可信开源镜像外,以Docker Hub为代表的公共镜像仓库中还可能存在一些恶意镜像。如果使用了这些镜像或把这些镜像作为基础镜像,其行为相当于引狼入室,风险不言自明。在3.3节,我们将介绍一个在Docker Hub投放恶意挖矿镜像的案例。截至Docker Hub官方移除这些恶意镜像之时,它们已经累计被下载超过500万次。

3.极易泄露的敏感信息

容器的先进性之一在于它提供了“一次开发,随处部署”的可能性,大大降低了开发者和运维人员的负担。但凡事有利就有弊。为了开发、调试方便,开发者可能会将敏感信息——如数据库密码、证书和私钥等内容直接写到代码中,或者以配置文件形式存放。构建镜像时,这些敏感内容被一并打包进镜像,甚至上传到公开的镜像仓库,从而造成敏感数据泄露。

[1] https://prevasio.com/static/web/viewer.html?file=/static/Red_Kangaroo.pdf。