我跑unshare -r touch file
。然而,unshare -r chown nobody file
给了我Invalid argument
。为什么?
答案1
创建新的用户命名空间后,为了“完成”此操作,必须一劳永逸地完成 UID 和 GID 映射。
初始用户(如果没有特权)可以执行此映射,但只能将其自身映射到新用户命名空间中:这意味着仅一UID 和一GID 无需特权即可映射。
在这种受限情况下,新用户命名空间中只有两个用户是此单个用户映射的有趣候选者:要么 root,以获得包括与其他关联命名空间(例如:网络或挂载)相关的权限,要么是其本身(通常具有多层)用户命名空间:initial (john) -> userns1 (root) -> userns2 (john again) )。所以通常会选择 root(这就是该-r
选项的作用)。
在 root 权限中,有些权限与更改或影响进程、文件的 UID 相关……但是在这个新的用户命名空间中,除了所选的 UID(0 代表 root)之外,所有其他 UID 都不会被映射。它们被映射为(溢出的UID)无人(65534)并且任何改变或更改它们的尝试都会导致 EINVAL(无效参数)。这与 EPERM(不允许操作)不同,后者是初始用户命名空间中非特权用户执行相同操作的结果。但总体目标是相同的:无法通过尝试使用用户命名空间进行欺骗来获得主机(初始命名空间...)的特权或访问权限。
如果您必须在非特权用户创建的命名空间中使用多个 UID,则必须使用特权帮手。此类助手无处不在,并且是与非特权用户一起使用时容器技术(Docker、LXC ...)的先决条件:newuidmap
(及其同伴newgidmap
)。该工具是 setuid-root(它至少需要 CAP_SETUID,但可能还需要其他一些),并且除了用户本身之外,还可以向新用户命名空间授予从/etc/subuid
/中每个用户条目的整个映射范围。/etc/subgid
更多详细信息可以在此 Q/A 中找到:可以使用从属用户 ID 来授予文件系统权限吗?
答案2
只有 root 可以将所有权更改给其他用户。你unshare -r
将成为root,但仅限于你自己的命名空间
~$ unshare -r touch /tmp/foo
~$ unshare -r ls -l /tmp/foo
-rw-r--r-- 1 root root 0 27. Jul 14:20 /tmp/foo
~$ ls -l /tmp/foo
-rw-r--r-- 1 user user 0 27. Jul 14:20 /tmp/foo
由于chown
命名空间中的 会篡改“真实”命名空间中的文件系统,因此可以防止这种情况。