出品丨Docker公司(ID:docker-cn)
编译丨小东
每周一、三、五晚6点10分 与您不见不散
前情回顾
创建安全的镜像供应链至关重要。每个组织都需要权衡所有可用选项并了解安全风险。可供选择的镜像过多大大增加了挑选难度。归根结底,每个组织都需要了解所有镜像的来源,即使它是来自于 store.docker.com 中的可信认的上游镜像时也是如此。将镜像导入基础架构后,很有必要进行漏洞扫描。而带镜像扫描功能的 Docker Trusted Registry 提供了深入了解漏洞的能力。最后,整个过程需要实现自动化以提供简单的审核线索,点击以下标题,回顾第一部分内容:
&
持续集成自动化
为了践行“任何人都不得将代码推送到生产环境”的理念,您需要将这一切自动化。借助较新版本的 GitLab,可以直接配置 CI/CD 功能。无需再使用其他工具。这大大简化了设置过程和可维护性。要利用 CI/CD,首先请至少注册一个运行程序。运行程序包含在前一创建部分中的 gitlab.yml 中。下一步是配置运行程序。
配置运行程序
与其他 CI 工具相似,GitLab 也要求使用运行程序来完成构建。要激活在前一部分中随 docker stack deploy 一起安装的运行程序,需要获取运行程序令牌。浏览至管理区域 --> 运行程序。在此处您将找到注册运行程序所需的令牌。
值得庆幸的是,存在注册运行程序的捷径。即通过 ssh 访问 GitLab 节点并运行以下 Docker 命令(从 GitLab CE 页面通知令牌):
docker exec -it $(docker ps --format '{{.Names}}\t{{.ID}}'|grep runner|awk '{print $2}') gitlab-runner \
register -n \
--url http://gitlab.example.com \
--registration-token <^>$token<^^> \
--executor docker \
--description "local docker" \
--docker-image "docker:latest" \
--docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
--docker-volumes "/root/.docker:/root/.docker"
注册完成后,您将看到运行程序显示已共享标签。您还需要确保选中了运行无标签作业,未选中锁定到当前项目。
构建描述
CI 将在此处发挥作用。GitLab 依赖镜像仓库根目录中名称为 .gitlab-ci.yml 的文件。该文件就是 CI 描述文件。
注:有关此主题,请查看 GitLab 文档(https://docs.gitlab.com/ee/ci/yaml/README.html)。
请思考以下情况。请务必在各个镜像仓库中配置变量。
下面是从 git 本身构建镜像的良好示例。
# Official docker image.
variables:
DOCKER_DRIVER: overlay2
image: docker:latest
before_script:
- docker login -u <^>$DTR_USERNAME<^^> -p <^>$DTR_PASSWORD<^^> <^>$DTR_SERVER<^^>
build:
stage: build
script:
- docker build --pull -t dtr.example.com/admin/"<^>$CI_PROJECT_NAME<^^>"_build:<^>$CI_JOB_ID<^^> .
- docker push dtr.example.com/admin/"<^>$CI_PROJECT_NAME<^^>"_build:<^>$CI_JOB_ID<^^>
- docker rmi dtr.example.com/admin/"<^>$CI_PROJECT_NAME<^^>"_build:<^>$CI_JOB_ID<^^>
下面是用于拉取、添加标签以及将镜像从 store.docker.com 推送到 DTR 的 .gitlab-ci.yml 的良好示例。
# Official docker image.
variables:
DOCKER_DRIVER: overlay2
image: docker:latest
before_script:
- docker login -u <^>$DTR_USERNAME<^^> -p <^>$DTR_PASSWORD<^^> <^>$DTR_SERVER<^^>
stages:
- signer
signer:
stage: signer
script:
- docker pull <^>$DTR_SERVER<^^>/admin/flask:latest
- export DOCKER_CONTENT_TRUST=1
- docker push <^>$DTR_SERVER<^^>/admin/flask:latest
- docker rmi <^>$DTR_SERVER<^^>/admin/flask:latest
现在,已为 GitLab 设置好变量和构建描述。接下来,为项目添加触发器。
管道触发器
GitLab 现在包含出色的 CI 工具以及远程触发管道的方法。GitLab 会调用这些触发器。创建这些触发器最简便的方法是浏览至项目 --> 设置 --> CI/CD --> 管道触发器 --> 展开。
此处为触发器格式的示例。http://gitlab.example.com/api/v4/projects/<^><PROJECT><^^>/trigger/pipeline?token=<^><TOKEN><^^>&ref=<^><REF><^^>.此处所需的三个字段为 <^><PROJECT><^^>、<^><TOKEN><^^> 和 <^><REF><^^>。<^><REF><^^> 应设置为分支名称。<^><TOKEN><^^> 应设置为您从 GitLab 获取的令牌。获取 <^><PROJECT><^^> 的最佳方法是复制管道触发器页面中的 URL。您将在稍后用到管道触发器。
接下来,添加 Docker Trusted Registry。
Docker Trusted Registry
Docker Trusted Registry 不仅仅是简单的镜像库。DTR 现在包含一些可强化供应链的出色功能。新功能包括镜像提升和不可变性等。
在接下来的部分中将介绍部分新功能。
镜像扫描
从 版本 2.2.0 开始,DTR 包含本地镜像扫描功能。DTR 中的本地扫描引擎将对照 CVE 数据库扫描镜像。首先,扫描程序将对镜像的每一层执行二进制扫描,识别每一层中的软件组件,并对每个组件的 SHA 编制索引。该二进制扫描会逐个数位地对组件进行评估,因此存在漏洞的组件总会被发现,无论它们的文件名为何,无论它们是否包含在分发清单或软件包管理器中,无论它们是静态链接的组件还是动态链接的组件,即使它们来自基础镜像 OS 分发也不例外。
然后该扫描会将每个组件的 SHA 与 CVE 数据库(已知信息安全漏洞的“字典”)进行比较。当 CVE 数据库更新时,扫描服务会审查已编制索引的组件以发现与新发现的漏洞匹配的组件。大多数扫描会在几分钟之内完成,但是较大的镜像仓库可能需要较长的时间才能扫描完,具体取决于系统资源。扫描引擎提供了扫描所有镜像的中心点并提供物料清单 (BOM),可将其与 Notary 耦合以确保为镜像提供极其安全的供应链。
从 DTR 2.3.0 开始,该扫描引擎也可以扫描 Windows 二进制文件。
设置镜像扫描
开始之前,请确保您或您的组织已经购买了包含 Docker 安全扫描功能的 DTR 许可证,并且您的 Docker ID 可以在 Docker 商店中访问和下载此许可证。
默认情况下,当启用安全扫描时,每次执行 docker push,新镜像仓库都会自动执行扫描,但是,默认情况下,任何在启用扫描前就已存在的镜像仓库都会被设为“手动扫描”模式。如果这些镜像仓库仍在使用,则可以在每个镜像仓库的设置页面中更改此设置。
要启用镜像扫描,转至设置 --> 安全,选择启用扫描,然后选择使用 Doker 提供的 CVE 数据库(联机 — 默认选项)还是使用本地上传文件(脱机 — 仅对未联网的环境或无法连接到 Doker 进行持续更新的环境推荐该选项)。
以联机模式启用后,DTR 将从 Docker 下载 CVE 数据库,首次同步可能会花费较长时间。如果您的安装无法访问 https://dss-cve-updates.docker.com/,您必须手动上传包含安全数据库的 .tar 文件。
如果您使用的是在线模式,DTR 实例就会连接 Docker 服务器,下载最新的漏洞数据库,然后进行安装。安装完成后会立即开始扫描。
如果您使用的是脱机模式,则按照更新扫描数据库 - 脱机模式中的说明上传初始安全数据库。
CVE 脱机数据库
如果 DTR 实例无法连接更新服务器,可以下载并安装包含数据库更新的 .tar 文件。可从 Store.docker.com 中我的内容 --> 许可证设置下找到这些脱机 CVE 数据库文件。
扫描结果
要查看扫描的结果,浏览至镜像仓库本身,然后单击镜像。未发现漏洞的镜像扫描会显示绿色的勾号盾牌图标:
发现漏洞的镜像扫描会显示红色的警告盾牌:
对于扫描结果,存在两种视图,层和组件。层视图显示镜像的哪个层上具有存在漏洞的二进制文件。要诊断漏洞位于 Dockerfile 何处时,此视图极其有用。
单击层本身时,将显示存在漏洞的二进制文件,以及该层上的所有其他内容。在本示例中,存在几个可能存在漏洞的二进制文件:
单击存在漏洞的镜像来查看 组件 视图。从组件视图中,可查看 CVE 编号、指向 CVE 数据库的链接、文件路径、受影响的层、严重性和严重性说明:
现在您可以对存在漏洞的二进制文件/层/镜像采取操作。
如果发现了存在漏洞的组件,请检查是否存在安全漏洞已经修复的更新后版本。如有必要,请联系组件的维护人员来确保在未来的版本或补丁更新中修复此漏洞。
如果该漏洞位于基础层(例如操作系统)中,您可能无法纠正镜像中的问题。在这种情况下,您可能需要切换到另一个基础层版本,或者可以寻找一个功能相当但不太容易受到攻击的基础层。您也可以确定是否可以接受该漏洞或暴露。
通过使用存在漏洞的组件的已更新和已更正版本,或使用功能相同的不同组件,来解决镜像仓库中的漏洞问题。当您已更新源代码时,请运行一个构建以创建新镜像,标记镜像并将更新后的镜像推送到您的 DTR 实例。然后,您可以重新扫描该镜像以确认您已修复这些漏洞。
当有新漏洞发布时应该怎么办?实际上有两个阶段。第一阶段是为镜像的二进制文件和层生成哈希值指纹。第二阶段是将这些哈希值与 CVE 数据库进行比较。生成指纹阶段耗时最久。比较哈希值很快就可以完成。当有新的 CVE 数据库时,DTR 只需将现有哈希值与新的数据库进行比较即可。此过程耗时也较短。扫描结果会一直更新。
现在已经有了扫描结果,接下来该添加提升策略了。
![640?wx_fmt=png](https://i-blog.csdnimg.cn/blog_migrate/37d3721dfa90996719b9a52786a482d1.png)
点击下列标题,阅读更多干货
如果本文对你有帮助,欢迎分享到朋友圈!获取更多Docker实用技巧,扫描下图二维码!