微服务架构的兴起,容器化部署已经成为时下最流行的生产方式,越来越多的公司将应用部署在基于容器的架构上。自然的,随着容器的广泛使用,容器的安全性就成为了业界关注的焦点,容器安全厂商如雨后春笋般相继成立,如:CoreOSClair、AquaSecurity、Twistlock、Anchore等等。
容器是基于镜像构建的,如果镜像本身就是一个恶意镜像或是一个存在漏洞的镜像,那么基于它搭建的容器自然就是不安全的了,故镜像安全直接决定了容器安全。
为什么容器镜像会产生安全问题?
在传统的部署方式中,应用依赖于操作系统中的环境。在配置好环境后,应用可以稳定地运行。
图1 传统部署结构
但是随着技术的发展,传统部署带来的问题越来越严重。因为多个应用对运行环境的不同要求,导致应用部署产生了很多出乎意料的麻烦,在琐碎的环境问题上消耗了许多精力。
图2 传统部署带来的问题
因此,容器化部署被引进以应对这种情景。容器安装了运行时所需要的环境,并且要求开发人员将他们的应用程序及其所需的依赖关系打包到容器镜像中。 无论其他开发人员和操作系统如何,每个开发人员都可以拥有自己的依赖版本。最终不论是用户还是开发者都在这种部署方案中受益匪浅,开发者可以轻松地在不同环境中测试应用的运行情况,在发布新版本的时候也不必为环境的改变而定制升级教程;用户在使用容器部署时也十分便利,并且不同的软件之间也不会相互影响。
图3 容器化部署结构
理想情况下,容器镜像应该只包含应用程序的二进制文件及其依赖项。 然而实际上,容器镜像往往是相当巨大的。像Ubuntu、Centos这样被广泛使用的基础系统镜像,它们包含了相当多的无用功能。尽管有些功能在调试部署的时候带来了一定的便利,但是在增大的体积面前,收益极低。
图4 容器化部署实际情况
容器实际上是不透明的,被封装成一个个繁琐的镜像。
最终,当越来越多的容器被创建时,没有人再确定容器到底装载了什么?实际运行着什么?
图5 容器部署现状
正是因为如此,我们日常使用的镜像面临严峻的安全问题。随着历年来积累的CVE越来越多,很多应用都存在一些问题,在更新频率低的镜像中尤为严重。
因此,笔者做了一个测试,拉取了Docker Hub上公开热门镜像中的前十页镜像,对其使用Clair进行了CVE扫描统计。结果出乎预料。在一百多个镜像中,没有漏洞的只占到24%,包含高危漏洞的占到67%。很多我们经常使用的镜像都包含在其中,如:Httpd,Nginx,Mysql等等。
图6 扫描示例
图7 扫描结果统计
那我们该如何改善目前的处境呢?
目前Docker安全工具有很多,从多方面来维护容器的安全性,如运行时监控预警、取证、预生产分析、安装配置校验、信任管理等。本文主要关注于镜像在使用之前的扫描和审计,即预生产分析类的工具。这类工具主要从CVE漏洞与恶意镜像两方面来对镜像进行扫描。
接下类介绍三款有代表性的镜像安全工具,分别针对CVE检测,恶意镜像产生,恶意镜像检测:
Clair :
Clair的目标是能够从一个更加透明的维度去看待基于容器化基础框架的安全性,Clair是由CoreOS所推出的这样一款针对容器镜像的安全扫描工具。 Clair主要模块分为Detector、Fetcher、Notifier和Webhook,Clair首先对镜像进行特征的提取,然后再将这些特征匹配CVE漏洞库,若发现漏洞则进行提示,其功能侧重于扫描容器中的OS及APP的CVE漏洞。
Clair是扫描引擎,启动后暴露API等待调用。在这里笔者使用clairctl(一个第三方调用工具)来对Clair发出调用请求,从而完成扫描。
下图为clairctl的基本命令介绍,基本命令如图所示,详情了解某一条的用法在命令后加上–help参数即可。
图8 Clair示例
上图使用Clair对本地(-l 参数)镜像Centos进行了一次扫描,扫描结果为没有漏洞,随后生成报告,保存在/reports/html/analysis-centos-latest.heml,用浏览器打开即可查看详情。
Dockerscan:
Dockerscan是一个分析、攻击工具。它可以在网络中找出镜像仓库所在的主机,可以在镜像中插入木马,查看镜像中的敏感信息等等。
下图为Dockerscan基本命令,以及一次对 223.****.210/28 这个小网段进行一次探测容器仓库扫描。探测发现两台网易的容器仓库。
图9 Dockerscan扫描示例
下图为获取mysql_origin镜像的基本信息,可以看到该镜像被植入一个反弹shell,接收shell的端口为2222,地址为 10.****.8。
图10 Dockerscan查看镜像信息
下图为利用Dockerscan攻击受害者的流程,将木马植入正常镜像Nginx中,当用户运行该镜像时,攻击者就会接收到反弹出的shell,从而达到控制服务器的目的。
图11 Dockescan攻击链
下图为使用实例,白窗为Dockerscan容器,黑窗为容器所在宿主机,宿主机/tmp目录挂载在容器~/images 目录。首先在宿主机/tmp目录下将镜像保存为文件(docker save -o filename imagename),然后再容器中可以看到该镜像文件,然后使用dockerscan修改镜像,将木马植入该镜像,接受地址设置为 10.****.8(我的宿主机),端口为2222,
保存为evil.tar(植入木马的mysql镜像文件),随后在本地监听2222端口(nc -v -k -l 2222),然后再宿主机导入注入木马的镜像(docker load -i evil.tar),随后运行该镜像,
监听端口随即收到反弹出的shell,执行命令测试。
图12 Dockerscan使用示例
Anchore:
Clair能扫描出一个镜像中的所有CVE漏洞,但现在有一种情况,黑客使用最新版无漏洞的OS镜像,然后在其之上安装后门木马,或执行恶意命令,这样Clair就不能检测其安全性了。
这时就要介绍一个分析工具Anchorele,与Clair不同,Anchore侧重于对镜像的审计,其有强大的对镜像的解析能力。在分析之后可以对镜像进行多种操作,内置了许多脚本,用途广泛。
下图为Anchore使用命令截图,初次使用要先使用feeds list和 feeds sync来同步漏洞库。接下来有使用示例命令,在这里不多做介绍了。在有想了解的命令时,加上–help参数即可查看详细介绍。
图13 Anchore使用命令
这里介绍几个常用的命令,query命令是调用已有模块对镜像进行相应的操作,调用不同的脚本需要不同的参数。接下来调用一个模块做演示。
图14 Anchore query功能
在这里,我们想调用show-file-diffs模块来对比两个镜像的差别,在之前,我们需要首先先分析两个镜像mysql:evil 和 origin:origin,这是上个环节使用dockerscan生成的恶意镜像和原始镜像。接下来调用该模块,可以看到差别是在/usr/share/lib目录下多了一个反弹shell的文件。
图15 Anchore 示例
下图是toolbox命令的详情,里面有一些使用的小工具,接下里我们尝试几个命令。
show-familytree 、 show-taghistory、show-layers、show-dockerfile,来查看镜像registry的镜像关系,版本历史,镜像的层,还有镜像构建文件。
图16 Anchore功能示例
图17 Anchore功能示例
镜像安全决定了容器安全,而目前Docker Hub上的镜像76%都存在漏洞,所以我们使用镜像运行容器前,一定要对镜像镜像进行扫描,从而提高安全性。