通过简单地从头开始在容器中设置随机UID来创建非root用户的工作原理是什么?

时间:2019-05-09 11:30:40

标签: docker go dockerfile

我正在使用Docker设置Golang服务器,为了安全起见,我希望没有特权的用户在其容器内启动它。

这是我使用的简单Dockerfile。我将二进制文件导入容器并设置一个随机UID。

FROM scratch
WORKDIR /app
COPY --chown=1001:1001 my-app-binary my-app-binary
USER 1001
CMD ["/app/my-app-binary"]

如果我的服务器侦听端口443,则它不起作用,因为它需要特权权限。因此,我的应用程序按预期由非特权用户运行。

尽管如此,未正确创建用户1001。我看到的教程告诉我要在一个中间“构建器”容器(例如,alpine)中创建用户,并从中导入/ etc / passwd。我没有发现做我的工作的任何例子。 (here我遵循了一个教程)

有人可以向我解释为什么我的解决方案有效或我不理解吗?

1 个答案:

答案 0 :(得分:2)

披露:在我的回答中,我使用了this blog post中的引号。我既不是本文的作者,也不是与作者相关的任何人。

可以预料-容器可以在容器未知的用户下运行。引用docker run docs

  

root(id = 0)是容器中的默认用户。图像开发人员可以创建其他用户。这些用户可以通过名称访问。 传递数字ID时,用户不必在容器中。

     

-https://docs.docker.com/engine/reference/#user

它可以帮助您解决以下问题:

  

有时候,当我们在Docker容器中运行构建时,构建会在从主机(例如源代码目录)将其安装到容器中的文件夹中创建文件。这会给我们带来痛苦,因为这些文件将由root用户拥有。当普通用户在准备下一个版本时尝试清理这些文件时(例如,使用git clean),他们会收到错误消息,并且我们的版本将失败。

     

-https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#7d3a

这可能是因为:

  

幸运的是,docker run为我们提供了一种方法:the --user parameter。我们将使用它来指定Docker应该使用的用户ID(UID)和组ID(GID)。之所以可行,是因为Docker容器都共享相同的内核,因此也共享相同的UID和GID列表,即使容器不知道相关的用户名(稍后会详细介绍)。

     

-https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#b430

以上内容也适用于USER dockerfile command

使用容器未知的UID有一些陷阱:

  

您的用户将少$ HOME

     

我们在这里实际要做的是让我们的Docker容器使用一无所知的用户ID进行操作,这会带来一些麻烦。也就是说,这意味着用户正在丢失一些我们已经学到的仅希望用户拥有的东西-诸如主目录之类的东西。这可能很麻烦,因为这意味着$ HOME $中的所有内容(包括临时文件,应用程序设置,程序包缓存)现在都无处可住。容器化过程只是无法知道将它们放在哪里。

     

当我们尝试做特定于用户的事情时,这可能会影响我们。我们发现使用gem install会导致问题(尽管使用Bundler可以),或者运行依赖于ENV['HOME']的代码。因此,这可能意味着您需要做一些调整。

     

您的用户也将是匿名的

     

事实证明,我们无法轻松地在Docker主机及其容器之间共享用户名。这就是为什么我们不能只使用docker run --user=$(whoami)的原因-容器不知道您的用户名。它只能通过其UID来找到有关您用户的信息。

     

这意味着当您在容器中运行whoami时,将得到类似I have no name!的结果。这很有趣,但是如果您的代码依赖于知道您的用户名,那么您可能会得到一些令人困惑的结果。

     

-https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15#e295