取消共享用户命名空间并使用 newuidmap 设置 uid 映射

unshare user namespace and set uid mapping with newuidmap

我试图通过试验 unsharenewuidmap 命令来更好地理解用户命名空间。

这些是我的命令 运行:

[root@host ~]$ ls -l /usr/bin/newuidmap
-rwsr-xr-x 1 root root 32944 May 16 19:37 /usr/bin/newuidmap
[root@host ~]$  unshare -U bash namespace
[nobody@host ~]$ echo $$
7134
[nobody@host ~]$ newuidmap 7134 65534 5000 1
newuidmap: write to uid_map failed: Operation not permitted

/etc/subuid:

nobody:5000:1
root:5000:1

知道为什么会失败吗?

然后我尝试 运行 来自父名称空间的同一 PID 上的 newuidmap 命令,它似乎有效:

[root@host ~]$ newuidmap 7134 65534 5000 1
[root@host ~]$ cat /proc/7134/uid_map 
 65534       5000          1

但是当我 运行 来自新命名空间的进程时,它似乎仍然 运行 作为 root 而不是 UID 5000:

[nobody@host ~]$ exec sleep 20

来自另一个shell:

[root@host ~]$ ps aux | grep 7134
root      7134  0.0  0.0   7292   708 pts/2    S+   02:07   0:00 sleep 20

我错过了什么?

卡坦曼

1)

[nobody@host ~]$ newuidmap 7134 65534 5000 1
newuidmap: write to uid_map failed: Operation not permitted

Any idea why this is failing?

文档 (http://man7.org/linux/man-pages/man7/user_namespaces.7.html) 声明如下:

The child process created by clone(2) with the CLONE_NEWUSER flag starts out with a complete set of capabilities in the new user namespace. <...> Note that a call to execve(2) will cause a process's capabilities to be recalculated in the usual way (see capabilities(7)).

发生这种情况是因为取消共享在将控制权返回给用户之前调用了 'exec bash',并且您失去了必要的功能,因此您无法从用户命名空间中更改 uid_map/gid_map。

不过,如果您编译某些应用程序(例如,您可以在 user_namespaces(7) 的示例中进行小的修复)在 'exec' 之前更新 uid_map/gid_map,则更新将成功。

2)

But when I run a process from within the new namespace it still seems to run as root instead of UID 5000:

What am I missing?

  • 映射不改变用户。将子命名空间中的 links ids 映射到其父命名空间中的 ids,而不是相反的方式。
  • 您可以从子命名空间内调用 setuid(2)seteuid(2) 以将凭据更改为来自同一用户命名空间的一些其他凭据。它们当然应该映射到父命名空间中的值,否则 geteuid() 函数将失败。

这里有两个例子:

示例1.假设我们已经创建了一个子用户命名空间。

arksnote linux-namespaces   # unshare -U bash
nobody@arksnote ~  $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)
nobody@arksnote ~  $ echo $$
18526

现在让我们link从子命名空间中的一些id(在本例中为0)的父命名空间root:

arksnote linux-namespaces   # newuidmap 18526 0 0 1
arksnote linux-namespaces   # cat /proc/18526/uid_map
         0          0          1

这是子命名空间发生的情况:

nobody@arksnote ~  $ id
uid=0(root) gid=65534(nobody) группы=65534(nobody)

您可以尝试一些其他映射,例如 newuidmap 18526 1 0 1,看看它是否应用于子用户命名空间,而不是父用户命名空间。

例2:现在我们不为root设置映射:

arksnote linux-namespaces   # newuidmap 18868 0  1000 1
arksnote linux-namespaces   # cat /proc/18868/uid_map
         0       1000          1

在这种情况下,子用户命名空间的用户 root 未知:

nobody@arksnote ~  $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)

您对 [root@host ~]$ newuidmap 7134 65534 5000 1 所做的是将父命名空间中的用户 ID 5000 与子命名空间中的用户 ID 65534 关联起来,但该进程仍以 root 运行。它显示为 65534 只是因为这个值用于任何未知的 id:

函数 getuid()、getgid() returns 来自 /proc/sys/kernel/overflowgid 的 uids/gids 的值没有映射。该值对应于没有任何系统权限的特殊用户:nobody,如您在上面输出中的 uid/gid 中所见。

参见 user_namespaces(7) 中的 Unmapped user and group IDs