在尝试 LXD 时,我尝试与 LXC 容器共享计算机中的文件夹,但我无法在容器中的文件夹中写入,因为ls -l
显示它属于 usernobody
和 group nobody
。
如何知道这个用户和组的ID?
答案1
您还可以使用以下id
命令查找 uids 和 gids:
# Get the numeric uid of the user 'nobody'
$ id -u nobody
65534
# Get the numeric gid of the user 'nobody'
$ id -g nobody
65534
如果没有选项,它将打印 uid 和用户所属的所有 gids:
$ id nobody
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
答案2
我发现该ls
命令可以选择-n
查看 ID 而不是名称:
-n, --numeric-uid-gid like -l, but list numeric user and group IDs
所以我使用了ls -ln
,它向我显示了 ID:
65534 65534
答案3
从OP的上下文来看:使用容器和命名空间,我将假设还涉及用户命名空间,因此没有人和无组不寻常没有人和无组预期的用户和组。
该用户没有人实际上可能是溢出尝试访问未映射到当前用户命名空间的用户 ID 时返回的用户 ID,而不是实际用户没有人。默认情况下,溢出用户 ID 映射到没有人。
只要下面的命令不返回三元组 0 0 4294967295(意味着所有内容都已映射,如初始用户命名空间中一样),则可能会发生这种情况:
$ cat /proc/self/uid_map
0 0 4294967295
$ cat /proc/self/gid_map
0 0 4294967295
这是相关段落用户命名空间(7):
有很多地方可以未映射的用户 ID(组 ID)可能会暴露给用户空间。例如,新用户命名空间中的第一个进程可能会在为命名空间定义用户 ID 映射之前调用 getuid(2)。在大多数此类情况下,将未映射的用户ID转换为溢出用户ID(组ID);溢出用户ID(组ID)的默认值为65534。
/proc/sys/kernel/overflowuid
请参阅和/proc/sys/kernel/overflowgid
中 的描述 过程(5)。以这种方式映射未映射 ID 的情况包括返回用户 ID 的系统调用(获取UID(2),获取gid(2)等),通过 UNIX 域套接字传递的凭据,由 stat(2)、waitid(2) 返回的凭据,
[...]
一个简单的例子可以看出这一点,即在没有任何映射的情况下启动一个新的用户命名空间unshare -U
,无论是从根用户还是非特权用户。此处显示从初始主机真实根开始,以获得更多自由并overflowuid
稍后进行更改:
root@host:~# newgrp daemon
root@host:~# id
uid=0(root) gid=1(daemon) groups=1(daemon),0(root)
root@host:~# id bin
uid=2(bin) gid=2(bin) groups=2(bin)
root@host:~# id sys
uid=3(sys) gid=3(sys) groups=3(sys)
root@host:~# touch /tmp/foo
root@host:~# chown bin:sys /tmp/foo
root@host:~# ls -l /tmp/foo; ls -n /tmp/foo
-rw-r--r-- 1 bin sys 0 Oct 11 21:34 /tmp/foo
-rw-r--r-- 1 2 3 0 Oct 11 21:34 /tmp/foo
root@host:~# unshare -U
nobody@host:~$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
nobody@host:~$ ls -l /tmp/foo; ls -n /tmp/foo
-rw-r--r-- 1 nobody nogroup 0 Oct 11 21:34 /tmp/foo
-rw-r--r-- 1 65534 65534 0 Oct 11 21:34 /tmp/foo
nobody@host:~$ exit
logout
root@host:~# sysctl -w kernel.overflowuid=60000
kernel.overflowuid = 60000
root@host:~# sysctl -w kernel.overflowgid=61000
kernel.overflowgid = 61000
root@host:~# unshare -U
$ id
uid=60000 gid=61000 groups=61000
$ ls -l /tmp/foo; ls -n /tmp/foo
-rw-r--r-- 1 60000 61000 0 Oct 11 21:34 /tmp/foo
-rw-r--r-- 1 60000 61000 0 Oct 11 21:34 /tmp/foo
$ exit
logout
root@host:~#
所以现实要复杂得多。在显示溢出 UID/GID 的容器内,如果未映射到不同的值,则无法确定父命名空间中存在的实际 UID/GID 是哪一个。这里,溢出值 60000 和 61000 取代了默认值 65534,不会从父命名空间指向原始 UID/GID:它们是否代表 0(root)、1(daemon)、2(bin)、 3(sys) 还是其他什么?没办法知道。