首页 > 解决方案 > 以非 root 用户身份运行需要 root 的脚本?

问题描述

现在的情况

我有一个基础 docker 镜像(基于 opensuse 构建),其他镜像都基于该镜像构建。

基础镜像在运行时运行一些启动脚本。

启动脚本运行的命令之一是:

update-ca-certificates

https://manpages.ubuntu.com/manpages/xenial/man8/update-ca-certificates.8.html#:~:text=update%2Dca%2Dcertificates%20is%20a,%2Fetc%2Fca%2Dcertificates

update-ca-certificates写入root拥有的以下目录:

/var/lib/ca-certificates

update-ca-certificates还调用chmod目录,因为chmod只能以目录的所有者身份运行,这意味着update-ca-certificates必须以 root 身份运行:

https://github.com/p11-glue/p11-kit/blob/master/trust/save.c#L614

要求

  1. 容器在运行时执行的启动脚本应该能够以任意非 root 用户身份运行。

  2. 这个任意的非 root 用户应该能够由USERdockerfile 中的指令或--user=xxx:yyy传递给的标志提供docker run

什么尝试过

选项 1:须藤

尝试的第一件事是将任何用户可以使用 sudo 运行的有限数量的命令引入基本映像,这将允许非 root 用户运行启动脚本。

例如,将以下文件添加到 /etc/sudoers.d:

ALL ALL=(ALL) NOPASSWD: /usr/sbin/update-ca-certificates

然后更新启动脚本以将 sudo 添加到命令中:

sudo update-ca-certificates

选项1的问题:

sudo 检查 passwd 文件以将 uid 解析为用户名以进行权限检查,因此用户需要首先存在于容器中。此选项不适用于匿名用户或域用户,因为它们不存在于 passwd 文件中。看到以下错误:

sudo: unknown uid xxx: who are you?

选项 2:setuid

setuid 权限位告诉 Linux 以所有者 (root) 的有效用户 id 运行程序,而不是执行者。

如果我们/usr/sbin/update-ca-certificates使用 setuid 标志运行,它可能会起作用。就像是:

chmod u+s /usr/sbin/update-ca-certificates
/usr/sbin/update-ca-certificates

选项2的问题:

setuid 仅适用于可执行文件,shell 脚本(例如update-ca-certificates)忽略 setuid 位。

我们可以将其包装update-ca-certificates在一个二进制文件中,如下所述:

https://unix.stackexchange.com/a/369

但是,正如对上述帖子的评论所述,这可能是一种不安全的方法。

选项3:暂时开放/var/lib/ca-certificates目录的权限

接下来尝试的是打开/var/lib/ca-certificates目录上的权限(临时),以便任何用户都可以写入它们。就像是:

RUN chmod -R ugo+rwx /var/lib/ca-certificates

选项3的问题:

选项 3 仅在update-ca-certificates调用chmod目录时起作用:

https://github.com/p11-glue/p11-kit/blob/master/trust/save.c#L614

由于chmod只能由目录的所有者(root)运行,因此会出现以下错误:

p11-kit: couldn't set directory permissions: /var/lib/ca-certificates/openssl: Operation not permitted

/var/lib/ca-certificates选项 4:临时更改dir的所有者

继选项 3 的问题之后,我想看看是否可以临时更改/var/lib/ca-certificates目录的所有者。

但是,我认为这是不可能的,因为在构建时基本映像不会知道任意的非 root 用户:

RUN sudo chown -R <DON'T KNOW THE USER YET?> /var/lib/ca-certificates

标签: javalinuxdockersslopensuse

解决方案


推荐阅读