你可能不知道的容器镜像安全实践

科技资讯 投稿 11000 0 评论

你可能不知道的容器镜像安全实践

最近在公司搭建CI流水线,涉及到容器镜像安全的话题,形成了一个笔记,分享与你,也希望我们都能够提高对安全的重视。

1 时代背景

根据 Anchore 发布的《Anchore 2021年软件供应链安全报告》显示容器的采用成熟度已经非常高了,65% 的受访者表示已经在重度使用容器了,而其他 35% 表示也已经开始了对容器的使用:

业界已经达成共识:云原生时代已经到来,如果说容器是云原生时代的核心,那么镜像应该就是云原生时代的灵魂。镜像的安全对于应用程序安全、系统安全乃至供应链安全都有着深刻的影响。

根据 snyk 发布的 2020年开源安全报告 中指出,在 dockerhub 上常用的热门镜像几乎都存在安全漏洞,多的有上百个,少的也有数十个。具体数据如下图所示:

2 解决方式

GitLab(极狐)建议我们:预防为主,防治结合的方式来提高镜像的安全性。

3 防的最佳实践

3.1 以安全的方式构建容器镜像

常规构建容器镜像的方式就是 docker build,这种情况需要客户端要能和 docker守护进程进行通信。对于云原生时代,容器镜像的构建是在 Kubernetes 集群内完成的,因此容器的构建也常用 dind(docker in docker)的方式来进行。

为了解决这个问题,可以使用一种更安全的方式来构建容器镜像,也就是使用 kaniko。kaniko是谷歌发布的一款根据 Dockerfile 来构建容器镜像的工具。kaniko 无须依赖 docker 守护进程即可完成镜像的构建。其和GitLab CI/CD的集成也是非常方便的,只需要在GitLab CI/CD 中嵌入即可,下面是在我司CI Pipeline中的实践:

variables: EXECUTOR_IMAGE_NAME: "gcr.io/kaniko-project/executor" EXECUTOR_IMAGE_VERSION: "debug" docker-build-job: stage: docker-build-stage image: name: "$EXECUTOR_IMAGE_NAME:$EXECUTOR_IMAGE_VERSION" entrypoint: [""] rules: - if: '$IMAGE_SOURCE_BUILD != "" &&$BUILD_DOCKER_IMAGE == "true" && $CI_PIPELINE_SOURCE !="merge_request_event"' script: - |- KANIKO_CONFIG="{\"auths\":{\"$CI_REGISTRY_IMAGE\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" echo "${KANIKO_CONFIG}" >/kaniko/.docker/config.json - mkdir release - cp -r Build/* release/ - | /kaniko/executor \ --context "${CI_PROJECT_DIR}" \ --dockerfile "Dockerfile" \ --destination"${CI_REGISTRY_IMAGE}:${BUILD_TAG}"

3.2 选择合适且可靠的基础镜像

Dockerfile 的第一句通常都是 FROM some_image,也就是基于某一个基础镜像来构建自己所需的业务镜像,基础镜像通常是应用程序运行所需的语言环境,比如.NET、Go、Java、PHP等,对于某一种语言环境,一般是有多个版本的。

点此浏览

docker pull registry.access.redhat.com/ubi8/dotnet-60-runtime:6.0-22

3.3 不安装非必要的安装包

Dockerfile 中应该尽量避免安装不必要的软件包,除非是真的要用到。比如:我们习惯了直接写 apt-get update && apt-get install xxxx。

3.4 以非root用户启动容器

因此,建议在Dockerfile中添加命令来让容器以非root用户身份启动,在我司的CI Pipeline中的实践:

...... USER 0 RUN chown -R 1001:0/opt/app-root && fix-permissions /opt/app-root # No root should run USER 1001 ENV ASPNETCORE_URLS=http://+:8080 EXPOSE 8080 CMD dotnet ${APPLICATION_DLL}

备注:上面的${APPLICATION_DLL}是在镜像打包阶段由流水线通过参数传递给Dockerfile的。

4 治的最佳实践

在CI流水线中加入容器镜像安全扫描任务。

参考资料

GitLab DevSecOps七剑下天山之容器镜像安全扫描》

云原生时代,如何保证容器镜像安全?》

编程笔记 » 你可能不知道的容器镜像安全实践

赞同 (56) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽