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

时间:2017-08-31 02:45:01

标签: linux linux-namespaces

我尝试通过试用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 个答案:

答案 0 :(得分:5)

catanman

1)

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

知道为什么会失败吗?

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

  

clone(2)使用CLONE_NEWUSER标志创建的子进程   从新用户开始,提供一整套功能   命名空间。 < ...>请注意,调用execve(2)将导致进程   以通常的方式重新计算的能力(见   能力(7))。

这是因为取消共享电话' 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

现在让我们在父命名空间中链接根,并在子命名空间中使用一些id(在本例中为0):

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所做的是父命名空间中的userid 5000与子命名空间中的uid 65534的关联,但该过程仍然以root运行。它仅显示为65534,因为此值用于任何未知ID:

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

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