问题
I'm trying to gain a better understanding of user namespaces by experimenting with the unshare
and newuidmap
commands.
These are the commands I ran:
[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
Any idea why this is failing?
I then tried to run the newuidmap
command on the same PID from the parent namespace and it appeared to work:
[root@host ~]$ newuidmap 7134 65534 5000 1
[root@host ~]$ cat /proc/7134/uid_map
65534 5000 1
But when I run a process from within the new namespace it still seems to run as root instead of UID 5000:
[nobody@host ~]$ exec sleep 20
From another shell:
[root@host ~]$ ps aux | grep 7134
root 7134 0.0 0.0 7292 708 pts/2 S+ 02:07 0:00 sleep 20
What am I missing?
回答1:
catanman
1)
[nobody@host ~]$ newuidmap 7134 65534 5000 1 newuidmap: write to uid_map failed: Operation not permitted
Any idea why this is failing?
Documentation (http://man7.org/linux/man-pages/man7/user_namespaces.7.html) states the following:
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)).
This happens because unshare calls 'exec bash' before returing the control to the user and you loose the necessary capabilities, thus you cannot change uid_map/gid_map from within user namespace.
Still, if you compile some application (e.g. you can make a small fix in an example from user_namespaces(7)) which updates uid_map/gid_map before 'exec', the update will succeed.
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?
- The mapping does not change the user. The mapping links ids in a child namespace to ids in its parent namespace, not the opposite way.
- You can call
setuid(2)
orseteuid(2)
from within a child namespace to change the credentials to some other credentials from the same user namespace. They of course should be mapped onto the values in the parent namespace, otherwise geteuid() function will fail.
Here are two examples:
Example 1. Suppose we have created a child user namespace.
arksnote linux-namespaces # unshare -U bash
nobody@arksnote ~ $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)
nobody@arksnote ~ $ echo $$
18526
Now let's link root from parent namespace with some id (0 in this case) in a child namespace:
arksnote linux-namespaces # newuidmap 18526 0 0 1
arksnote linux-namespaces # cat /proc/18526/uid_map
0 0 1
Here's what happens to the child namespace:
nobody@arksnote ~ $ id
uid=0(root) gid=65534(nobody) группы=65534(nobody)
You can try some other mappings, like newuidmap 18526 1 0 1
and see that it is applied to the child user namespace, not the parent one.
Example 2: Now we does not set a mapping for root
:
arksnote linux-namespaces # newuidmap 18868 0 1000 1
arksnote linux-namespaces # cat /proc/18868/uid_map
0 1000 1
In this case the user root
is left unknown for the child user namespace:
nobody@arksnote ~ $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)
What you have done with [root@host ~]$ newuidmap 7134 65534 5000 1
was association of userid 5000 in a parent namespace with uid 65534 in a child namespace, but the process still runs as root
. It is shown as 65534 only because this value is used for any unknown id:
Functions getuid(), getgid() returns the value from /proc/sys/kernel/overflowgid
for uids/gids which does not have a mapping. The value corresponds to a special user without any system rights:nobody
, as you can see in uid/gid in the output above.
See Unmapped user and group IDs
in user_namespaces(7).
来源:https://stackoverflow.com/questions/45972426/unshare-user-namespace-and-set-uid-mapping-with-newuidmap