使用GitlabCI和Trivy

介绍

如今,镜像安全扫描变得越来越流行。这个想法是分析一个Docker镜像并基于CVE数据库寻找漏洞。这样,我们可以在使用镜像之前知道其包含哪些漏洞,因此我们只能在生产中使用“安全”镜像。

有多种分析Docker镜像的方法(取决于您使用的工具)。可以从CLI执行安全扫描,也可以将其直接集成到Container Registry中,或者更好(在我看来),您可以将安全扫描集成到CI/CD管道中。最后一种方法很酷,因为它使我们能够自动化流程并不断分析所生成的图像,从而符合DevOps的理念。

这是一个简单的例子:

因此,今天我将向您展示如何设置集成到CI/CD管道中的镜像安全扫描。

工具类

有多种工具可以执行镜像安全扫描:

  • Trivy:由AquaSecurity开发。
  • Anchore:由Anchore Inc.开发。
  • Clair:由Quay开发。
  • Docker Trusted Registry:如果您使用Docker Enterprise,尤其是Docker Trusted Registry,则可以使用直接集成在注册表中的即用型安全扫描程序。
  • Azure/AWS/GCP:如果您使用这些云提供程序之一,则可以轻松设置安全扫描。实际上,您不需要进行任何设置,只需要您的信用卡即可。:)

当然,还有更多开放源代码或专有工具可以实现该目标。对于本教程,我将在GitlabCI管道上使用Trivy。

Trivy快速概述

Trivy是一种易于使用但准确的图像安全扫描仪。安装非常简单:

$ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s--b / usr / local / bin $ sudo mv ./bin/trivy / usr / local / bin / trivy $ trivy --version 

及其用法:

$ trivy image nginx:alpine

给我们这样的输出:

就如此容易。

有关更多信息:Trivy的Github

添加一个简单的Docker镜像

为了说明将安全扫描包含在CI/CD管道中,我们需要一个Docker镜像作为示例。我将使用该简单的Dockerfile:

FROM debian:busterRUN apt-get update && apt-get install nginx -y

这个Dockerfile非常简单。它从正式的debian buster映像开始,并添加了nginx的安装。

我们稍后将在CI/CD管道中构建该映像,但是我们可以如下构建它:

$ docker build -t security_scan_example:latest。

现在,我们只需要创建一个Gitlab项目并将Dockerfile推送到该项目中即可。

创建一个简单的CI/CD管道

现在,我们已经为示例镜像创建了Dockerfile,我们可以创建CI/CD管道来构建镜像并使用Trivy对其进行扫描。

毫不奇怪,由于我们正在使用Gitlab,因此我们将在我们的CI/CD管道中使用GitlabCI。首先,让我们添加构建部分:

build:  stage: build  image: docker:stable  services:    - docker:dind  tags:    - docker  before_script:    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY  script:    - docker build -t $CI_REGISTRY_IMAGE:latest  .    - docker push $CI_REGISTRY_IMAGE:latest

该作业在基于docker:stable映像的容器上运行。它基于我们之前推送的Dockerfile构建项目的映像,然后将映像推送到Gitlab容器注册表中。

现在让我们添加有趣的部分:

security_scan:  stage: test  image:     name: aquasec/trivy:latest    entrypoint: [""]  services:    - docker:dind  tags:    - docker  script:    - trivy --no-progress --output scanning-report.txt  $CI_REGISTRY_IMAGE:latest  artifacts:    reports:      container_scanning: scanning-report.txt

这项工作是我们的安全扫描工作。这次,它在基于Trivy官方图像的容器上运行。它基于trivy命令扫描镜像,并将报告输出到名为scanning-report.txt的文件中

太好了!让我们看一下我们的GitlabCI管道,该管道应该在推送后自动运行。我们可以看到我们的两个作业都成功运行了:

让我们看一下安全扫描作业:

images

报告在哪里?

如您在扫描作业的结果中看到的,我们有多个漏洞,更确切地说是114个“低”和8个“中”,24个“高”和1个“严重”漏洞。

我们希望获得有关这些漏洞的更多详细信息。默认情况下,Trivy在标准输出中打印报告。在此示例中,我们告诉trivy将报告输出到文件中,并根据该文件创建了作业工件。因此,该报告可按以下方式下载:

images

下载后,我们可以查看报告以获取更多详细信息:

images

我们可以看到我们有更多有关扫描程序发现的漏洞的信息,例如受影响的库/二进制文件,CVE ID,严重性,可能的修复程序等。

现在怎么办 ?

好的,现在我们已经将镜像扫描集成到CI / CD管道中,现在的问题是如何处理这些信息?

当前,安全扫描作业永远不会失败,因为trivy命令默认情况下返回0。如果镜像“不安全”,则使工作失败,否则,则可以使工作成功,从而改善这种情况。

问题是,什么时候失败?显然,我们不能简单地说“每当发现一个漏洞时就会失败”,因为我们的映像很可能至少会存在一些漏洞。答案很难说,因为它取决于您要实现的安全级别。通常,我们希望尽可能避免严重漏洞。答案还取决于您获得的漏洞。您能忽略其中一些吗?这取决于您。这就是为什么与安全团队持续合作可以从这些扫描中受益匪浅的原因。

对于此示例,如果我们只有一个严重漏洞,我们将使我们的CI/CD管道失败,否则将成功。

幸运的是,trivy允许我们使用“严重性”选项仅查找特定严重性的漏洞。我们还可以借助“退出代码”选项来处理退出代码,告诉trivy如果发现一个漏洞,则返回1,否则返回0。

因此,如果发现一个或多个“关键”漏洞,我们将更改扫描作业以使其失败,例如:

script:  - trivy --no-progress --output scanning-report.json $CI_REGISTRY_IMAGE:latest  - trivy --exit-code 1 --no-progress --severity CRITICAL $CI_REGISTR_IMAGE:latest

因此,当执行我们的作业时,我们仍然可以下载完整的报告,但是这次,CI/CD作业将成功还是失败,这取决于trivy是否发现了严重漏洞:

最后一步……

好的,我们的CI/CD管道看起来很棒!我们需要处理最后一件事……

目前,仅在构建/推送图像时才对其进行分析。这很酷,但不足。确实,我们的扫描工具使用的CVE数据库每天都有新的漏洞在发展。今天的“安全”镜像明天可能(而且很可能)不安全。因此,我们需要在第一次推送图像后继续对其进行扫描。

好吧,让我们添加一个计划的管道,比如说每晚2AM扫描镜像。我们需要进入CI/CD->时间表->新时间表:

注意:我们使用“ security_scan”值定义了一个名为SCHEDULED_PIPELINE的变量。稍后我们将看到此变量的目的。

这样做,我们的管道将被完全执行,包括构建部分。这不是我们真正想要的。因此,我们将修改gitlabCI文件,以使计划的管道仅执行扫描作业。

我们将添加一个额外的扫描作业,其中包含与上一个作业完全相同的定义,并带有一个额外的“only”选项,使其仅在变量SCHEDULED_PIPELINE(我们先前在计划的管道中定义)等于“ scanning_scan”时才可执行。为了避免代码冗余,我们将使用作业模板。

因此,我们最终的gitlabCI文件如下所示:

.scanning-template: &scanning-template  stage: test  image:    name: aquasec/trivy:latest    entrypoint: [""]  services:    - docker:dind  tags:    - docker  script:    - trivy --no-progress --output scanning-report.json  $CI_REGISTRY_IMAGE:latest    - trivy --exit-code 1 --no-progress --severity CRITICAL $CI_REGISTR_IMAGE:latest  artifacts:    reports:      container_scanning: scanning-report.jsonbuild:  stage: build  image: docker:stable  services:    - docker:dind  tags:    - docker  before_script:    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY  script:    - docker build -t $CI_REGISTRY_IMAGE:latest  .    - docker push $CI_REGISTRY_IMAGE:latest  except:    variables:      - $SCHEDULED_PIPELINEsecurity_scan:  <<:>  except:    variables:      - $SCHEDULED_PIPELINEsecurity_scan:on-schedule:  <<:>  only:    variables:      - $SCHEDULED_PIPELINE == "security_scan"

这样,当我们推送一些代码时,我们的标准管道(构建+扫描)将正常执行,而调度的管道将每天凌晨2点执行安全扫描作业。

我们如何解决这些漏洞?

通常,通过升级映像。在我们的情况下,我们可能会升级基础映像(或者可能使用另一个镜像,例如Alpine)或升级我们安装的nginx。

另一个答案可能是通过删除映像中不必要的内容,无论如何构建docker映像都是一个好习惯。安全扫描可以帮助您检测实际未使用的组件。

在我们的情况下,让我们更改基本图像并改为使用Alpine:

FROM alpine:3.12RUN apk update && apk add nginx -y

这次,我们的管道成功了……:

……没有一个漏洞。

结论

因此,我们已经看到了如何将安全扫描作业集成到GitlabCI管道中,这非常简单(至少使用Trivy)。当然,在我的示例中,我在单个master分支中完成了所有操作。在现实世界中,我们将进行多分支项目,这需要进行一些调整。

关于我们

泽阳,DevOps领域实践者。专注于企业级DevOps运维开发技术实践分享,主要以新Linux运维技术、DevOps技术课程为主。丰富的一线实战经验,课程追求实用性获得多数学员认可。课程内容均来源于企业应用,在这里既学习技术又能获取热门技能,欢迎您的到来!(微信ID: devopsvip)

DevOps流水线实践课程

?戳阅读原文,进入课堂

sudo apt install镜像_将Docker镜像安全扫描步骤添加到CI/CD管道相关推荐

  1. docker 删除所有镜像_关于 Docker 镜像的操作,看完这篇就够啦 !(下)| 文末福利...

    紧接着上篇<关于 Docker 镜像的操作,看完这篇就够啦 !(上)>,奉上下篇 !!! 镜像作为 Docker 三大核心概念中最重要的一个关键词,它有很多操作,是您想学习容器技术不得不掌 ...

  2. docker看远程仓库镜像_查看Docker镜像仓库中镜像的所有标签

    用 Docker 的人都知道,我们在查询远端镜像仓库中镜像的时候,在命令行只能看到镜像名,说明等信息,而看不到标签.因此,如果我想要查看镜像有哪些标签,就只能通过网页的方式查看,比如通过 https: ...

  3. docker $PWD路径_深入浅出Docker 镜像

    技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作为云计算的当红明星Docker 来势汹汹,它就像一场森林大火,烧到了我们中间.因为工作的原因, ...

  4. docker desktop ubuntu镜像_「Docker」 - 镜像仓库

    一.镜像仓库 将Docker镜像和Git进行对比,镜像仓库类似GitHub.GitLab等托管平台,Docker的镜像仓库托管的不是代码项目,而是镜像. Docker镜像仓库最大的作用是实现了Dock ...

  5. sudo apt install ...

    在使用apt安装任何软件包之前,建议使用以下命令更新软件包列表: sudo apt update ----------------------------------------------- Ubu ...

  6. sudo apt install 遇到关于 lock 的错误消息

    当我在 ubuntu 里使用 sudo apt install 试图安装应用时,遇到如下错误: Could not get lock /var/lib/dpkg/lock-frontend 错误消息说 ...

  7. docker 根据标签删除镜像_10 个 Docker 镜像安全最佳实践

    <Docker 镜像安全最佳实践速查表[1]>列举了 10 个诀窍和指南,确保更安全和更高质量的 Docker 镜像处理.此外,还可以检视有关 Docker 安全的新报告<Docke ...

  8. linux中运行ifconfig出现错误,不能sudo apt install net-tools,Linux不能联网

    linux中运行ifconfig出现错误,且不能sudo apt install net-tools linux中运行ifconfig出现错误 不能sudo apt install net-tools ...

  9. Command ‘ifconfig‘ not found, but can be installed with: sudo apt install net-tools VM Ubuntu 解决方案

    Command 'ifconfig' not found, but can be installed with: sudo apt install net-tools VM Ubuntu 解决方案 参 ...

最新文章

  1. 数据库连接池到底应该设多大?
  2. linux下的解压命令
  3. MCtalk 创业声音丨辉禹科技合伙人孔杰:投资和创业都是思维的放大器
  4. 模糊推理机制 matlab,基于模糊综合评判推理机制的学生素质评价系统设计与实现...
  5. flutter text 最大长度_Flutter小技巧之TextField换行自适应
  6. linux vim 单引号,单引号和双引号的区别、linux快捷键、zip压缩、lrzsz、vim常见问题...
  7. efcore 批量_【EF Core】Entity Framework Core 批处理语句
  8. java应用程序如何编译运作_开发Java应用程序的基本步骤是: 1 编写源文件, 2.编译源文件, 3.运行程序。_学小易找答案...
  9. 自学JAVA-2:数据类型与运算符
  10. 2021,前方路艰,与君共勉
  11. 新ICT:引爆物联网的变革潜能
  12. python把两张图片合成一张_怎么合成图片-利用Python将两张图片合成为一张图
  13. 使用内核模块添加系统调用
  14. 知识产权行业获客难?一招解决
  15. 人民大学与加拿大女王大学金融硕士——你终究会成为你想成为的人
  16. 一幅长文细学GaussDB(二)——数据库基础知识
  17. 使用yarn add安装依赖时报错‘error An unexpected error occurred: “EINVAL: invalid argument, unlink ’
  18. 【花雕动手做】有趣好玩的音乐可视化系列小项目(17)--光导纤维灯
  19. TC35i的TxD和RxD引脚定义
  20. android中实现更溜的字母导航索引

热门文章

  1. boost::type_erasure::any_cast相关的测试程序
  2. boost::mpl模块实现find_if相关的测试程序
  3. boost::geometry模块实现递归多边形线性区域的测试程序
  4. boost::geometry模块多边形DP算法简化示例
  5. boost::filesystem模块实现打印window属性的测试程序
  6. GDCM:gdcm::GroupDict的测试程序
  7. Boost: 检查underlying_type特性是否有效的测试程序
  8. boost::callable_traits的has_varargs的测试程序
  9. VTK:可视化之NamedColorPatches
  10. VTK:可视化之DisplayCoordinateAxes