取消共享用户命名空间并使用 newuidmap 设置 uid 映射
unshare user namespace and set uid mapping with newuidmap
我试图通过试验 unshare
和 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
/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
。
我试图通过试验 unshare
和 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
/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
。