阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker 的镜像并不安全!

135次阅读
没有评论

共计 3809 个字符,预计需要花费 10 分钟才能阅读完成。

最近使用 Docker 下载“官方”容器镜像的时候,我发现这样一句话:

  1. Ubuntu:14.04:The image you are pulling has been verified (您所拉取的镜像已经经过验证)

起初我以为这条信息引自 Docker 大力推广的镜像签名系统,因此也就没有继续跟进。后来,研究加密摘要系统的时候——Docker 用这套系统来对镜像进行安全加固——我才有机会更深入的发现,逻辑上整个与镜像安全相关的部分具有一系列系统性问题。

Docker 的镜像并不安全!

Docker 所报告的,一个已下载的镜像经过“验证”,它基于的仅仅是一个标记清单(signed manifest),而 Docker 却从未据此清单对镜像的校验和进行验证。一名攻击者以此可以提供任意所谓具有标记清单的镜像。一系列严重漏洞的大门就此敞开。

镜像经由 HTTPS 服务器下载后,通过一个未加密的管道流进入 Docker 守护进程:

  1. [decompress]->[tarsum]->[unpack]

这条管道的性能没有问题,但是却完全没有经过加密。不可信的输入在签名验证之前是不应当进入管道的。不幸的是,Docker 在上面处理镜像的三个步骤中,都没有对校验和进行验证。

然而,不论 Docker 如何声明,实际上镜像的校验和(Checksum)从未经过校验。下面是 Docker 与镜像校验和的验证相关的代码片段,即使我提交了校验和不匹配的镜像,都无法触发警告信息。

  1. if img.Checksum!=“”&& img.Checksum!= checksum {
  2. log.Warnf(“image layer checksum mismatch: computed %q,
  3. expected %q”, checksum, img.Checksum)
  4. }

不安全的处理管道

解压缩

Docker 支持三种压缩算法:gzip、bzip2 和 xz。前两种使用 Go 的标准库实现,是内存安全(memory-safe)的,因此这里我预计的攻击类型应该是拒绝服务类的攻击,包括 CPU 和内存使用上的当机或过载等等。

第三种压缩算法,xz,比较有意思。因为没有现成的 Go 实现,Docker 通过执行(exec)xz 二进制命令来实现解压缩。

xz 二进制程序来自于 XZ Utils 项目,由大概 2 万行 C 代码生成而来。而 C 语言不是一门内存安全的语言。这意味着 C 程序的恶意输入,在这里也就是 Docker 镜像的 XZ Utils 解包程序,潜在地存在可能会执行任意代码的风险。

Docker 以 root 权限 运行 xz 命令,更加恶化了这一潜在威胁。这意味着如果在 xz 中出现了一个漏洞,对 docker pull 命令的调用就会导致用户整个系统的完全沦陷。

Tarsum

对 tarsum 的使用,其出发点是好的,但却是最大的败笔。为了得到任意一个加密 tar 文件的准确校验和,Docker 先对 tar 文件进行解密,然后求出特定部分的哈希值,同时排除剩余的部分,而这些步骤的顺序都是固定的。

由于其生成校验和的步骤固定,它解码不可信数据的过程就有可能被设计成攻破 tarsum 的代码。这里潜在的攻击既包括拒绝服务攻击,还有逻辑上的漏洞攻击,可能导致文件被感染、忽略、进程被篡改、植入等等,这一切攻击的同时,校验和可能都是不变的。

解包

解包的过程包括 tar 解码和生成硬盘上的文件。这一过程尤其危险,因为在解包写入硬盘的过程中有另外三个已报告的漏洞。

任何情形下未经验证的数据都不应当解包后直接写入硬盘。

libtrust

Docker 的工具包 libtrust,号称“通过一个分布式的信任图表进行认证和访问控制”。很不幸,对此官方没有任何具体的说明,看起来它好像是实现了一些 javascript 对象标记和加密规格以及其他一些未说明的算法。

使用 libtrust 下载一个清单经过签名和认证的镜像,就可以触发下面这条不准确的信息(说不准确,是因为事实上它验证的只是清单,并非真正的镜像):

  1. ubuntu:14.04:The image you are pulling has been verified(您所拉取的镜像已经经过验证)

目前只有 Docker 公司“官方”发布的镜像清单使用了这套签名系统,但是上次我参加 Docker 管理咨询委员会的会议讨论时,我所理解的是,Docker 公司正计划在未来扩大部署这套系统。他们的目标是以 Docker 公司为中心,控制一个认证授权机构,对镜像进行签名和(或)客户认证。

我试图从 Docker 的代码中找到签名秘钥,但是没找到。好像它并不像我们所期望的把密钥嵌在二进制代码中,而是在每次镜像下载前,由 Docker 守护进程通过 HTTPS 从 CDN 远程获取。这是一个多么糟糕的方案,有无数种攻击手段可能会将可信密钥替换成恶意密钥。这些攻击包括但不限于:CDN 供应商出问题、CDN 初始密钥出现问题、客户端下载时的中间人攻击等等。

补救

研究结束前,我报告了一些在 tarsum 系统中发现的问题,但是截至目前我报告的这些问题仍然没有修复。

要改进 Docker 镜像下载系统的安全问题,我认为应当有以下措施:

摒弃 tarsum 并且真正对镜像本身进行验证

出于安全原因 tarsum 应当被摒弃,同时,镜像在完整下载后、其他步骤开始前,就对镜像的加密签名进行验证。

添加权限隔离

镜像的处理过程中涉及到解压缩或解包的步骤必须在隔离的进程(容器?)中进行,即只给予其操作所需的最小权限。任何场景下都不应当使用 root 运行 xz 这样的解压缩工具。

替换 libtrust

应当用更新框架 (The Update Framework) 替换掉 libtrust,这是专门设计用来解决软件二进制签名此类实际问题的。其威胁模型非常全方位,能够解决 libtrust 中未曾考虑到的诸多问题,目前已经有了完整的说明文档。除了已有的 Python 实现,我已经开始着手用 Go 语言实现的工作,也欢迎大家的贡献。

作为将更新框架加入 Docker 的一部分,还应当加入一个本地密钥存储池,将 root 密钥与 registry 的地址进行映射,这样用户就可以拥有他们自己的签名密钥,而不必使用 Docker 公司的了。

我注意到使用非 Docker 公司官方的第三方仓库往往会是一种非常糟糕的用户体验。Docker 也会将第三方的仓库内容降为二等地位来看待,即使不因为技术上的原因。这个问题不仅仅是生态问题,还是一个终端用户的安全问题。针对第三方仓库的全方位、去中心化的安全模型既必须又迫切。我希望 Docker 公司在重新设计他们的安全模型和镜像认证系统时能采纳这一点。

结论

Docker 用户应当意识到负责下载镜像的代码是非常不安全的。用户们应当只下载那些出处没有问题的镜像。目前,这里的“没有问题”并 包括 Docker 公司的“可信(trusted)”镜像,例如官方的 Ubuntu 和其他基础镜像。

最好的选择就是在本地屏蔽 index.docker.io,然后使用 docker load 命令在导入 Docker 之前手动下载镜像并对其进行验证。Red Hat 的安全博客有一篇很好的文章,大家可以看看。

感谢 Lewis Marshall 指出 tarsum 从未真正验证。

CentOS 6/ 7 系列安装 Docker http://www.linuxidc.com/Linux/2014-07/104768.htm

Docker 的搭建 Gitlab CI 全过程详解 http://www.linuxidc.com/Linux/2013-12/93537.htm

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

在 Docker 中使用 MySQL http://www.linuxidc.com/Linux/2014-01/95354.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

参考

  • 校验和的代码
  • cloc 介绍了 18141 行没有空格没有注释的 C 代码,以及 5900 行的 header 代码,版本号为 v5.2.0。
  • Android 中也发现了类似的 bug,能够感染已签名包中的任意文件。同样出现问题的还有 Windows 的 Authenticode 认证系统,二进制文件会被篡改。
  • 特别的:CVE-2014-6407、CVE-2014-9356 以及 CVE-2014-9357。目前已有两个 Docker 安全发布有了回应。
  • 参见 2014-10-28 DGAB 会议记录的第 8 页。

原文:https://titanous.com/posts/docker-insecurity 作者:titanous
译文:LCTT http://linux.cn/article-4702-1.html 译者:tinyeyeser

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计3809字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中