java - 以非 root 用户身份运行需要 root 的脚本?
问题描述
现在的情况
我有一个基础 docker 镜像(基于 opensuse 构建),其他镜像都基于该镜像构建。
基础镜像在运行时运行一些启动脚本。
启动脚本运行的命令之一是:
update-ca-certificates
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
要求
容器在运行时执行的启动脚本应该能够以任意非 root 用户身份运行。
这个任意的非 root 用户应该能够由
USER
dockerfile 中的指令或--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
解决方案
推荐阅读
- sql - 在 Informix 中使用 sysmaster 用户连接时如何获取特定数据库的表列表?
- python - 在 python 中为整数值获取相同的字符,就像在 VB6 中一样
- c# - TreeView 粗体节点 (C#)
- angular - Angular 7 - tsconfig 需要一次文件刷新才能包含外部模块
- python-2.7 - 如何在 Python 2.7 上处理图形的文本文件
- xml - 使用 XSLT 转换包含不同值的重复 XML 元素
- javascript - 如何将路由连接到 server.js
- java - 本地日期解析在没有分隔符的情况下不起作用
- c# - 在 C# 中使用 File.Append 追加文本时访问被拒绝错误
- python - 如何在 python 中使用 keras 获得概率/置信度作为 CNN 的输出?