table of contents
UNSHARE(1) | User Commands | UNSHARE(1) |
NAME¶
unshare - run program in new namespaces
SYNOPSIS¶
unshare [options] [program [arguments]]
DESCRIPTION¶
The unshare command creates new namespaces (as specified by the command-line options described below) and then executes the specified program. If program is not given, then "${SHELL}" is run (default: /bin/sh).
By default, a new namespace persists only as long as it has member processes. A new namespace can be made persistent even when it has no member processes by bind mounting /proc/pid/ns/type files to a filesystem path. A namespace that has been made persistent in this way can subsequently be entered with nsenter(1) even after the program terminates (except PID namespaces where a permanently running init process is required). Once a persistent namespace is no longer needed, it can be unpersisted by using umount(8) to remove the bind mount. See the EXAMPLES section for more details.
unshare since util-linux version 2.36 uses /proc/[pid]/ns/pid_for_children and /proc/[pid]/ns/time_for_children files for persistent PID and TIME namespaces. This change requires Linux kernel 4.17 or newer.
The following types of namespaces can be created with unshare:
mount namespace
unshare since util-linux version 2.27 automatically sets propagation to private in a new mount namespace to make sure that the new namespace is really unshared. It’s possible to disable this feature with option --propagation unchanged. Note that private is the kernel default.
UTS namespace
IPC namespace
network namespace
PID namespace
cgroup namespace
user namespace
time namespace
OPTIONS¶
-i, --ipc[=file]
-m, --mount[=file]
-n, --net[=file]
-p, --pid[=file]
See also the --fork and --mount-proc options.
-u, --uts[=file]
-U, --user[=file]
-C, --cgroup[=file]
-T, --time[=file]
-f, --fork
--keep-caps
--kill-child[=signame]
--mount-proc[=mountpoint]
--map-user=uid|name
--map-users=outeruid,inneruid,count|auto
--map-group=gid|name
--map-groups=outergid,innergid,count|auto
--map-auto
-r, --map-root-user
-c, --map-current-user
--propagation private|shared|slave|unchanged
--setgroups allow|deny
To be able to call setgroups(2), the calling process must at least have CAP_SETGID. But since Linux 3.19 a further restriction applies: the kernel gives permission to call setgroups(2) only after the GID map (/proc/pid*/gid_map*) has been set. The GID map is writable by root when setgroups(2) is enabled (i.e., allow, the default), and the GID map becomes writable by unprivileged processes when setgroups(2) is permanently disabled (with deny).
-R, --root=dir
-w, --wd=dir
-S, --setuid uid
-G, --setgid gid
--monotonic offset
--boottime offset
-h, --help
-V, --version
NOTES¶
The proc and sysfs filesystems mounting as root in a user namespace have to be restricted so that a less privileged user cannot get more access to sensitive files that a more privileged user made unavailable. In short the rule for proc and sysfs is as close to a bind mount as possible.
EXAMPLES¶
The following command creates a PID namespace, using --fork to ensure that the executed command is performed in a child process that (being the first process in the namespace) has PID 1. The --mount-proc option ensures that a new mount namespace is also simultaneously created and that a new proc(5) filesystem is mounted that contains information corresponding to the new PID namespace. When the readlink(1) command terminates, the new namespaces are automatically torn down.
# unshare --fork --pid --mount-proc readlink /proc/self 1
As an unprivileged user, create a new user namespace where the user’s credentials are mapped to the root IDs inside the namespace:
$ id -u; id -g 1000 1000 $ unshare --user --map-root-user \
sh -c ''whoami; cat /proc/self/uid_map /proc/self/gid_map'' root
0 1000 1
0 1000 1
As an unprivileged user, create a user namespace where the first 65536 IDs are all mapped, and the user’s credentials are mapped to the root IDs inside the namespace. The map is determined by the subordinate IDs assigned in subuid(5) and subgid(5). Demonstrate this mapping by creating a file with user ID 1 and group ID 1. For brevity, only the user ID mappings are shown:
$ id -u 1000 $ cat /etc/subuid 1000:100000:65536 $ unshare --user --map-auto --map-root-user # id -u 0 # cat /proc/self/uid_map
0 1000 1
1 100000 65535 # touch file; chown 1:1 file # ls -ln --time-style=+ file -rw-r--r-- 1 1 1 0 file # exit $ ls -ln --time-style=+ file -rw-r--r-- 1 100000 100000 0 file
The first of the following commands creates a new persistent UTS namespace and modifies the hostname as seen in that namespace. The namespace is then entered with nsenter(1) in order to display the modified hostname; this step demonstrates that the UTS namespace continues to exist even though the namespace had no member processes after the unshare command terminated. The namespace is then destroyed by removing the bind mount.
# touch /root/uts-ns # unshare --uts=/root/uts-ns hostname FOO # nsenter --uts=/root/uts-ns hostname FOO # umount /root/uts-ns
The following commands establish a persistent mount namespace referenced by the bind mount /root/namespaces/mnt. In order to ensure that the creation of that bind mount succeeds, the parent directory (/root/namespaces) is made a bind mount whose propagation type is not shared.
# mount --bind /root/namespaces /root/namespaces # mount --make-private /root/namespaces # touch /root/namespaces/mnt # unshare --mount=/root/namespaces/mnt
The following commands demonstrate the use of the --kill-child option when creating a PID namespace, in order to ensure that when unshare is killed, all of the processes within the PID namespace are killed.
# set +m # Don't print job status messages # unshare --pid --fork --mount-proc --kill-child -- \
bash --norc -c ''(sleep 555 &) && (ps a &) && sleep 999'' & [1] 53456 # PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a # ps h -o 'comm' $! # Show that background job is unshare(1) unshare # kill $! # Kill unshare(1) # pidof sleep
The pidof(1) command prints no output, because the sleep processes have been killed. More precisely, when the sleep process that has PID 1 in the namespace (i.e., the namespace’s init process) was killed, this caused all other processes in the namespace to be killed. By contrast, a similar series of commands where the --kill-child option is not used shows that when unshare terminates, the processes in the PID namespace are not killed:
# unshare --pid --fork --mount-proc -- \
bash --norc -c ''(sleep 555 &) && (ps a &) && sleep 999'' & [1] 53479 # PID TTY STAT TIME COMMAND
1 pts/3 S+ 0:00 sleep 999
3 pts/3 S+ 0:00 sleep 555
5 pts/3 R+ 0:00 ps a # kill $! # pidof sleep 53482 53480
The following example demonstrates the creation of a time namespace where the boottime clock is set to a point several years in the past:
# uptime -p # Show uptime in initial time namespace up 21 hours, 30 minutes # unshare --time --fork --boottime 300000000 uptime -p up 9 years, 28 weeks, 1 day, 2 hours, 50 minutes
AUTHORS¶
Mikhail Gusarov <dottedmag@dottedmag.net>, Karel Zak <kzak@redhat.com>
SEE ALSO¶
newuidmap(1) newgidmap(1) clone(2), unshare(2), namespaces(7), mount(8)
REPORTING BUGS¶
For bug reports, use the issue tracker at <https://github.com/util-linux/util-linux/issues>.
AVAILABILITY¶
The unshare command is part of the util-linux package which can be downloaded from Linux Kernel Archive <https://www.kernel.org/pub/linux/utils/util-linux/>.
2022-05-11 | util-linux 2.38.1 |