一、前言
最近几年容器化技术快速发展,各大互联网厂商也都开始使用容器化技术,而如何保证容器安全便是撰写本文的目的之一。Anchore Engine的功能之一是可以基于CVE数据来对容器镜像进行漏洞扫描,从而发现是否存在安全漏洞和策略问题。本文将从两个部分来讲解Anchore Engine的使用:
基于Anchore-cli客户端的使用
与Jenkins结合完善DevSecOps
二、Anchore Engine的安装
使用Docker Compose进行安装
Anchore Engine支持docker-compose或者helm来进行安装,在此我们使用最简单的docker-compose来进行安装测试。
1.命令如下:
# curl https://docs.anchore.com/current/docs/engine/quickstart/docker-compose.yaml > docker-compose.yaml # docker-compose up -d
2.查看部署是否成功:
# docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------- root_analyzer_1 /docker-entrypoint.sh anch ... Up 8228/tcp root_api_1 /docker-entrypoint.sh anch ... Up 0.0.0.0:8228->8228/tcp root_catalog_1 /docker-entrypoint.sh anch ... Up 8228/tcp root_db_1 docker-entrypoint.sh postgres Up 5432/tcp root_policy-engine_1 /docker-entrypoint.sh anch ... Up 8228/tcp root_queue_1 /docker-entrypoint.sh anch ... Up 8228/tcp # docker-compose exec api anchore-cli system status Service analyzer (anchore-quickstart, http://analyzer:8228): up Service simplequeue (anchore-quickstart, http://queue:8228): up Service apiext (anchore-quickstart, http://api:8228): up Service policy_engine (anchore-quickstart, http://policy-engine:8228): up Service catalog (anchore-quickstart, http://catalog:8228): up Engine DB Version: 0.0.13 Engine Code Version: 0.7.1
3.等待漏洞库更新完毕,这里需要注意的是因为漏洞库在国外,所以更新过程需要很长时间,几个小时甚至一天都是有可能的,请耐心等待。当RecordCount列的值都不是None的时候,漏洞库就算更新完毕了。
# docker-compose exec api anchore-cli system wait Starting checks to wait for anchore-engine to be available timeout=-1.0 interval=5.0 API availability: Checking anchore-engine URL (http://localhost:8228)... API availability: Success. Service availability: Checking for service set (catalog,apiext,policy_engine,simplequeue,analyzer)... Service availability: Success. Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... Feed sync: Checking sync completion for feed set (vulnerabilities)... # docker-compose exec api anchore-cli system feeds list //查看更新情况,状态是pending代表等待更新 Feed Group LastSync RecordCount github github:composer pending None github github:gem pending None github github:java pending None github github:npm pending None github github:nuget pending None github github:python pending None nvdv2 nvdv2:cves pending None vulnerabilities alpine:3.10 2020-06-22T03:08:25.647466 1725 vulnerabilities alpine:3.11 2020-06-22T03:08:44.098248 1904 vulnerabilities alpine:3.3 2020-06-22T03:09:03.977480 457 vulnerabilities alpine:3.4 2020-06-22T03:09:09.253906 681 vulnerabilities alpine:3.5 2020-06-22T03:09:16.594355 875 vulnerabilities alpine:3.6 pending 1000 vulnerabilities alpine:3.7 pending None
三、基于Anchore-cli客户端的使用
扫描指定镜像
1.添加镜像到anchore
# docker-compose exec api anchore-cli image add docker.io/library/ubuntu:20.04 Image Digest: sha256:93fd0705706e5bdda6cc450b384d8d5afb18fecc19e054fe3d7a2c8c2aeb2c83 Parent Digest: sha256:52259450119427dab05c0c455121c48d7b04cee2d61b5dbdde1219b2163af572 Analysis Status: not_analyzed Image Type: docker Analyzed At: None Image ID: 74435f89ab7825e19cf8c92c7b5c5ebd73ae2d0a2be16f49b3fb81c9062ab303 Dockerfile Mode: None Distro: None Distro Version: None Size: None Architecture: None Layer Count: None Full Tag: docker.io/library/ubuntu:20.04 Tag Detected At: 2020-06-22T07:19:18Z
2.查看扫描状态,Analysis Status为analyzed代表扫描结束
# docker-compose exec api anchore-cli image list Full Tag Image Digest Analysis Status docker.io/library/ubuntu:20.04 sha256:93fd0705706e5bdda6cc450b384d8d5afb18fecc19e054fe3d7a2c8c2aeb2c83 analyzed
3.接着查看扫描结果
# docker-compose exec api anchore-cli image vuln docker.io/library/ubuntu:20.04 all Vulnerability ID Package Severity Fix CVE Refs Vulnerability URL Type Feed Group Package Path CVE-2013-4235 login-1:4.8.1-1ubuntu5 Low None CVE-2013-4235 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2013-4235 dpkg ubuntu:20.04 pkgdb CVE-2013-4235 passwd-1:4.8.1-1ubuntu5 Low None CVE-2013-4235 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2013-4235 dpkg ubuntu:20.04 pkgdb CVE-2016-2781 coreutils-8.30-3ubuntu2 Low None CVE-2016-2781 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2016-2781 dpkg ubuntu:20.04 pkgdb CVE-2018-7169 login-1:4.8.1-1ubuntu5 Low None CVE-2018-7169 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-7169 dpkg ubuntu:20.04 pkgdb CVE-2018-7169 passwd-1:4.8.1-1ubuntu5 Low None CVE-2018-7169 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2018-7169 dpkg ubuntu:20.04 pkgdb CVE-2019-12904 libgcrypt20-1.8.5-5ubuntu1 Low None CVE-2019-12904 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-12904 dpkg ubuntu:20.04 pkgdb CVE-2019-13050 gpgv-2.2.19-3ubuntu2 Low None CVE-2019-13050 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-13050 dpkg ubuntu:20.04 pkgdb CVE-2019-18276 bash-5.0-6ubuntu1 Low None CVE-2019-18276 http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-18276 dpkg ubuntu:20.04 pkgdb
这就是最简单的扫描镜像方法:把镜像添加到扫描引擎,等待扫描结束然后查看扫描结果。但是这种方式基本不适用实际的工作场景,所以文章的下一部分将阐述如何把Anchore Engine应用到实际工作中。
四、与Jenkins结合应用到DevSecOps中
在传统的开发流程中,安全工作通常是作为最后一步进行。这就导致了一旦发现问题,修复的人力、时间等成本都会很高,而且通常安全问题影响的可能不仅仅是开发,甚至会改变需求和架构。而将“安全左移”,其目的就是为了降低修复问题的成本。
目前容器化技术快速发展,导致很多厂商改变了传统的部署方式,转而使用类似K8S+jenkins+harbor的组合。先看下这套经典组合的架构:
1.开发人员提交代码到gitlab等代码仓库
2.通过手动执行jenkins构建(或者配置webhook触发jenkins执行构建),下载代码仓库里的最新代码
3.通过mvn编译生成jar包,并进行一系列的静态分析、单元测试等工作
4.测试成功后开始通过docker build命令把jar包构建成镜像
5.把生成的镜像push到harbor镜像仓库中
6.通过k8s拉取harbor上的镜像进行创建容器和服务,最终发布完成
按照DevSecOps里安全左移的原则,我们选择在第五步构建镜像后进行镜像扫描。下面笔者将用一个示例来展示如何使用jenkins+anchore实现自动化镜像扫描。
安装插件
从Jenkins主菜单中选择Manage Plugins。
单击【可选插件】然后在过滤框里输入【anchore】,选中【Anchore Container Image Scanner】后点击【直接安装】。
配置anchore插件
点击【Manage Jenkins】->【configure system】,找到【Anchore Container Image Scanner】,输入anchore engine的详细信息:
Engine URL:anchore engine的url地址(默认都是http://your_anchore_engine_IP:8228/v1)
Engine Username:用户名(默认admin)
Engine Password:密码(默认foobar)
添加docker仓库帐号
点击凭据->系统->全局凭据->添加凭证,添加一个hub.docker.com的帐号,id随便填写,这里填写hub.docker.com。点击【确定】完成添加
在流水线中添加扫描镜像
在这个示例中,我们将使用pipeline进行构建:
在jenkins中新建一个任务并选择pipe line,在【流水线】里输入以下脚本后点击保存
pipeline { environment { registry = "zj1244/demo" //仓库地址,用于把镜像push到镜像仓库。按照实际情况修改 registryCredential = 'hub.docker.com' //用于登陆镜像仓库的凭证,按照实际情况修改 } agent any stages { //jenkins从代码仓库里下载代码 stage('Cloning Git') { steps { git 'https://github.com/zj1244/docker-dvwa.git' } } //构建镜像 stage('Build Image') { steps { script { app = docker.build(registry+ ":$BUILD_NUMBER") } } } //把镜像推送到仓库 stage('Push Image') { steps { script { docker.withRegistry('', registryCredential ) { app.push() } } } } //镜像扫描 stage('Container Security Scan') { steps { sh 'echo "'+registry+':$BUILD_NUMBER `pwd`/Dockerfile" > anchore_images' anchore engineRetries: "240", name: 'anchore_images' } } stage('Cleanup') { steps { sh script: "docker rmi " + registry+ ":$BUILD_NUMBER" } } } }
最后点击【立即构建】开始进行构建
查看结果
构建结束后,点击【Anchore Report (FAIL)】查看扫描报告
报告会给出扫描结果是FAIL还是PASS,默认情况下存在漏洞将导致构建失败
整合结果
在实际工作中经常会出现一天发版几十次的情况,这种频率下在jenkins上查看扫描结果显然很不方便,所以有个图形界面来进行统计就很有必要了。anchore企业版倒是提供了UI界面,但是企业版是需要收费的,所以笔者简单做了个UI界面对扫描结果进行了整合
总结
本文介绍了Anchore Engine的一些基本用法,包括如何和jenkins结合,欢迎大家批评指正。也希望借此抛砖引玉,有好的建议大家一起交流共同进步。最后给出anchore ui的github地址,有需要的朋友自取
来源:freebuf.com 2020-07-02 20:03:48 by: zj1244
请登录后发表评论
注册