最佳做法是不要以 root 身份运行容器。许多 Docker 镜像,甚至一些官方镜像,都忽略了这一点,并要求您以 root 身份运行。建议通常是您应该设置映像,以便您的应用程序不需要 root 并且可以作为您在Dockerfile 中设置的非 root 用户启动。出于几个原因,即使这个建议也不是最安全的选择。
首先他们会说使用USER username,其中username显然不是root。对于托管该图像的平台,这实际上并不能保证您的应用程序没有以root 运行。这是因为命名用户(例如username)可以映射到容器中的0 中的uid,因此仍以root 权限运行。要允许平台正确验证您的图像未设置为以root 运行,您应该使用uid 而不是username。那应该是除了 0 的 uid 之外的任何东西。
第二个问题是,虽然在你自己的 Docker 服务实例中作为特定的非root 用户运行可能没问题,但当你考虑多租户环境时,不管是针对不同用户,甚至是不同应用程序,情况都不是这样。重要的是不同的应用程序不能以任何方式相互访问。
在多租户环境中,您可以做的最安全的事情是以不同用户的身份运行特定帐户或不同项目中拥有的所有应用程序。这是导入的一个原因是从持久卷上的数据访问的角度来看。如果一切都以同一个用户身份运行并且它设法访问了它不应该访问的持久卷,它可以看到来自其他应用程序的数据。
就 OpenShift 而言,默认情况下它以最高级别的安全性运行以保护您。因此,一个项目中的应用程序与另一个项目中的应用程序使用不同的用户运行。
如果您拥有适当的权限,您可以减少安全措施并覆盖它,但只有在您确信您正在执行的应用程序具有低风险配置文件时,您才应该进行更改。也就是说,您不会从 Internet 上抓取一些您一无所知的任意 Docker 映像并让它以 root 身份运行。
要了解有关更改特定应用程序的安全上下文约束的更多信息,请先阅读以下内容:
您可以覆盖默认值并说图像可以作为它在Dockerfile 中声明的用户运行,或者如果需要,甚至可以作为root 运行。
如果想要最好的安全性,更好的方法是构建 Docker 映像,以便它可以作为任何用户运行,而不仅仅是特定用户。
如何做到这一点的一般准则是:
- 在容器中创建一个新的用户帐户来运行应用程序。将此帐户的主组设为组 ID
0。也就是说,它的组将是root 的组,但用户不会。它需要是组 ID 0,因为如果以在 UNIX passwd 文件中没有条目的用户身份运行,UNIX 将默认使用该组。
- 应用程序需要读取权限的任何目录/文件都应该可以被其他人读取/访问,或者可以被群组
root读取/访问。
- 应用程序需要写入权限的任何目录/文件都应该可以由组
root 写入。
- 应用程序不应需要绑定特权端口的能力。从技术上讲,您可以通过使用 Linux 功能来解决这个问题,但是 Docker 映像的某些构建系统,例如 Docker Hub 自动构建,似乎不支持您使用 Linux 功能的各个方面,因此如果需要,您将无法使用这些功能构建图像使用
setcap。
最后,您会发现,如果使用 Red Hat 的 OpenShift Local (CDK) 或 OpenShift Origin 的一体化虚拟机,这些都不需要。这是因为这些 VM 映像已被特意设置为允许作为默认策略运行任何映像,甚至是希望以 root 身份运行的映像。这纯粹是为了更容易尝试下载的任意图像,但在生产系统中,您确实希望以更安全的方式运行图像,默认情况下能够以 root 身份运行图像。
如果您想详细了解以 root 身份运行容器的一些问题以及平台以任意用户 ID 身份运行容器时可能出现的问题,请查看以下博客系列文章: