Detaillierte Erklärung und Fall des Unshare-Befehls

Detaillierte Erläuterung des Befehls zum Freigeben

1. Name

unshare - run program with some namespaces unshared from parent(使用与父程序不共享的名称空间运行程序)

2. Zusammenfassung

unshare [options] program [arguments]

3. Beschreibung

Hebt die Freigabe der angegebenen Namespaces vom übergeordneten Prozess auf und führt dann das angegebene Programm aus. Die freizugebenden Namespaces werden über Optionen angezeigt. Nicht gemeinsam nutzbare Namespaces sind (hebt die Freigabe der angegebenen Namespaces vom übergeordneten Prozess auf und führt dann das angegebene Programm aus. Der Leerzeichen wird durch Optionen angezeigt. Namespaces, die nicht gemeinsam genutzt werden können, umfassen)

Für die Freigabe können insgesamt 6 nicht freigegebene Namespaces festgelegt werden:

mount namespace

UTS namespace

IPC namespace

network namespace

pid namespace

user namespace

4. Optionen

Es gibt insgesamt folgende Optionen:

(1)-i, --ipc

 unshare the IPC namespace.

(2)-m, --mount

 Unshare the mount namespace.

(3)-n, --net

 Unshare the network namespace.

(4) -p, --pid

Unshare the pid namespace.  See also the --fork and --mount-proc options.

(5)-u, --uts

 Unshare the UTS namespace.

(6) -U, --user

Unshare the user namespace.

(7)-f, --fork

Fork the specified program as a child process of unshare rather than running it directly.  This is useful when creating a new pid namespace.

(8)--mount-proc[=mountpoint]

Just  before running the program, mount the proc filesystem at mountpoint (default is /proc).  This is useful when creating a new pid namespace.  It also implies creating a new mount names‐pace since the /proc mount would otherwise mess up existing programs on the system.  The new proc filesystem is explicitly mounted as private (by MS_PRIVATE|MS_REC).

(9)-r, --map-root-user

Run the program only after the current effective user and group IDs have been mapped to the superuser UID and GID in the newly created user namespace.  This  makes  it  possible  to  conve‐niently  gain  capabilities  needed  to  manage various aspects of the newly created namespaces (such as configuring interfaces in the network namespace or mounting filesystems in the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support more sophisticated use cases, such as mapping multiple ranges  of  UIDs  and  GIDs.  This  option  implies --setgroups=deny.

(10) --propagation private|shared|slave|unchanged

Recursively  sets mount propagation flag in the new mount namespace. The default is to set the propagation to private, this feature is possible to disable by unchanged argument. The options        is silently ignored when mount namespace (--mount) is not requested.

(11)--setgroups allow|deny

Allow or deny setgroups(2) syscall in user namespaces.

setgroups(2) is only callable with CAP_SETGID and CAP_SETGID in a user namespace (since Linux 3.19) does not give you permission to call setgroups(2) until after GID map has been  set.  The GID map is writable by root when setgroups(2) is enabled and GID map becomes writable by unprivileged processes when setgroups(2) is permanently disabled.

(12) -V, --version

Display version information and exit.

(13)-h, --help

Display help text and exit.

5. Beispiele

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

1

Establish a PID namespace, ensure we're PID 1 in it against newly mounted procfs instance.

(建立一个PID命名空间,确保我们在新安装的procfs实例中是PID 1。)

 

$ unshare --map-root-user --user sh -c whoami

root

Establish a user namespace as an unprivileged user with a root user within it.

(将用户命名空间建立为非特权用户,其中包含根用户。)

6. Welche Rolle spielen verschiedene Namespaces?

(1) Mount-Namespace

Mount Namespace ist der erste vom Linux-Kernel implementierte Namespace, der seit Version 2.4.19 des Kernels hinzugefügt wurde. Es kann verwendet werden, um Einhängepunkte zu isolieren, die von verschiedenen Prozessen oder Prozessgruppen gesehen werden. Für Laien ist es möglich, verschiedene Mount-Verzeichnisse in verschiedenen Prozessen zu sehen. Durch die Verwendung des Mount-Namespace kann festgestellt werden, dass nur Ihre eigenen Mount-Informationen im Container angezeigt werden und der Mount-Vorgang im Container keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.

Lassen Sie uns ein Beispiel verwenden, um den Mount-Namespace zu demonstrieren. Wir verwenden ein Kommandozeilen-Tool zum Freigeben. unshare ist ein Tool im util-linux Toolkit. CentOS 7 hat dieses Tool standardmäßig integriert. Mit dem Befehl unshare können Sie verschiedene Arten von Namespaces erstellen und darauf zugreifen.

Zunächst verwenden wir die folgenden Befehle, um einen Bash-Prozess und einen neuen Mount-Namespace zu erstellen:

unshare --mount --fork /bin/bash

Nach dem Ausführen des obigen Befehls haben wir einen neuen Mount-Namespace auf dem Host erstellt, und der neu erstellte Mount-Namespace wurde dem aktuellen Befehlszeilenfenster hinzugefügt. Lassen Sie mich anhand eines Beispiels überprüfen, ob das Erstellen eines Mount-Verzeichnisses in einem unabhängigen Mount-Namespace keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.

Nach dem Ausführen des obigen Befehls haben wir einen neuen Mount-Namespace auf dem Host erstellt, und der neu erstellte Mount-Namespace wurde dem aktuellen Befehlszeilenfenster hinzugefügt. Lassen Sie mich anhand eines Beispiels überprüfen, ob das Erstellen eines Mount-Verzeichnisses in einem unabhängigen Mount-Namespace keine Auswirkungen auf das Mount-Verzeichnis des Hosts hat.

Erstellen Sie zunächst ein Verzeichnis unter dem Verzeichnis / tmp.

[root@centos7 centos]# mkdir /tmp/tmpfs

Verwenden Sie nach dem Erstellen des Verzeichnisses den Befehl mount, um ein Verzeichnis vom Typ tmpfs bereitzustellen. Der Befehl lautet wie folgt:

[root@centos7 centos]# mount -t tmpfs -o size=20m tmpfs /tmp/tmpfs

Verwenden Sie dann den Befehl df, um die bereitgestellten Verzeichnisinformationen anzuzeigen:

[root@centos7 centos]# df -h

Filesystem   Size Used Avail Use% Mounted on

/dev/vda1    500G 1.4G 499G  1% /

devtmpfs     16G   0  16G  0% /dev

tmpfs      16G   0  16G  0% /dev/shm

tmpfs      16G   0  16G  0% /sys/fs/cgroup

tmpfs      16G  57M  16G  1% /run

tmpfs      3.2G   0 3.2G  0% /run/user/1000

tmpfs      20M   0  20M  0% /tmp/tmpfs

Sie können sehen, dass das Verzeichnis / tmp / tmpfs korrekt bereitgestellt wurde. Um zu überprüfen, ob dieses Verzeichnis nicht auf dem Host bereitgestellt ist, öffnen wir ein neues Befehlszeilenfenster und führen den Befehl df aus, um die Bereitstellungsinformationen des Hosts anzuzeigen:

[centos@centos7 ~]$ df -h

Filesystem   Size Used Avail Use% Mounted on

devtmpfs     16G   0  16G  0% /dev

tmpfs      16G   0  16G  0% /dev/shm

tmpfs      16G  57M  16G  1% /run

tmpfs      16G   0  16G  0% /sys/fs/cgroup

/dev/vda1    500G 1.4G 499G  1% /

tmpfs      3.2G   0 3.2G  0% /run/user/1000

Aus der obigen Ausgabe können wir ersehen, dass / tmp / tmpfs nicht auf dem Host gemountet ist. Es ist ersichtlich, dass die Mount-Operation in unserem unabhängigen Mount-Namespace keinen Einfluss auf den Host hat.

Um unsere Ideen weiter zu überprüfen, überprüfen wir weiterhin die Namespace-Informationen des aktuellen Prozesses im aktuellen Befehlszeilenfenster. Der Befehl lautet wie folgt:

[root@centos7 centos]# ls -l /proc/self/ns/

total 0

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 ipc -> ipc:[4026531839]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 mnt -> mnt:[4026532239]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 net -> net:[4026531956]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 pid -> pid:[4026531836]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 user -> user:[4026531837]

lrwxrwxrwx. 1 root root 0 Sep 4 08:20 uts -> uts:[4026531838]

Öffnen Sie dann ein neues Befehlszeilenfenster und überprüfen Sie mit demselben Befehl die Namespace-Informationen auf dem Host:

[centos@centos7 ~]$ ls -l /proc/self/ns/

total 0

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 ipc -> ipc:[4026531839]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 mnt -> mnt:[4026531840]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 net -> net:[4026531956]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 pid -> pid:[4026531836]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 user -> user:[4026531837]

lrwxrwxrwx. 1 centos centos 0 Sep 4 08:20 uts -> uts:[4026531838]

Durch Vergleichen der Ausgabeergebnisse der beiden Befehle können wir feststellen, dass die ID-Werte anderer Namespaces mit Ausnahme der ID-Werte von Mount Namespace identisch sind.

Aus den obigen Ergebnissen können wir schließen, dass mit dem Befehl unshare ein neuer Mount-Namespace erstellt werden kann und der Mount im neu erstellten Mount-Namespace vollständig von außen isoliert ist.

(2) PID-Namespace

Die Funktion des PID-Namespace besteht darin, den Prozess zu isolieren. In verschiedenen PID-Namespaces können Prozesse dieselbe PID-Nummer haben. Mithilfe des PID-Namespace kann erkannt werden, dass der Hauptprozess jedes Containers Prozess Nr. 1 ist, während die Prozesse im Container unterschiedliche PIDs auf dem Host haben. Beispielsweise beträgt die PID eines Prozesses auf dem Host 122, und der PID-Namespace kann verwendet werden, um zu erkennen, dass der Prozess die PID 1 im Container sieht.

Im Folgenden wird anhand eines Beispiels die Rolle des PID-Namespace demonstriert. Zuerst verwenden wir den folgenden Befehl, um einen Bash-Prozess zu erstellen und einen neuen PID-Namespace zu erstellen:

unshare --fork --pid --mount-proc /bin/bash

Nach dem Ausführen des obigen Befehls haben wir einen neuen PID-Namespace auf dem Host erstellt und den neu erstellten PID-Namespace zum aktuellen Befehlszeilenfenster hinzugefügt. Verwenden Sie den Befehl ps aux im aktuellen Befehlszeilenfenster, um die Prozessinformationen anzuzeigen:

[root@centos7 centos]# ps aux

USER    PID %CPU %MEM  VSZ  RSS TTY   STAT START  TIME COMMAND

root     1 0.0 0.0 115544 2004 pts/0  S  10:57  0:00 bash

root    10 0.0 0.0 155444 1764 pts/0  R+  10:59  0:00 ps aux

Durch die Ausgabe des obigen Befehls können Sie sehen, dass bash der Prozess Nr. 1 unter dem aktuellen Namespace ist und wir keine anderen Prozessinformationen auf dem Host sehen können.

(3) UTS-Namespace

Der UTS-Namespace wird hauptsächlich zum Isolieren von Hostnamen verwendet und ermöglicht es jedem UTS-Namespace, einen unabhängigen Hostnamen zu haben. Unser Hostname ist beispielsweise Docker. Mit UTS Namespace können Sie den Hostnamen im Container als Ladoudocker oder einen anderen benutzerdefinierten Hostnamen realisieren.

In ähnlicher Weise verwenden wir ein Beispiel, um die Rolle des UTS-Namespace zu überprüfen. Zunächst verwenden wir den Befehl unshare, um einen UTS-Namespace zu erstellen:

unshare --fork --uts /bin/bash

Nachdem der UTS-Namespace erstellt wurde, befindet sich das aktuelle Befehlszeilenfenster bereits in einem unabhängigen UTS-Namespace. Als Nächstes verwenden wir den Befehl hostname (Hostname kann zum Anzeigen des Hostnamens verwendet werden), um den Hostnamen festzulegen:

 hostname -b lagoudocker

Überprüfen Sie dann den Hostnamen erneut:

[root@centos7 centos]# hostname

lagoudocker

Durch die Ausgabe des obigen Befehls können wir sehen, dass der Hostname im aktuellen UTS-Namespace in Lagudocker geändert wurde. Dann öffnen wir ein neues Befehlszeilenfenster und überprüfen mit demselben Befehl den Hostnamen des Hosts:

[centos@centos7 ~]$ hostname

centos7

Sie können sehen, dass der Name des Hosts immer noch centos7 lautet und nicht geändert wurde. Hieraus kann überprüft werden, ob der UTS-Namespace zum Isolieren von Hostnamen verwendet werden kann.

(4) IPC-Namespace

Der IPC-Namespace wird hauptsächlich zum Isolieren der Kommunikation zwischen Prozessen verwendet. Beispielsweise können PID-Namespace und IPC-Namespace zusammen verwendet werden, um zu erkennen, dass Prozesse innerhalb desselben IPC-Namespace miteinander kommunizieren können, Prozesse mit unterschiedlichen IPC-Namespaces jedoch nicht.

In ähnlicher Weise verwenden wir ein Beispiel, um die Rolle des IPC-Namespace zu überprüfen. Zunächst verwenden wir den Befehl unshare, um einen IPC-Namespace zu erstellen:

unshare --fork --ipc /bin/bash

Als Nächstes müssen zwei Befehle verwendet werden, um den IPC-Namespace zu überprüfen.

Befehl ipcs -q: Wird verwendet, um die Liste der Kommunikationswarteschlangen zwischen Systemen anzuzeigen.

Befehl ipcmk -Q: Wird zum Erstellen einer Kommunikationswarteschlange zwischen Systemen verwendet.

Wir verwenden zuerst den Befehl ipcs -q, um die Liste der Systemkommunikationswarteschlangen unter dem aktuellen IPC-Namespace anzuzeigen:

[centos@centos7 ~]$ ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

Aus dem obigen können wir erkennen, dass derzeit keine Systemkommunikationswarteschlange vorhanden ist, und dann verwenden wir den Befehl ipcmk -Q, um eine Systemkommunikationswarteschlange zu erstellen:

[root@centos7 centos]# ipcmk -Q

Message queue id: 0

Verwenden Sie den Befehl ipcs -q erneut, um die Liste der Systemkommunikationswarteschlangen unter dem aktuellen IPC-Namespace anzuzeigen

[root@centos7 centos]# ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

0x73682a32 0     root    644    0      0

Sie sehen, dass wir erfolgreich eine Systemkommunikationswarteschlange erstellt haben. Dann öffnen wir ein neues Befehlszeilenfenster und überprüfen mit dem Befehl ipcs -q die Systemkommunikationswarteschlange des Hosts:

[centos@centos7 ~]$ ipcs -q

------ Message Queues --------

key    msqid   owner   perms   used-bytes  messages

Durch das obige Experiment kann festgestellt werden, dass die in einem separaten IPC-Namespace erstellte Systemkommunikationswarteschlange auf dem Host nicht sichtbar ist. Das heißt, IPC Namespace realisiert die Isolation von Systemkommunikationswarteschlangen.

(5) Benutzernamensraum

Der Benutzername wird hauptsächlich zum Isolieren von Benutzern und Benutzergruppen verwendet. Ein typisches Anwendungsszenario besteht darin, dass ein Prozess, der als Nicht-Root-Benutzer auf dem Host ausgeführt wird, einem Root-Benutzer in einem separaten Benutzernamensraum zugeordnet werden kann. Durch die Verwendung des Benutzernamensraums kann festgestellt werden, dass der Prozess über Root-Berechtigungen im Container verfügt, es sich jedoch nur um einen normalen Benutzer auf dem Host handelt.

User Namesapce kann ohne Rootberechtigung erstellt werden. Im Folgenden erstellen wir einen Benutzernamenraum als normalen Benutzer. Der Befehl lautet wie folgt:

[centos@centos7 ~]$ unshare --user -r /bin/bash

[root@centos7 ~]#

CentOS7 erlaubt standardmäßig die Erstellung eines Benutzernamensraums auf 0. Wenn die Ausführung des obigen Befehls fehlschlägt (der vom Befehl unshare zurückgegebene Fehler lautet unshare: unshare failed: Ungültiges Argument), müssen Sie den folgenden Befehl verwenden, um die Anzahl zu ändern Benutzernamen, die vom System erstellt werden dürfen. Der Befehl lautet: echo 65535> / proc / sys / user / max_user_namespaces, und versuchen Sie dann erneut, Benutzernamen zu erstellen.

Führen Sie dann den Befehl id aus, um die aktuellen Benutzerinformationen zu überprüfen:

[root@centos7 ~]# id

uid=0(root) gid=0(root) groups=0(root),65534(nfsnobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Anhand der obigen Ausgabe können wir erkennen, dass wir bereits der Root-Benutzer im neuen Benutzernamensraum sind. Im Folgenden verwenden wir den Befehl reboot, der nur vom Root-Benutzer des Hosts ausgeführt werden kann, um ihn zu überprüfen, und führen den Befehl reboot im aktuellen Befehlszeilenfenster aus:

[root@centos7 ~]# reboot

Failed to open /dev/initctl: Permission denied

Failed to talk to init daemon.

Wie Sie sehen, sind wir zwar der Root-Benutzer im neu erstellten Benutzernamensraum, haben jedoch nicht die Berechtigung, den Befehl zum Neustart auszuführen. Dies zeigt, dass im isolierten Benutzernamensraum die Stammberechtigung des Hosts nicht abgerufen werden kann, was bedeutet, dass der Benutzernamensraum die Isolation von Benutzern und Benutzergruppen realisiert.

(6) Net Namespace

Der Net Namespace wird verwendet, um Informationen wie Netzwerkgeräte, IP-Adressen und Ports zu isolieren. Mit Net Namespace kann jeder Prozess seine eigenen unabhängigen IP-Adressen-, Port- und Netzwerkkarteninformationen haben. Beispielsweise lautet die Host-IP-Adresse 172.16.4.1, und eine unabhängige IP-Adresse kann im Container auf 192.168.1.1 festgelegt werden.

Verwenden Sie auch die Beispielüberprüfung. Zuerst verwenden wir den Befehl ip a, um die Netzwerkinformationen auf dem Host zu überprüfen:

$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

  inet 127.0.0.1/8 scope host lo

​    valid_lft forever preferred_lft forever

  inet6 ::1/128 scope host

​    valid_lft forever preferred_lft forever

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

  link/ether 02:11:b0:14:01:0c brd ff:ff:ff:ff:ff:ff

  inet 172.20.1.11/24 brd 172.20.1.255 scope global dynamic eth0

​    valid_lft 86063337sec preferred_lft 86063337sec

  inet6 fe80::11:b0ff:fe14:10c/64 scope link

​    valid_lft forever preferred_lft forever

3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default

  link/ether 02:42:82:8d:a0:df brd ff:ff:ff:ff:ff:ff

  inet 172.17.0.1/16 scope global docker0

​    valid_lft forever preferred_lft forever

  inet6 fe80::42:82ff:fe8d:a0df/64 scope link

​    valid_lft forever preferred_lft forever

Dann verwenden wir den folgenden Befehl, um einen Net Namespace zu erstellen:

 unshare --net --fork /bin/bash

In ähnlicher Weise verwenden wir den Befehl ip a, um die Netzwerkinformationen zu überprüfen:

[root@centos7 centos]# ip a

1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Wie Sie sehen können, befinden sich auf dem Host Netzwerkgeräte wie lo, eth0 und docker0, und die Netzwerkgeräte in unserem neu erstellten Net Namespace unterscheiden sich von denen auf dem Host.

Ich denke du magst

Origin blog.csdn.net/qq_34939308/article/details/114115443
Empfohlen
Rangfolge