我们从容器镜像、活动容器、容器网络、容器管理程序接口、宿主机操作系统和软件漏洞六个方面来分析容器基础设施可能存在的风险。

容器镜像

与虚拟机镜像不同的是,容器镜像是一个不包含系统内核的联合文件系统(Unionfs),即为进程的正常运行提供基本、一致的文件环境。另外,容器是动态的,镜像是静态的。

  • .不安全的第三方组件:用户自己的代码依赖若干开源组件,这些开源组件本身又有着复杂的依赖树,甚至最终打包好的业务镜像中还包含完全用不到的开源组件。这导致许多开发者可能根本不知道自己的镜像中到底包含多少以及哪些组件。包含的组件越多,可能存在的漏洞就越多,大量引入第三方组件的同时也大量引入了风险。
  • 恶意镜像:除了有漏洞的可信开源镜像外,以Docker Hub为代表的公共镜像仓库中还可能存在一些恶意镜像。如果使用了这些镜像或把这些镜像作为基础镜像,其行为相当于引狼入室,风险不言自明。
  • 极易泄露的敏感信息:容器的先进性之一在于它提供了“一次开发,随处部署”的可能性,大大降低了开发者和运维人员的负担。为了开发、调试方便,开发者可能会将敏感信息——如数据库密码、证书和私钥等内容直接写到代码中,或者以配置文件形式存放。构建镜像时,这些敏感内容被一并打包进镜像,甚至上传到公开的镜像仓库,从而造成敏感数据泄露。
活动容器
  • 不安全的容器应用:与传统IT环境类似,容器环境下的业务代码本身也可能存在Bug甚至安全漏洞。容器技术并不能解决这些问题。无论是SQL注入、XSS和文件上传漏洞,还是反序列化或缓冲区溢出漏洞,它们都有可能出现在容器化应用中。
  • 不受限制的资源共享:如果容器使用了过多资源,就会对宿主机及宿主机上的其他容器造成影响,甚至形成资源耗尽型攻击。
  • 不安全的配置与挂载:通过简单的配置和挂载,容器的隔离性将被轻易打破。
容器网络

默认情况下每个容器处于自己独立的网络命名空间中,与宿主机之间存在隔离。然而,每个容器都处于由docker0网桥构建的同一局域网内,彼此之间互相连通。理论上,容器之间可能发生网络攻击,尤其是中间人攻击等局域网内常见攻击方式。

容器内的root用户虽然被Docker禁用了许多权限(Capabilities机制),但它目前依然具有CAP_NET_RAW权限,具备构造并发送ICMP、ARP等报文的能力。因此,ARP欺骗、DNS劫持等中间人攻击是可能发生在容器网络的。

容器管理程序接口

Socket是Docker守护进程接收请求及返回响应的应用接口。Docker守护进程主要监听两种形式的Socket:UNIX socket和TCP socket。

  • UNIX socket:通过入侵UNIX socket可以实现提升权限、逃逸出容器;
  • TCP socket:入侵者通过TCP socket对目标主机上的Docker守护进程下发命令,从而实现对目标主机的控制。只是需要通过-H tcp://参数来设置目标地址和端口。
宿主机操作系统

容器通常与宿主机共享内核。这意味着,如果宿主机内核本身存在安全漏洞,理论上,这些漏洞是能够在容器内进行利用的。通过利用这些漏洞,黑客可能实现权限提升,甚至从容器中逃逸,获得宿主机的控制权。

无法根治的软件漏洞

任何软件都存在漏洞,Docker自然不会例外。在已经曝光的漏洞中,CVE-2019-14271、CVE-2019-5736等漏洞能够导致容器逃逸,属于高危漏洞,其中CVE-2019-14271的CVSS 3.x风险评分更是高达9.8分(满分为10)。