mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
PUB:20150104 Docker Image Insecurity
@tinyeyeser
This commit is contained in:
parent
7e84dad563
commit
0bed6db015
@ -6,7 +6,7 @@ Docker的镜像并不安全!
|
||||
|
||||
起初我以为这条信息引自Docker[大力推广][1]的镜像签名系统,因此也就没有继续跟进。后来,研究加密摘要系统的时候——Docker用这套系统来对镜像进行安全加固——我才有机会更深入的发现,逻辑上整个与镜像安全相关的部分具有一系列系统性问题。
|
||||
|
||||
Docker所报告的,一个已下载的镜像经过“验证”,它基于的仅仅是一个标记清单(signed manifest),而Docker却从未根据清单对镜像的校验和进行验证。一名攻击者以此可以提供任意所谓具有标记清单的镜像。一系列严重漏洞的大门就此敞开。
|
||||
Docker所报告的,一个已下载的镜像经过“验证”,它基于的仅仅是一个标记清单(signed manifest),而Docker却从未据此清单对镜像的校验和进行验证。一名攻击者以此可以提供任意所谓具有标记清单的镜像。一系列严重漏洞的大门就此敞开。
|
||||
|
||||
镜像经由HTTPS服务器下载后,通过一个未加密的管道流进入Docker守护进程:
|
||||
|
||||
@ -14,7 +14,7 @@ Docker所报告的,一个已下载的镜像经过“验证”,它基于的
|
||||
|
||||
这条管道的性能没有问题,但是却完全没有经过加密。不可信的输入在签名验证之前是不应当进入管道的。不幸的是,Docker在上面处理镜像的三个步骤中,都没有对校验和进行验证。
|
||||
|
||||
然而,不论Docker如何[声明][2],实际上镜像的校验和从未经过校验。下面是Docker与镜像校验和的验证相关的代码[片段][3],即使我提交了校验和不匹配的镜像,都无法触发警告信息。
|
||||
然而,不论Docker如何[声明][2],实际上镜像的校验和(Checksum)从未经过校验。下面是Docker与镜像校验和的验证相关的代码[片段][3],即使我提交了校验和不匹配的镜像,都无法触发警告信息。
|
||||
|
||||
if img.Checksum != "" && img.Checksum != checksum {
|
||||
log.Warnf("image layer checksum mismatch: computed %q,
|
||||
@ -29,7 +29,7 @@ Docker支持三种压缩算法:gzip、bzip2和xz。前两种使用Go的标准
|
||||
|
||||
第三种压缩算法,xz,比较有意思。因为没有现成的Go实现,Docker 通过[执行(exec)][5]`xz`二进制命令来实现解压缩。
|
||||
|
||||
xz二进制程序来自于[XZ Utils][6]项目,由[大概][7]2万行C代码生成而来。而C语言不是一门内存安全的语言。这意味着C程序的恶意输入,在这里也就是Docker镜像的XZ Utils解包程序,潜在地可能会执行任意代码。
|
||||
xz二进制程序来自于[XZ Utils][6]项目,由[大概][7]2万行C代码生成而来。而C语言不是一门内存安全的语言。这意味着C程序的恶意输入,在这里也就是Docker镜像的XZ Utils解包程序,潜在地存在可能会执行任意代码的风险。
|
||||
|
||||
Docker以root权限*运行* `xz` 命令,更加恶化了这一潜在威胁。这意味着如果在`xz`中出现了一个漏洞,对`docker pull`命令的调用就会导致用户整个系统的完全沦陷。
|
||||
|
||||
@ -39,7 +39,6 @@ Docker以root权限*运行* `xz` 命令,更加恶化了这一潜在威胁。
|
||||
|
||||
由于其生成校验和的步骤固定,它解码不可信数据的过程就有可能被设计成[攻破tarsum的代码][9]。这里潜在的攻击既包括拒绝服务攻击,还有逻辑上的漏洞攻击,可能导致文件被感染、忽略、进程被篡改、植入等等,这一切攻击的同时,校验和可能都是不变的。
|
||||
|
||||
|
||||
**解包**
|
||||
|
||||
解包的过程包括tar解码和生成硬盘上的文件。这一过程尤其危险,因为在解包写入硬盘的过程中有另外三个[已报告的漏洞][10]。
|
||||
@ -60,8 +59,7 @@ Docker的工具包[libtrust][11],号称“通过一个分布式的信任图表
|
||||
|
||||
### 补救 ###
|
||||
|
||||
研究结束前,我[报告][15]了一些在tarsum系统中发现的问题,但是截至目前我报告的这些问题仍然
|
||||
没有修复。
|
||||
研究结束前,我[报告][15]了一些在tarsum系统中发现的问题,但是截至目前我报告的这些问题仍然没有修复。
|
||||
|
||||
要改进Docker镜像下载系统的安全问题,我认为应当有以下措施:
|
||||
|
||||
@ -79,16 +77,18 @@ Docker的工具包[libtrust][11],号称“通过一个分布式的信任图表
|
||||
|
||||
作为将更新框架加入Docker的一部分,还应当加入一个本地密钥存储池,将root密钥与registry的地址进行映射,这样用户就可以拥有他们自己的签名密钥,而不必使用Docker公司的了。
|
||||
|
||||
我注意到使用Docker公司非官方的宿主仓库往往会是一种非常糟糕的用户体验。当没有技术上的原因时,Docker也会将第三方的仓库内容降为二等地位来看待。这个问题不仅仅是生态问题,还是一个终端用户的安全问题。针对第三方仓库的全方位、去中心化的安全模型即必须又迫切。我希望Docker公司在重新设计他们的安全模型和镜像认证系统时能采纳这一点。
|
||||
我注意到使用非Docker公司官方的第三方仓库往往会是一种非常糟糕的用户体验。Docker也会将第三方的仓库内容降为二等地位来看待,即使不因为技术上的原因。这个问题不仅仅是生态问题,还是一个终端用户的安全问题。针对第三方仓库的全方位、去中心化的安全模型既必须又迫切。我希望Docker公司在重新设计他们的安全模型和镜像认证系统时能采纳这一点。
|
||||
|
||||
### 结论 ###
|
||||
|
||||
Docker用户应当意识到负责下载镜像的代码是非常不安全的。用户们应当只下载那些出处没有问题的镜像。目前,这里的“没有问题”并不包括Docker公司的“可信(trusted)”镜像,例如官方的Ubuntu和其他基础镜像。
|
||||
Docker用户应当意识到负责下载镜像的代码是非常不安全的。用户们应当只下载那些出处没有问题的镜像。目前,这里的“没有问题”并**不**包括Docker公司的“可信(trusted)”镜像,例如官方的Ubuntu和其他基础镜像。
|
||||
|
||||
最好的选择就是在本地屏蔽 `index.docker.io`,然后使用`docker load`命令在导入Docker之前手动下载镜像并对其进行验证。Red Hat的安全博客有一篇[很好的文章][18],大家可以看看。
|
||||
|
||||
感谢Lewis Marshall指出tarsum从未真正验证。
|
||||
|
||||
参考
|
||||
|
||||
- [校验和的代码][19]
|
||||
- [cloc][20]介绍了18141行没有空格没有注释的C代码,以及5900行的header代码,版本号为v5.2.0。
|
||||
- [Android中也发现了][21]类似的bug,能够感染已签名包中的任意文件。同样出现问题的还有[Windows的Authenticode][22]认证系统,二进制文件会被篡改。
|
||||
@ -101,7 +101,7 @@ via: https://titanous.com/posts/docker-insecurity
|
||||
|
||||
作者:[titanous][a]
|
||||
译者:[Mr小眼儿](http://blog.csdn.net/tinyeyeser)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](http://linux.cn/) 荣誉推出
|
||||
|
Loading…
Reference in New Issue
Block a user