本文的翻译是专门为Linux安全课程的学生准备的。
阅读第一部分
5.不要在Docker映像中保留敏感数据
有时在Docker映像中创建应用程序时,您需要诸如SSH私有密钥之类的敏感数据,以便从私有存储库中提取代码,或者需要令牌来安装封闭的软件包。 如果将它们复制到中间Docker容器,则即使它们稍后删除,它们也会缓存在添加它们的层中。 这些令牌和密钥必须存储在
Dockerfile
外部。
使用多阶段构建
使用Docker对多阶段构建的支持,可以在映像的中间层中处理秘密,该秘密随后会被删除,因此不会有敏感数据到达最终构建。 使用以下代码将秘密数据添加到中间件:
FROM: ubuntu as intermediate WORKDIR /app COPY secret/key /tmp/ RUN scp -i /tmp/key build@acme/files . FROM ubuntu WORKDIR /app COPY --from=intermediate /app .
使用Docker Secrets命令
在Docker中使用alpha功能来管理敏感数据以挂载敏感文件而不缓存它们:
您可以在Docker网站上了解有关管理敏感数据的更多信息。
提防递归复制
您还应该注意将文件复制到创建的图像。 例如,以下命令将整个程序集上下文文件夹递归复制到Docker映像,这也可能导致复制敏感文件:
COPY . .
如果您的文件夹中有敏感文件,请将其删除或使用
.dockerignore
忽略它们:
private.key appsettings.json
6.使用固定标签进行免疫
每个Docker映像可以具有表示同一映像变体的多个标签。 最常见的标签是
latest
,代表图像的最新版本。 图像标签不是一成不变的,图像作者可以多次发布相同的标签。
这意味着您的Docker文件的基础映像可以在构建之间进行更改。 由于对基础图像进行了更改,这可能导致意外行为。
有几种方法可以解决此问题:
- 首选最具体的标签。 如果图像具有多个标签,例如
:8
和:8.0.1
或什至:8.0.1-alpine
,则首选后者,因为它是图像的最具体链接。 避免使用最常见的标签,例如最新标签。 固定特定标签时,请记住最终可以将其删除。 - 若要解决特定图像标签变得不可访问并成为依赖它的组的广告显示限制的问题,请考虑在注册表或由您自己控制的帐户中启动该图像的本地镜像。 重要的是要考虑此方法所需的维护成本,因为这意味着您需要维护注册表。 优良作法是在注册表中复制要使用的映像,以确保所使用的映像没有更改。
- 要特别具体! 不用拉标签,而是使用特定的SHA256链接将图像拉到Docker图像,以确保您为每个请求获得相同的图像。 但是,请注意,使用SHA256链接可能会有以下风险-如果图像更改,则哈希可能不再起作用。
7.使用COPY代替ADD
Docker提供了两个命令,用于在创建文件后将文件从主机复制到Docker映像:
COPY
和
ADD
。 命令本质上相似,但功能不同:
- COPY-递归复制本地文件,指示源文件和目标文件或目录。 使用COPY,您必须声明位置。
- ADD-递归复制本地文件,隐式创建目标目录(如果不存在),并接受归档作为本地或远程URL作为源,然后分别将其扩展或加载到目标目录中。
尽管ADD和COPY之间的区别不是那么根本,但它们很重要。 请注意它们,以避免潜在的安全问题: - 当使用远程URL将数据直接下载到其原始位置时,这可能导致代理攻击,从而修改下载文件的内容。 此外,必须进一步验证远程URL的来源和真实性。 使用COPY时,必须通过安全的TLS连接声明要从远程URL下载的文件的来源,并且还必须验证其来源。
- 关于图像的空间和层的注意事项:使用COPY,您可以将归档文件的添加与远程位置分开,然后将其解压缩到不同的层中,从而优化了图像的缓存。 如果需要远程文件,请将它们全部合并为一个RUN命令,随后将下载,提取和清除该命令,从而优化使用ADD所需的多层上的单层操作。
- 使用本地存档时,ADD会自动将其提取到目标目录。 尽管这是可以接受的,但它增加了获得zip炸弹和Zip Slip漏洞的风险 ,这些漏洞随后可以自动启动。
8.使用元数据标签
图像标签为您创建的图像提供元数据。 这使用户更容易弄清楚如何使用图像。 最常用的标签是“ maintainer”,它表示支持该图像的人员的电子邮件地址和姓名。 使用以下
LABEL
命令添加元数据:
LABEL maintainer="me@acme.com"
除了维护者的联系方式,添加对您重要的所有元数据。 此元数据可能包含:提交哈希,指向适当程序集的链接,质量状态(是否通过了所有测试?),源代码,指向SECURITY.TXT文件位置的链接等。
最好支持
SECURITY.TXT (RFC5785)文件,该文件在添加新标签时会指向Docker标签方案的责任披露策略,例如:
LABEL securitytxt="https://www.example.com/.well-known/security.txt"
查看有关Docker映像的更多标签信息:
https://label-schema.org/rc1/9.使用多级组装以获得小的和安全的图像
使用
Dockerfile
创建应用程序时,会创建许多构件,这些构件仅在构建时才需要。 它可以是编译所需的开发工具和库,也可以是运行单元测试,临时文件,机密等所需的依赖项。
将这些工件存储在可用于生产的基本映像中会导致Docker映像的大小增加,这会极大地影响下载它的时间并增加攻击面,因此将安装更多软件包。 对于正在使用的Docker映像也是如此-您可能需要特定的Docker映像来构建,但不需要运行应用程序代码。
Golang是一个很好的例子。 要创建Golang应用程序,您需要Go编译器。 编译器创建一个可执行文件,该文件可在任何操作系统上运行,而没有依赖关系,包括干净的映像。
这是Docker能够逐步构建的一个很好的理由。 此功能使您可以在组装过程中使用多个临时图像,仅保存最后一个图像以及复制到其中的信息。 因此,您有两个图像:
- 第一个映像非常大,并带有许多用于创建应用程序和运行测试的依赖项。
- 第二个图像在库的大小和数量方面非常轻巧,仅包含在生产环境中运行应用程序所需的工件副本。
10.使用短绒
使用短绒棉布可以避免常见的错误,并建立工程师可以自动遵循的最佳实践。
哈多林特就是其中
之一 。 它分析Dockerfile并针对任何不符合其建议的错误发出警告。

当在集成开发环境(IDE)中使用时,Hadolint变得更加强大。 例如,当使用hadolint作为
VSCode扩展名时,在输入过程中会出现
棉绒错误。 这有助于更快地编写最佳dockerfile。
了解有关保护Docker映像的更多信息。