如何使用 docker 的 --user 选项将 uid 设置安全地添加到 docker 容器的 /etc/passwd 中

and*_*sch 8 fuse docker dockerfile

问题

对于应该以非 root 身份运行的 docker 映像(基于 alpine),我有两个要求:

  1. 我必须在 docker 容器内安装 FUSE 文件系统
  2. docker 镜像的用户可以设置 docker 用户的 UID/GIDdocker run --user {uid}:{gid}

FUSE 的fusermount命令需要用户在 中输入有效的条目/etc/passwd,否则它不会挂载文件系统。鉴于我在构建时不知道用户的 UID/GID,我无法adduser在构建时调用。我也无法在运行时执行此操作,因为用户没有适当的权限。

找到解决方案

到目前为止,我发现了两种感觉不合适/不安全的解决方案

1. 使/etc/passwd可写

当添加chmod 555 /etc/passwd到 Dockerfile 时,我可以在运行时执行

echo "someuser:x:${my_uid}:$(id -g)::/tmp:/sbin/nologin" >> /etc/passwd
Run Code Online (Sandbox Code Playgroud)

这完成了定影安装的工作。不幸的是,我没有找到一种方法可以在运行时将 passwd 文件更改回只读状态,如果没有这种方法,我就会担心有人可能会滥用它来重新获得 root 权限。虽然我找不到一种简单的方法来使用打开的 passwd 文件进行某些攻击(虽然我能够直接在 /etc/passwd 中为所有用户添加/修改密码和配置,然后通过 更改用户login,但 alpine 不允许这样做用户 root (既不是 vialogin也不是 via su)。但我想有人比我更聪明,不知何故整个解决方案感觉像是一个相当肮脏的黑客。有没有人有具体的想法如何使用容器内的可写 passwd 文件在容器内获得不适当的权限?

2. 将要求 #2 替换为两个附加环境变量

通过引入 DUID 和 DGID 作为环境变量并将 USER 设置为 Dockerfile 中新添加的非 root 用户,我在 sudo 和 /etc/sudoers 的帮助下找到了一个解决方案:在我用作入口点的启动脚本中,我可以调用 sudo adduser/addgroup 为给定的 DUID/DGID,然后使用通过 指定的用户启动实际程序sudo -u someuser someprog

除了整个设置变得相当丑陋之外,我不喜欢我的 docker 镜像的用户无法再使用常规选项docker run --user,因为这会破坏 sudo 配置。