Scroll to navigation

UNSHARE(1) Dienstprogramme für Benutzer UNSHARE(1)

BEZEICHNUNG

unshare - Programm in neuen Namensräumen ausführen

ÜBERSICHT

unshare [options] [program [arguments]]

BESCHREIBUNG

Der Befehl unshare erzeugt neue Namensräume (wie in den nachfolgend beschriebenen Befehlszeilenoptionen angegeben) und führt dann das angegebene Programm aus. Falls kein Programm angegeben ist, dann wird »${SHELL}« ausgeführt (Vorgabe: /bin/sh).

In der Voreinstellung ist ein neuer Namensraum nur so lange beständig, wie er Mitgliedprozesse hat. Ein neuer Namensraum kann beständig gemacht werden, selbst wenn es keine Mitgliedprozesse gibt, indem /proc/PID/ns/Typ-Dateien mit »bind« in einen Dateisystempfad eingebunden werden. Ein Namensraum, der auf diese Weise beständig gemacht wurde, kann anschließend mit nsenter(1) betreten werden, sogar, wenn das Programm beendet wird (außer PID-Namensräume, bei denen ein dauerhaft laufender Init-Prozess benötigt wird). Sobald ein beständiger Namensraum nicht länger benötigt wird, kann die Beständigkeit mit umount(8) aufgehoben werden, um die Bind-Einhängung aufzuheben. Weitere Einzelheiten finden Sie im Abschnitt BEISPIELE.

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.

Die folgenden Namensraumtypen können mit unshare erzeugt werden:

Einhänge-Namensraum

Ein- und Aushängen von Dateisystemen betrifft den Rest des Systems nicht, außer für Dateisysteme, die explizit als Mehrfacheinhängungen markiert sind (mit mount --make-shared; siehe /proc/self/mountinfo oder findmnt -o+PROPAGATION für die shared-Schalter). Für weitere Details siehe mount_namespaces(7).

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-Namensraum

Setzen des Rechner- oder Domain-Namens wird den Rest des Systems nicht betreffen. Für weitere Details siehe uts_namespaces(7).

IPC-Namensraum

Der Prozess erhält einen unabhängigen Namensraum für POSIX-Meldungswarteschlangen sowie System-V-Meldungswarteschlangen, Semaphor-Gruppen und gemeinsam genutzte Speichersegmente. Für weitere Details siehe ipc_namespaces(7).

Netzwerk-Namensraum

Der Prozess erhält unabhängige IPv4- und IPv6-Stapel, IP-Routing-Tabellen, Firewall-Regeln, die Verzeichnisbäume /proc/net und /sys/class/net, Sockets usw. Für weitere Details siehe network_namespaces(7).

PID-Namensraum

Kindprozesse werden eine eigene Gruppe von Abbildungen der PIDs zu Prozessen haben. Für weitere Details siehe pid_namespaces(7).

Cgroup-Namensraum

Der Prozess wird über einen virtualisierten Blick auf /proc/self/cgroup verfügen und neue Cgroup-Einhängungen werden ihre Wurzel in der Wurzel der Cgroup-Namensraum-Wurzel haben. Für weitere Details siehe cgroup_namespaces(7).

Benutzer-Namensraum

Der Prozess wird über eine eindeutige Gruppe an UIDs, GIDS und Capabilities verfügen. Für weitere Details siehe user_namespaces(7).

Zeit-Namensraum

Der Prozess kann eine abweichende Sicht auf CLOCK_MONOTONIC und/oder CLOCK_BOOTTIME haben, was mittels /proc/self/timens_offsets geändert werden kann. Für weitere Details, siehe time_namespaces(7).

OPTIONEN

-i, --ipc[=Datei]

Erzeugen eines neuen IPC-Namensraums. Falls eine Datei angegeben ist, wird der Namensraum beständig gemacht, indem eine »bind«-Einhängung auf der Datei erstellt wird.

-m, --mount[=Datei]

erstellt einen neuen Einhänge-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht. Beachten Sie, dass die Datei auf einem Dateisystem liegen muss, dessen Ausbreitungstyp nicht auf shared gesetzt ist (anderenfalls würde ein Fehler auftreten). Verwenden Sie den Befehl findmnt -o+PROPAGATION, wenn Sie sich bezüglich der derzeitigen Einstellung nicht sicher sind. Lesen Sie auch die nachfolgenden Beispiele.

-n, --net[=Datei]

erstellt einen neuen Netz-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht.

-p, --pid[=Datei]

erstellt einen neuen PID-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht. (Die Erstellung eines beständigen PID-Namensraums wird fehlschlagen, wenn nicht auch die Option --fork angegeben ist.)

Siehe auch die Optionen --fork und --mount-proc.

-u, --uts[=Datei]

erstellt einen neuen UTS-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht.

-U, --user[=Datei]

erstellt einen neuen Benutzer-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht.

-C, --cgroup[=Datei]

erstellt einen neuen Cgroup-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht.

-T, --time[=Datei]

erstellt einen neuen Zeit-Namensraum. Falls eine Datei angegeben ist, wird der Namensraum durch Erzeugen einer »bind«-Einhängung in Datei beständig gemacht. Mit den Optionen --monotonic und --boottime können Sie den korrespondierenden Versatz im Zeit-Namensraum angeben.

-f, --fork

Forkt das angegebene Programm als Kindprozess von unshare, anstatt es direkt auszuführen. Dies ist nützlich, wenn Sie einen neuen PID-Namensraum erstellen. Beachten Sie: Wenn unshare auf einen Kindprozess wartet, dann ignoriert es SIGINT und SIGTERM und leitet keine Signale an den Kindprozess weiter. Es ist daher nötig, Signale an den Kindprozess zu senden.

--keep-caps

stellt bei übergebener Option --user sicher, dass die im Benutzernamensraum gewährten Capabilities im Kindprozess erhalten bleiben.

--kill-child[=Signalname]

Wenn sich unshare beendet, soll der angegebene Signalname an den mit Fork erstellten Kindprozess gesendet werden. Kombiniert mit --pid erlaubt dies ein leichtes und zuverlässiges Töten eines gesamten Prozessbaums unterhalb von unshare. Falls nicht angegeben, ist der Signalname standardmäßig SIGKILL. Diese Option impliziert --fork.

--mount-proc[=Einhängepunkt]

Direkt vor Ausführung des Programms wird das proc-Dateisystem unter Einhängepunkt (Vorgabe ist /proc) eingehängt. Das ist bei der Erstellung eines neuen PID-Namensraums nützlich. Dies impliziert auch die Erstellung eines neuen Einhängenamensraums, da die /proc-Einhängung ansonsten bestehende Programme auf dem System durcheinanderbringen würde. Das neue proc-Dateisystem wird explizit als privat eingehängt (mit MS_PRIVATE|MS_REC).

--map-user=UID|Name

führt das Programm erst aus, nachdem die aktuelle effektive Benutzerkennung auf UID gesetzt wurde. Falls diese Option mehrfach angegeben wird, hat die zuletzt angegebene Option Vorrang. Diese Option impliziert --user.

--map-users=innere_UID:äußere_UID:Anzahl|auto|all

führt das Programm nur aus, nachdem der Block der Benutzer-IDs der Größe Anzahl beginnend bei der äußeren_UID auf den Block der Benutzer-IDs beginnend bei der inneren_UID abgebildet wurde. Diese Abbildung geschieht mittels newuidmap(1), falls unshare ohne Administratorrechte ausgeführt wurde. Falls die Bereiche der Benutzer-IDs mit der durch --map-user angegebenen Abbildung überlappen, wird ein »Loch« aus der Abbildung entfernt. Dadurch kann es passieren, dass die höchste Benutzer-ID der Abbildung nicht abgebildet wird. Wenn Sie --map-users mehrfach angeben, können Sie so mehr als einen Block an Benutzer-IDs zuweisen. Der spezielle Wert auto bildet den ersten Block der Benutzer-IDs, der dem effektiven Benutzer aus /etc/subuid gehört, auf einen Block ab, der bei der Benutzer-ID 0 beginnt. Der spezielle Wert all erzeugt eine Durchreichung der Zuweisung für jede Benutzer-ID. Diese Option impliziert --user.

Vor der Version 2.39 von util-linux erwartete diese Option ein durch Kommata getrenntes Argument der Form äußere_UID,innere_UID,Anzahl, aber dieses Format ist als veraltet anzusehen, um die Kompatibilität mit der in /proc/[PID]/uid_map und in der Einhängeoption X-mount.idmap verwendeten Anordnung zu gewährleisten.

--map-group=GID|Name

führt das Programm erst aus, nachdem die aktuelle effektive Gruppenkennung auf GID gesetzt wurde. Falls diese Option mehrfach angegeben wird, hat die zuletzt angegebene Option Vorrang. Diese Option impliziert --setgroups=deny und --user.

--map-groups=innere_GID:äußere_GID:Anzahl|auto|all

Run the program only after the block of group IDs of size count beginning at outergid has been mapped to the block of group IDs beginning at innergid. This mapping is created with newgidmap(1) if unshare was run unprivileged. If the range of group IDs overlaps with the mapping specified by --map-group, then a "hole" will be removed from the mapping. This may result in the highest group ID of the mapping not being mapped. Use --map-groups multiple times to map more than one block of group IDs. The special value auto will map the first block of user IDs owned by the effective user from /etc/subgid to a block starting at group ID 0. The special value all will create a pass-through map for every group ID available in the parent namespace. This option implies --user.

Vor der Version 2.39 von util-linux erwartete diese Option ein durch Kommata getrenntes Argument der Form äußere_GID,innere_GID,Anzahl, aber dieses Format ist als veraltet anzusehen, um die Kompatibilität mit der in /proc/[PID]/gid_map und in der Einhängeoption X-mount.idmap verwendeten Anordnung zu gewährleisten.

--map-auto

bildet den ersten Block der Benutzerkennungen, die dem effektiven Benutzer aus /etc/subuid gehören, auf einen Block beginnend mit der Benutzerkennung 0 ab. Auf die gleiche Weise wird auch der erste Block der Gruppenkennungen, die der effektiven Gruppe aus /etc/subgid gehören, auf einen Block beginnend mit der Gruppenkennung 0 abgebildet. Diese Option ist für den häufig vorkommenden Fall gedacht, in dem der erste Block untergeordneter Benutzer- und Gruppenkennungen den gesamten Benutzer- und Gruppenkennungsraum abbilden kann. Diese Option ist gleichbedeutend mit der gleichzeitigen Angabe von --map-users=auto und --map-groups=auto.

-r, --map-root-user

Führt das Programm erst aus, wenn die effektive Benutzer- und Gruppenkennungen auf die UID und GID des Systemverwalters in dem neu erstellten Namensraum abgebildet wurde. Dies ermöglicht es, bequem die benötigten Capabilities zu erlangen, um verschiedene Aspekte in dem neu erstellten Namensraum zu verwalten (wie die Konfiguration von Schnittstellen im Netzwerk-Namensraum oder das Einhängen von Dateisystemen in dem Einhängenamensraum), selbst bei unprivilegierter Ausführung. Als reine Bequemlichkeitsfunktionalität unterstützt es keine fortgeschritteneren Anwendungsfälle, wie das Abbilden von mehreren Bereichen von UIDs und GIDs. Diese Option impliziert --setgroups=deny und --user. Diese Option ist äquivalent zu --map-user=0 --map-group=0.

-c, --map-current-user

führt das Programm erst aus, nachdem die aktuellen effektiven Benutzer- und Gruppenkennungen im neu erzeugten Benutzernamensraum auf die gleichen Benutzer- und Gruppenkennungen gesetzt wurden. Diese Option impliziert --setgroups=deny und --user. Diese Option ist äquivalent zu --map-user=$(id -ru) --map-group=$(id -rg).

--propagation private|shared|slave|unchanged

Setzt den Einhängeausbreitungsschalter in dem neuen Einhängenamensraum rekursiv. Die Vorgabe ist, die Ausbreitung auf private zu setzen. Es ist möglich, diese Funktionalität mit dem Argument unchanged zu deaktivieren. Diese Option wird ohne Rückmeldung ignoriert, wenn der Einhängenamensraum (--mount) nicht angefordert wird.

--setgroups allow|deny

Erlaubt oder verweigert den Systemaufruf setgroups(2) in Benutzer-Namensräumen.

Um setgroups(2) aufrufen zu können, muss der aufrufende Prozess mindestens über CAP_SETGID verfügen. Seit Linux 3.19 gilt eine weitere Einschränkung: Der Kernel erteilt die Berechtigung, setgroups(2) aufzurufen, nur nachdem die GID-Abbildung (/proc/pid*/gid_map*) eingerichtet wurde. Die GID-Abbildung ist durch Root beschreibbar, wenn setgroups(2) aktiviert ist (d.h. allow, die Vorgabe) und die GID-Abbildung wird durch unprivilegierte Prozesse beschreibbar, wenn setgroups(2) permanent deaktiviert ist (mit deny).

-R, --root=Verzeichnis

führt den Befehl aus, wobei das Wurzelverzeichnis auf das angegebene Verzeichnis gesetzt wird.

-w, --wd=Verzeichnis

ändert das Arbeitsverzeichnis auf das angegebene Verzeichnis.

-S, --setuid UID

legt die Benutzerkennung fest, die in dem betretenen Namensraum verwendet wird.

-G, --setgid GID

legt die Gruppenkennung fest, die en dem betretenen Namensraum verwendet wird und entfernt zusätzliche Gruppen.

--monotonic Versatz

legt den Versatz von CLOCK_MONOTONIC fest, der im betretenen Zeit-Namensraum verwendet wird. Diese Option erfordert die Trennung eines Zeit-Namensraums mit --time.

--boottime Versatz

legt den Versatz von CLOCK_BOOTTIME fest, der im betretenen Zeit-Namensraum verwendet wird. Diese Option erfordert die Trennung eines Zeit-Namensraums mit --time.

-h, --help

zeigt einen Hilfetext an und beendet das Programm.

-V, --version

zeigt Versionsinformationen an und beendet das Programm.

ANMERKUNGEN

Die proc- und sysfs-Dateisystemeinhängungen als Root in einem Benutzernamensraum müssen eingeschränkt werden, so dass ein weniger privilegierter Benutzer nicht mehr Zugriffe auf sensible Dateien haben kann, als ein höher privilegierter Benutzer unverfügbar gemacht hat. Kurz gesagt, die Regeln für proc und sysfs sind so ähnlich zu einer Bind-Einhängung wie möglich.

BEISPIELE

Der folgende Befehl erzeugt einen PID-Namensraum, wobei --fork verwendet wird, um sicherzustellen, dass der aufgerufene Befehl in einem Kind-Namensraum ausgeführt wird (welcher der erste Prozess im Namensraum ist), der die PID 1 hat. Die Option --mount-proc sorgt dafür, dass gleichzeitig auch ein neuer Einhängenamensraum erzeugt und ein neues proc(5)-Dateisystem eingehängt wird, das Informationen zum neuen PID-Namensraum enthält. Wenn der Befehl readlink(1) beendet wird, werden die neuen Namensräume automatisch zerstört.

# unshare --fork --pid --mount-proc readlink /proc/self
1

Mit den Rechten eines unprivilegierten Benutzers einen neuen Benutzernamensraum erstellen, in welchem die Anmeldedaten des Benutzers auf die Root-Kennungen innerhalb des Namensraums abgebildet werden:

$ 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

Als unprivilegierter Benutzer einen Benutzer-Namensraum erstellen, in dem die ersten 65536 IDs alle abgebildet sind und die Anmeldedaten der Benutzer auf die Root-IDs innerhalb dieses Namensraums abgebildet sind. Die Abbildung wird durch die in subuid(5) und subgid(5) zugewiesenen Subordinaten-IDs bestimmt. Diese Abbildung durch Erstellung einer Datei mit der Benutzer-ID 1 und der Gruppen-ID 1 demonstrieren. Der Kürze halber werden nur die Abbildungen der Benutzer-IDs angezeigt:

$ 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

Der erste der folgenden Befehle erzeugt einen neuen dauerhaften UTS-Namenraum und ändert den Rechnernamen so, wie er im Namensraum gesehen wird. Der Namensraum wird dann mit nsenter(1) betreten, um den geänderten Rechnernamen anzuzeigen; dieser Schritt demonstriert, dass der UTS-Namensraum weiter existiert, obwohl der Namensraum nach dem Beenden des unshare-Prozesses keine eigenen Mitgliedprozesse mehr hat. Der Namensraum wird dann durch Entfernen der Bind-Einhängung zerstört.

# touch /root/uts-ns
# unshare --uts=/root/uts-ns hostname FOO
# nsenter --uts=/root/uts-ns hostname
FOO
# umount /root/uts-ns

Die folgenden Befehle etablieren einen dauerhaften Einhängenamensraum, der von der »bind«-Einhängung /root/namespaces/mnt angegeben wird. Um sicherzustellen, dass die Erzeugung dieser Bind-Einhängung erfolgreich ist, wird das Elternverzeichnis (/root/namespaces) zu einer Bind-Einhängung, deren Ausbreitungstyp nicht shared ist.

# mount --bind /root/namespaces /root/namespaces
# mount --make-private /root/namespaces
# touch /root/namespaces/mnt
# unshare --mount=/root/namespaces/mnt

Die folgenden Befehle demonstrieren die Verwendung der Option --kill-child beim Erzeugen eines PID-Namensraums, um sicherzustellen, dass beim Töten von unshare alle Prozesse innerhalb des PID-Namensraums getötet werden.

# set +m                # Keine Meldungen zum Auftragsstatus ausgeben
# 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' $! # Zeigen, dass der Hintergrund-Job unshare(1) ist unshare # kill $! # unshare(1) töten # pidof sleep

Der Befehl pidof(1) gibt nichts aus, da die sleep-Prozesse getötet wurden. Genauer gesagt: Wenn der sleep-Prozess, der in dem Namensraum die Prozesskennung 1 hat (also der Init-Prozess dieses Namensraums) getötet wurde, dann werden daraufhin alle anderen Prozesse in diesem Namensraum getötet. Im Gegensatz dazu zeigt eine ähnliche Reihe von Befehlen, bei denen die Option --kill-child nicht verwendet wird, dass die Prozesse in diesem PID-Namensraum beim Beenden von unshare nicht getötet werden:

# 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

Der folgende Befehl demonstriert die Erzeugung eines Zeit-Namensraums, in dem die Bootzeit-Uhr auf einen Zeitpunkt gesetzt ist, der einige Jahre in der Vergangenheit liegt:

# uptime -p             # Betriebszeit im ursprünglichen Zeit-Namensraum anzeigen
up 21 hours, 30 minutes
# unshare --time --fork --boottime 300000000 uptime -p
up 9 years, 28 weeks, 1 day, 2 hours, 50 minutes

AUTOREN

Mikhail Gusarov <dottedmag@dottedmag.net>, Karel Zak <kzak@redhat.com>

SIEHE AUCH

newuidmap(1), newgidmap(1), clone(2), unshare(2), namespaces(7), mount(8)

FEHLER MELDEN

Nutzen Sie zum Melden von Fehlern das Fehlererfassungssystem auf <https://github.com/util-linux/util-linux/issues>.

VERFÜGBARKEIT

Der Befehl unshare ist Teil des Pakets util-linux, welches aus dem Linux-Kernel-Archiv <https://www.kernel.org/pub/linux/utils/util-linux/> heruntergeladen werden kann.

2024-04-08 util-linux 2.40