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

cat*_*man 3 linux linux-namespaces

我正在尝试通过使用unshareand newuidmap命令来更好地理解用户名称空间。

这些是我运行的命令:

[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
Run Code Online (Sandbox Code Playgroud)

/ etc / subuid:

nobody:5000:1
root:5000:1
Run Code Online (Sandbox Code Playgroud)

知道为什么这失败了吗?

然后,我尝试newuidmap在父命名空间的同一PID上运行命令,它似乎可以正常工作:

[root@host ~]$ newuidmap 7134 65534 5000 1
[root@host ~]$ cat /proc/7134/uid_map 
 65534       5000          1
Run Code Online (Sandbox Code Playgroud)

但是,当我从新名称空间中运行进程时,它似乎仍以root身份而不是UID 5000身份运行:

[nobody@host ~]$ exec sleep 20
Run Code Online (Sandbox Code Playgroud)

从另一个shell:

[root@host ~]$ ps aux | grep 7134
root      7134  0.0  0.0   7292   708 pts/2    S+   02:07   0:00 sleep 20
Run Code Online (Sandbox Code Playgroud)

我想念什么?

Ark*_*rks 7

Catanman

1)

[nobody@host ~]$ newuidmap 7134 65534 5000 1
newuidmap: write to uid_map failed: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

知道为什么这失败了吗?

文档(http://man7.org/linux/man-pages/man7/user_namespaces.7.html)指出以下内容:

由clone(2)使用CLONE_NEWUSER标志创建的子进程从新用户名称空间中的一组完整功能开始。<...>请注意,对execve(2)的调用将导致以通常的方式重新计算流程的功能(请参阅capabilities(7))。

发生这种情况是因为unshare在将控制权重新授予用户之前调用了“ exec bash”,并且您释放了必要的功能,因此您无法在用户名称空间中更改uid_map / gid_map。

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

2)

但是,当我从新名称空间中运行进程时,它似乎仍以root身份而不是UID 5000身份运行:

我想念什么?

  • 映射不会更改用户。映射将子命名空间中的ID链接到其父命名空间中的ID,而不是相反的方式。
  • 您可以在子名称空间中调用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
Run Code Online (Sandbox Code Playgroud)

现在,让我们在子名称空间中将父名称空间的根与某些ID(在这种情况下为0)链接起来:

arksnote linux-namespaces   # newuidmap 18526 0 0 1
arksnote linux-namespaces   # cat /proc/18526/uid_map
         0          0          1
Run Code Online (Sandbox Code Playgroud)

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

nobody@arksnote ~  $ id
uid=0(root) gid=65534(nobody) ??????=65534(nobody)
Run Code Online (Sandbox Code Playgroud)

您可以尝试其他一些映射,例如,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
Run Code Online (Sandbox Code Playgroud)

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

nobody@arksnote ~  $ id
uid=65534(nobody) gid=65534(nobody) ??????=65534(nobody)
Run Code Online (Sandbox Code Playgroud)

您所做的[root@host ~]$ newuidmap 7134 65534 5000 1是将父名称空间中的userid 5000与子名称空间中的uid 65534关联,但是该过程仍以方式运行root。它仅显示为65534,因为此值用于任何未知的id:

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

参见Unmapped user and group IDsuser_namespaces(7)。

  • `newuidmap:不允许 uid 范围 [0-1) -&gt; [0-1)` (2认同)