为什么允许普通用户通过运行“podman unshare chown”来放弃文件/文件夹?

Fan*_*ien 5 linux permissions chown docker

我认为通常不允许普通用户通过运行chown没有sudo. 在 unix.stackexchange 上提出并回答了一个问题:为什么普通用户不能访问chown文件?。我明白了为什么要这样设计。

最近我开始玩rootless Podman。然后我了解到,例如,我可以运行

podman unshare chown -R 1111:1111 folder/
Run Code Online (Sandbox Code Playgroud)

将文件夹的所有权更改folder为另一个用户/组(在上面的示例中,默认101110:101110情况下位于主机上)。

从某种意义上说,它打破了前面提到的限制。为什么这是允许的?它会导致一些潜在的安全问题吗?/etc/subid(也许 root 用户在分配命名空间时应该小心?)

我只是一个业余爱好者,我在自己的笔记本电脑上运行所有内容。所以我不需要对此过于担心。不过,我想问这个问题只是出于好奇。

A.B*_*A.B 6

TL;DR: rootless podman 需要newuidmap和 ,newgidmap它们是 setuid root 二进制文件,允许引导无根容器的操作。

回答所提出的问题:

可以通过使用无根容器创建的所有uid:gid值首先已为给定用户保留。它们没有被泄露,因为通过检查 和 的(从不重叠)内容,可以轻松地将这些附加的uid :gid值关联回单个原始用户。/etc/subuid/etc/subgid

长示例并附有解释。


以下是执行与 OP 相同命令的低级工具,可在每个标准 Linux 系统(例如 Debian、RHEL (>= 7.7) 等)上使用:

1号航站楼:

user@host$ stat -c '%u:%g %n' folder/a folder
1000:1000 folder/a
1000:1000 folder
user@host$ chown -R 1111:1111 folder/
chown: changing ownership of 'folder/a': Operation not permitted
chown: changing ownership of 'folder/': Operation not permitted
user@host$ id -u; id -g
1000
1000
user@host$ unshare -U
nobody@host$ echo $$
11893
nobody@host$ id -u; id -g
65534
65534
nobody@host$ chown -R 1111:1111 folder/
chown: changing ownership of 'folder/a': Invalid argument
chown: changing ownership of 'folder/': Invalid argument
Run Code Online (Sandbox Code Playgroud)

请注意,现在的错误甚至不一样(见下文)。

航站楼2:

user@host$ grep ^user: /etc/subuid /etc/subgid
/etc/subuid:user:1410720:65536
/etc/subgid:user:1410720:65536
user@host$ newuidmap 11893 0 1000 1 1 1410721 65535
user@host$ newgidmap 11893 0 1000 1 1 1410721 65535
Run Code Online (Sandbox Code Playgroud)

上面的命令将用户的真实 id 和 gid(除了 subids 和 subgids 之外也有效)映射为新创建的用户命名空间中的 root(其唯一成员是 shell 进程(以及从中运行的命令)),并映射(几乎)subid 和 subgid 的整个分配范围也给它。由于对于 uid 只能执行一次,对于 gid 只能执行一次,因此必须一次性完成。

再次在 Terminal1 上:

nobody@host$ id -u; id -g; exec bash
0
0
root@host# 
root@host# chown -v -R 1111:1111 folder/
changed ownership of 'folder/a' from root:root to 1111:1111
changed ownership of 'folder/' from root:root to 1111:1111
Run Code Online (Sandbox Code Playgroud)

在终端 2 上:

user@host$ stat -c '%u:%g %n' folder/a folder
1411831:1411831 folder/a
1411831:1411831 folder
Run Code Online (Sandbox Code Playgroud)

其中我们有 1411831-1111=1410720

对于OP的情况,考虑到101110-1111=99999,podman更有可能也映射/etc/subuid第一个subuid(如1),给出了101110-1111+1=100000,所以100000是给/etc/subgid定用户的可能值。无论如何,你明白了。

为什么这有效?这很简单:newuidmapnewgidmap都是 setuid root 命令,或者至少有足够的功能能够正常工作。/etc/subuid它们是辅助工具,允许普通用户创建一个简单的用户命名空间,以使用在/etc/subgid帐户最初创建时提供的分配的映射。

user@host$ stat -c %A /usr/bin/newuidmap /usr/bin/newgidmap
-rwsr-xr-x
-rwsr-xr-x
Run Code Online (Sandbox Code Playgroud)

现在,从主机映射到用户命名空间的uid:gid的整个范围可用于该用户命名空间中的正常操作。因此,在此用户命名空间内,其根用户可以将值从范围内的任何值更改为范围内的任何其他值。大多数情况下,范围是 65536 个条目的切片(或者对于 podman 可能是 1+65536=65537),但主机为此提供了 2^32-1 的范围。不是用户命名空间:

1号航站楼:

root@host# chown 66000 folder
chown: changing ownership of 'folder': Invalid argument
Run Code Online (Sandbox Code Playgroud)

未映射,这是以前根本未完成映射时出现的类似错误的情况。

请注意,如故障排除中所述,rootless podman 确实使用newuidmapnewgidmap

9) 运行无根 Podman 命令时 Newuidmap 丢失

Rootless Podman 需要安装 newuidmap 和 newgidmap 程序。

uid 映射的更多内部工作原理可以在用户命名空间联机帮助页中找到。