在 root 中安装所有软件包并切换到非 root 用户或直接在 dockerfile 中使用 `gosu` 或 `sudo`?

问题描述 投票:0回答:1

要遵循 Docker 镜像的最佳实践,我们必须以非 root 用户身份运行容器(如此处所述)。

其中一个想法是添加类似于以下行的内容:

ARG USERNAME=user
ARG USER_UID=1000
ARG USER_GID=1000

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
USER $USERNAME 

但是,安装软件包的需要使得必须使用

root
用户或使用
sudo
gosu
。另外,不建议从 root 和容器用户返回并更改用户。

因此,我问自己几个有关安全最佳实践的问题:

  • 我们是否应该在 Dockerfile 的 root 中安装所有软件包,然后继续使用更新所有内容后创建的用户,这存在来回移动的风险,例如与非 root 用户一起使用 pip,甚至
    cargo
    生锈?
  • 使用
    gosu
    (甚至
    sudo
    并将用户添加到 sudoers)是否有价值?这是否意味着创建的用户将是 sudoer 并且具有 root 权限?
  • root 是否仍应作为特权用户在 docker 内可用?
docker security pip
1个回答
0
投票

我们是否应该在 Dockerfile 的根目录中安装所有软件包,然后继续更新所有内容后创建的用户

是的。请注意,某些操作系统工具(例如 Debian APT 包管理器)需要以 root 身份运行。

我认为以 root 身份构建应用程序并在 Dockerfile 的最后仅切换到非 root

USER
是合理的。

使用

gosu
(甚至
sudo
并将用户添加到 sudoers)是否有价值?

不。我在 SO 问题中看到的“模式”通常涉及为用户分配一个易于猜测的固定密码,该密码在源代码管理和

docker history
中显而易见,然后为该用户提供不受限制的
sudo
权限。这可能可以防止某些类型的事故,但真正的攻击者很快就会发现他们只需要在命令前加上
sudo
前缀即可。

您可能根本不应该安装

sudo
。根据需要切换
USER
(即使多次)更容易,并且不需要额外的设置。

root 是否仍应作为特权用户在 docker 内可用?

实际上,“root”被定义为用户 ID 为 0 的用户。即使您从

docker run -u 0
中删除了
docker exec -u 0
条目,您也无法阻止
root
/etc/passwd
。我不会尝试禁用此功能。

使用

gosu
(重访)有价值吗?

有一种常见的模式,即使用图像的

ENTRYPOINT
作为包装脚本来进行一些首次设置,然后使用 Bourne shell
exec "$@"
切换到主
CMD
。我偶尔会看到这样的图像:首次设置必须以 root 身份完成,但您不希望主进程以 root 身份完成。在这种特定情况下,使用
gosu
“降级”到非特权用户非常有用。

#!/bin/sh
# entrypoint.sh

if [ "$(id -u)" != 0 ]; then
  echo 'container must start as root' >&2
  exit 1
fi

chown user /foo  # or something else that must be root

exec gosu user "$@"

最后:我反对将用户名或数字 ID 作为 Dockerfile 传递

ARG
。为用户选择一个固定名称,然后让 useradd(8) 自行选择数字 uid。您通常不想构建特定于特定主机用户 ID 的映像。另一方面,没有特定要求用户“存在”,并且当您运行容器时,您几乎总是可以
docker run -u $(id -u)
假设主机用户的数字 uid,而无需进行进一步设置。

© www.soinside.com 2019 - 2024. All rights reserved.