卡坦曼
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))。
发生这种情况是因为 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
现在让我们将父命名空间中的根与子命名空间中的某个 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() 从/proc/sys/kernel/overflowgid
没有映射的 uids/gids 返回值。该值对应于没有任何系统权限的特殊用户:nobody
,正如您在上面输出中的 uid/gid 中看到的那样。
参见Unmapped user and group IDs
user_namespaces(7)。