现在很多团队面临着这么一个挑战:如何在不减慢应用交付速度的情况下,管理好安全风险。有种方法可以解决该问题,就是采用安全的 DevOps 工作流程

安全的DevOps(也称为DevSecOps)会在从开发到生产的整个应用程序声明周期中提供安全性以及监控功能,帮助我们交付安全、稳定和高性能的应用程序。如果我们把该工作流程插入现有的工具链中,可以为DevOps、开发人员和安全团队最大程度地提高效率。

DevSecOps五个基本工作流程包括镜像扫描、运行安全、合规性、Kubernetes和容器的监控以及应用程序和云服务监控。

镜像扫描是嵌入到DevSecOps工作流程中的一项关键功能。作为第一道防线,它可以帮助我们在漏洞被利用之前检测到漏洞并阻止,另外,它还易于实现并可自动化。本文将介绍多个镜像扫描的最佳实践和技巧,帮助大家采用有效的容器镜像扫描策略。

什么是容器镜像扫描

镜像扫描是指分析容器镜像的内容和构建过程,以检测安全问题、漏洞或错误实践。

我们可以从多个 Feed(NVD、Alpine、Cannonical等)中收集"通用漏洞披漏(CVE)"信息,以检查镜像是否容易受到攻击,其中有些还提供了开箱即用的扫描规则,以查找最常见的安全问题和错误实践。

镜像扫描可以轻松被集成到DevSecOps工作流程的多个步骤中,例如集成到CI/CD管道中,阻止漏洞到达注册表;集成在注册表中,防止第三方镜像中的漏洞;也可以在运行时集成,防止新发现的CVE。

当我们遵循并执行最佳实践时,镜像扫描可确保团队不会因部署应用程序而导致交付速度变慢。现在让我们深入了解这 12 种镜像扫描最佳实践。

12 种镜像扫描最佳实践

1.将镜像扫描嵌入到 CI/CD 管道中

构建容器镜像时,我们应格外小心,并在镜像发布之前对其进行扫描。我们可以在DevOps工作流程中使用已经构建好的CI/CD管道,并增加镜像扫描的步骤。

CI/CD管道上镜像扫描的架构如下:

测试和构建镜像后,我们不必将镜像推送到生产库,可以先推送到暂存库,然后运行镜像扫描工具。这些工具通常会返回一份报告,列出发现的问题,并为每个问题分配不同级别的严重性。在CI/CD管道中,我们可以检查这些镜像扫描结果,并在出现任何严重问题时停止构建。

有一点要记住,自动化是最关键的,这是DevOps的核心概念,也适用于保护 DevOps。通过自动化 CI/CD 管道中的安全性检查,我们可以在漏洞进入注册表之前就将其捕获,这样就不会给漏洞任何机会。

2.采用 inline 扫描以保护隐私

在上一步中,我们看到了 CI/CD 管道中的镜像扫描与临时注册表的关系,但如果镜像包含一些错误凭证该怎么办?它们可能会出现错误,最终导致数据泄漏。所以更进一步,我们可以实施 inline 镜像扫描,不使用暂存库,直接从 CI/CD 管道扫描镜像。

使用 inline 镜像扫描,它会仅扫描发送到扫描工具的元数据,从而帮助保护隐私。

使用 inline 镜像扫描,可以在 CI/CD 管道内扫描镜像。代码推送后,在不离开 CI/CD 管道的情况下即可构建并扫描镜像。镜像元数据会被发送到镜像扫描器,然后结果会发送回 CI/CD 管道。如果该镜像遵循安全策略,那它将被推送到生产镜像存储库。

3.在注册表中执行镜像扫描

开始实施镜像扫描时,要将其嵌入到注册表中,这是第一步。

通常,我们会有一个用于发布镜像的专用存储库,还有一些用于从第三方下载镜像的公共存储库。我们需要扫描这两个存储库的镜像。

我们部署的所有镜像都将从注册表中提取。通过在那里扫描镜像,我们至少可以确保它们在运行之前已经被扫描过了。

4.使用 Kubernetes 准入控制器

如果想在使用镜像之前先对其进行检查,以防止将未扫描或易受攻击的镜像部署到集群上,我们可以使用准入控制器。

Kubernetes准入控制器是强大的Kubernetes原生功能,可以帮助我们自定义在集群上允许运行的内容。在对请求进行身份验证和授权之后,在对象持久化存储etcd之前,准入控制器可以拦截并处理对Kubernetes API的请求。

将Deployment的创建请求发送到Kubernetes后,准入控制器将调用Webhook并发送镜像元数据。镜像扫描器会将扫描结果发挥准入控制器,准入控制器在扫描通过后才会保留Deployment。

扫描工具通常会提供一个验证Webhook,该Webhook可以按需触发镜像扫描,然后返回验证决策。

准入控制器可以在调度镜像之前调用此Webhook。Webhook返回的安全性验证决策将传回API服务器,该服务器会回复原始请求者,并且仅在镜像通过检查后才将对象持久保存在etcd数据库中。不过,该决定是由镜像扫描器做出的,并没有任何集群中有关情况的上下文(context),这里我们可以使用OPA改进。

Open Policy Agent(OPA)是一种开放源代码通用策略引擎,它是一种叫Rego的高级声明性语言编写的。OPA关键思想之一是将决策与政策执行脱钩。

使用OPA,我们可以在Kubernetes集群而不是镜像扫描器中做出准入决定,这样就可以在决策过程中使用集群信息,例如命名空间、Pod元数据等。

5.固定的镜像版本

有时,我们扫描的镜像与在 Kubernetes 集群中部署的镜像不同,例如在使用可变标签(比如“latest”或“staging”)时,就可能会发生这种情况。此类标签会不断更新版本,从而使得我们很难知道最新的扫描结果是否仍然有效。

标签“:latest”会指向镜像的最新版本,除了最后一个版本外,其他所有版本均会被扫描。

使用可变标签可能会导致使用同一个镜像却部署了不同版本容器的情况。除了扫描结果带来的安全问题外,这可能还会导致难以调试。

为了代替 ubuntu:focal,我们应该尽可能使用不可变标签,例如 ubuntu:focal-20200423。

这里要记住,version 标签(对于某些镜像)往往会进行较小的、不间断的更新,因此确保可重复性唯一的选择就是使用实际镜像 ID:

ubuntu:@sha256:d5a6519d9f048100123c568eb83f7ef5bfcad69b01424f420f17c932b00dea76

这里可能有点超出镜像扫描最佳实践的范围,但我们要知道,这些不仅会影响 Dockerfiles 中的 FROM 命令,还会影响 Kubernetes Deployment 文件以及几乎所有放置镜像名称的地方。

从镜像扫描的角度来看,我们能做什么?我们可以通过结合使用 Kubernetes 准入控制器、镜像扫描器和 OPA 引擎来实施此策略。

6.扫描操作系统漏洞

作为一般的镜像扫描最佳实践,请牢记这一点:"镜像越轻越好",越轻的镜像意味着更快的构建、更快的扫描以及更少的潜在漏洞依赖性。

新的Docker镜像通常是在现有基础镜像的基础上构建的,或在现有基础镜像之上添加一层。该基础镜像是由Dockerfile镜像中的FROM语句定义的,这样的分层的体系结构设计,可以在最常见的任务中节省大量时间。例如,在镜像扫描时,我们只需要扫描一次基础镜像。如果父镜像易受攻击,那么在该父镜像之上构建的任何其他镜像也是易受攻击的。

WordPress和PHP镜像基于Apache,而Apache基于Ubuntu镜像。如果Apache上存在漏洞,那么WordPress和PHP镜像都将容易受到攻击。

即使我们没有在镜像中引入新漏洞,但基础镜像中的漏洞也很容易让我们受到攻击。这就是为什么扫描工具应主动跟踪已知漏洞文件的漏洞源,并在我们使用其中的漏洞时进行通知。

7.使用 distroless 镜像

distroless 镜像仅允许我们将应用程序及其依赖项打包在轻量级容器镜像中。将运行时容器中的内容严格限制为必需内容可以最大程度地减少攻击面。另外,它还可以改善扫描器的信噪比(例如CVE),并根据需要减轻负担。

以下示例显示了用于"Hello world"应用程序的Dockerfile,该应用程序在Ubuntu和Distroless上运行。

FROM ubuntu:focal

COPY main /

ENTRYPOINT ["/main"]

对其进行扫描后,我们发现了24个操作系统漏洞,其中两个严重程度为中。这样一个简单的应用程序,影响大小居然有77.98MB这么大。

现在,基于distroless镜像的同一应用程序:

FROM gcr.io/distroless/static-debian10

COPY main /

ENTRYPOINT ["/main"]

现在,我们只发现了两个可以忽略不计的漏洞,此外,镜像大小减小到只有6.93MB,这更适合此应用程序。

这表明,distroless容器没有任何不必要的程序包,这些程序包可能导致更多的漏洞而被利用。

8.扫描第三方库中的漏洞

应用程序使用了大量的库,以至于这些库最终提供的代码行比团队编写的实际代码还多。这意味着我们不仅需要知道代码中的漏洞,还需要知道其所有依赖项中的漏洞。

不过扫描器检测操作系统漏洞的相同漏洞源,会跟踪这些漏洞,但并非所有工具都能像扫描镜像中的库一样深入,因此请确保镜像扫描器已深入挖掘并向我们警告这些漏洞。

9.优化镜像层顺序

谨慎使用Dockerfile中的RUN命令可以进一步优化镜像。RUN命令的顺序可能会对最终镜像产生重大影响,因为它决定了镜像层的顺序。

我们可以首先防止较大的层(通常是不变的),最后放置变化最大的文件(例如已编译的应用程序)来优化Docker缓存的使用。这将有利于现有层的使用,加快构建镜像的速度,并间接加快镜像扫描的速度。

10.扫描 Dockerfile 中的配置错误 

如我们所见,Docker镜像构建过程遵循Dockerfile指令清单。

我们可以遵循以下几种Dockerfile最佳实践来检测常见的安全性错误配置:

  • 以特权(root)用户身份运行,会访问比所需更多的资源。
  • 暴露不安全的端口,例如不应在容器上打开ssh 22端口。
  • 由于错误的"COPY"或"ADD"命令不小心嵌入了私人文件。
  • 不通过环境变量或安装注入(泄露)secret或凭据。允许用户将选项传递给Entrypoint和CMD是一个好习惯。
  • 特定策略定义许多其他内容,例如被阻止的软件包、允许的基本镜像、是否已添加SUID文件等。

在这样的Dockerfile中:

FROM ubuntu:focal-20200423
USER root
RUN curl http://my.service/?auth=ABD54F0356FA0054
EXPOSE 80/tcp
EXPOSE 22/tcp
ENTRYPOINT ["/main"]

我们的镜像扫描可以自动检测到以下问题:

USER root

我们以root身份运行:

EXPOSE 22/tcp

在这里,我们将暴露通常用于ssh的22端口,这是容器不应该包含的工具。另外, 我们还将公开90端口,但这个没问题,这就像HTTP服务器的通用端口一样。

RUN curl http://my.service/auth=ABD54F0356FA005432D45D0056AF5400

此命令使用一个auth密钥,任何人都可以使用它来给我们造成危险,因此我们应该改用某种变量。这样的密钥不仅可以在Dockerfile上,还可以在镜像中存在的任何文件中使用正则表达式进行检测。作为一项额外措施,我们还可以检查已知可存储凭证的文件名。

11.快速标记 Kubernetes Deployment 中的漏洞

通过扫描的镜像并不是绝对安全的。如果在扫描后,我们部署了镜像,但此时发现了一个新漏洞,虽然我们可以立即加强安全策略,但是那些已经运行的镜像会怎么样?

生产中部署的易受攻击镜像的时间轴:

因此我们要连续扫描镜像以达到以下目标:

  • 检测新漏洞并进行符合我们策略的更改。
  • 向相应团队报告这些发现,以便他们尽快修复镜像。

当然,实施运行时扫描可以帮助我们减少这些漏洞的影响。以 CVE-2019-14287 为例, 我们可以编写一些 Falco 规则来检测该漏洞是否已被利用,但为每个漏洞编写特定规则是一项耗时的工作,应将其作为最后一道防线。因此,我们要连续扫描集群中正在运行的镜像。

安全工具会使用不同的策略进行存档,最简单的方法是每隔几个小时重新扫描一次所有镜像。理想情况下,我们希望在漏洞列表更新后立即重新扫描受影响的镜像。不过某些工具能够存储镜像元数据,无需完全重新扫描即可检测新漏洞。

一旦在运行中的容器中发现漏洞,我们就应尽快修复。这里的关键是有效的漏洞报告,这样每个人都可以专注于有关的信息。

实现此目标的一种方法是使用可查询的漏洞数据库,该数据库让 DevOps 安全团队可以在其庞大的镜像、程序包和 CVE 目录中进行一些排序。他们将搜索诸如 CVE age、是否有可用的修复程序、软件版本等参数。最后,如果可以下载这些报告并与漏洞管理团队、CISO 共享,那么将非常有用。

让我们用一个例子来说明,现在有一个查询包含了以下内容:所有的漏洞在 prod 命名空间,严重性为高,CVE>30 天,修复可用。

借助这种漏洞报告功能,团队可以轻松地识别出他们可以实际修复的易受攻击镜像,并在漏洞被利用之前开始着手解决方案。

12.选择基于 SaaS 的扫描解决方案

在本地解决方案上选择基于 SaaS 的扫描服务有很多好处:

  • 按需扩展资源:我们可以首先扫描几个镜像,然后随着容器应用程序的扩展而增长,无需担心后端数据管理。
  • 快速实施:我们可以将扫描嵌入到CI/CD管道中,并在几分钟内启动并运行,而本地应用程序则需要更多时间来安装和设置。
  • 轻松升级和维护:SaaS提供商处理并推出补丁程序不需要我们手动升级或更新新功能。
  • 无需基础设施或人员成本:我们可以避免为拥有永久所有权的内容硬件和软件许可证付费,也不需要现场维护和支持应用程序。

结论

镜像扫描是DevSecOps工作流程中的第一道防线。通过使其自动化,我们可以最大程度地发挥其潜力,并在问题有机会变大之前发现问题。遵循镜像扫描最佳实践将帮助大家将安全性嵌入其中,并且交付速度不会因此降低。

最后,要记住镜像扫描不该仅用一次,而要在工作流程中连续检查,包括在构建时、在注册表上、在部署之前以及容器已经运行时。

原文链接:https://sysdig.com/blog/image-scanning-best-practices/

生产中的12种容器镜像扫描最佳实践相关推荐

  1. Docker容器镜像安全最佳实践指南

    文章目录: 0x02 Docker 容器安全最佳实践 1.主机安全配置 1.1 更新docker到最新版本 1.2 为容器创建一个单独的分区 1.3 只有受信任的用户才能控制docker守护进程 1. ...

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

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

  3. 阿里云专有云容器服务弹性伸缩最佳实践

    简介:阿里云专有云容器服务弹性伸缩最佳实践 1.容器服务弹性伸缩简介 本小节将基于使用原理对容器服务弹性伸缩进行简要的描述. 本实践基于K8s的业务集群运行在专有云上,对测试业务进行压力测试,主要基于 ...

  4. 容器化技术最佳实践1--容器化技术简介与Docker入门

    容器化技术最佳实践1–容器化技术简介与Docker入门 文章目录 容器化技术最佳实践1--容器化技术简介与Docker入门 容器化简介 通过虚拟化了解容器化 对开发和运维的好处 容器化部署特点 什么情 ...

  5. 详解华为12种数据采集技术及应用实践

    导读:数字化转型要从根本上加强数据的可获得性,围绕我们构建的数据主题和对象丰富数据感知渠道.要追求更加实时.全面.有效.安全的数据获取. 作者:华为公司数据管理部 来源:大数据DT(ID:hzdash ...

  6. 云原生之路:容器技术落地最佳实践

    简介: 随着容器技术的快速发展和广泛应用,毫无疑问云原生技术是未来发展的必然趋势.作为国内最早布局容器技术的阿里云,无论在技术还是产品上,都取得了极大的成果.阿里云资深技术专家易立通过阿里云容器服务, ...

  7. k8s容器灰度发布最佳实践(基于spinnaker)

    k8s中的容器一般是通过deployment管理的,那么一次滚动升级理论上会更新所有pod,这由deployment资源特性保证的,但在实际的工作场景下,需要灰度发布进行服务验证,即只发布部分节点,这 ...

  8. docker 日志_Docker容器日志管理最佳实践

    博客园:https://www.cnblogs.com/operationhome/p/10907591.html 本文所有内容基于: Docker-CE Server Version: 18.09. ...

  9. Docker容器日志管理最佳实践

    Docker  日志分为两类: Docker 引擎日志(也就是 dockerd 运行时的日志), 容器的日志,容器内的服务产生的日志. 一 .Docker 引擎日志 Docker 引擎日志一般是交给了 ...

最新文章

  1. java 禁止缓存_JavaWeb如何实现禁用浏览器缓存
  2. python爬取慕课视频-Python爬虫抓取技术的门道
  3. Eclipse——e(fx)clipse下载错误导致的安装失败解决方案
  4. 最实用的logback讲解(1)
  5. hash和trie的对比
  6. VTK:相互作用之CallBack
  7. 牛客网 -- 计算机历年考研复试上机题 -- 手机键盘
  8. java流行的测试框架调研+市面上书籍调研
  9. IIS添加直接下载的文件类型
  10. 绝,Java 中创建对象的 5 种方法!
  11. 小米推新,黄章怒骂!留给魅族们的时间不多了 | 畅言
  12. 如何将超大文件传输给别人,超大文件如何传输
  13. java实现qq登录界面_java实现简单的QQ登录界面
  14. Qt Android treeWidget树状单击展开
  15. Ant 下载安装配置使用教程
  16. dcmtk读取DICOM并进行体绘制渲染
  17. 5.3 Hessenberg法求特征值
  18. 抖音协议算法教- API学习
  19. adb 连接手机 cannot connect to 192.168.x.xx:5555: 由于目标计算机积极拒绝,无法连接。 (10061)
  20. 真正的互联网诞生:TCP/IP协议的出现

热门文章

  1. PAT甲级 -- 1005 Spell It Right (20 分)
  2. 通俗易懂两种常用的多线程实现方式——Java并发系列学习笔记
  3. LinkedList方法源码
  4. Java 折半查询,java之折半查询
  5. oracle主从表分离怎么实时更新数据_高可用数据库主从复制延时的解决方案
  6. linux该专接本还是工作_是该专接本还是直接工作?学历和经验哪个重要?
  7. php substr 去掉前n位_PHP全栈学习笔记16
  8. c语言设计第六章答案,c语言第六章 循环结构程序设计(习题册答案)
  9. linux测量某个ip的网速,linux下测网速
  10. ERROR: No query specified