Detaillierte Erklärung des Linux Namespace-Benutzers

Detaillierte Erklärung des Linux Namespace-Benutzers

Der Benutzer-Namespace ist ein neuer Namespace, der in Linux 3.8 hinzugefügt wurde und zum Isolieren sicherheitsrelevanter Ressourcen wie Benutzer-IDs und Gruppen-IDs, Schlüsseln und Funktionen verwendet wird. Die Benutzer-ID und die Gruppen-ID desselben Benutzers können in verschiedenen Benutzer-Namespaces unterschiedlich sein (ähnlich dem PID-Namespace). Mit anderen Worten: Ein Benutzer kann in einem Benutzernamensraum ein normaler Benutzer, in einem anderen Benutzernamensraum jedoch ein Superuser sein.

Benutzer-Namespaces können verschachtelt werden (derzeit steuert der Kernel bis zu 32 Schichten). Mit Ausnahme des systemweiten Standardbenutzer-Namespaces haben alle Benutzer-Namespaces einen übergeordneten Benutzer-Namespace und jeder Benutzer-Namespace kann null oder mehr untergeordnete Benutzer-Namespaces haben. Wenn in einem Prozess „unshare“ oder „clone“ aufgerufen wird, um einen neuen Benutzernamensraum zu erstellen, ist der ursprüngliche Benutzernamensraum des aktuellen Prozesses der übergeordnete Benutzernamensraum und der neue Benutzernamensraum der untergeordnete Benutzernamensraum.

Hinweis: Die Demonstrationsumgebung dieses Artikels ist Ubuntu 16.04.

Erstellen eines Benutzernamensraums

Wir können einen neuen Benutzernamensraum erstellen, indem wir die Option --user des Befehls „unshare“ verwenden:

$ unshare -user -r /bin/bash 

Über den Parameter -r ordnen wir den Root-Benutzer im neuen Benutzernamensraum dem externen Spitznamenbenutzer zu (die mit der Zuordnung verbundenen Konzepte werden als Nächstes vorgestellt). Im neuen Benutzer-Namespace hat der Root-Benutzer die Berechtigung, andere Namespaces zu erstellen, beispielsweise den UTS-Namespace. Dies liegt daran, dass der aktuelle Bash-Prozess über alle Funktionen verfügt:

Lassen Sie uns einen neuen UTS-Namespace erstellen und ihn ausprobieren:

$ unshare --uts /bin/bash 

Wir können sehen, dass der neue UTS-Namespace erfolgreich erstellt wurde. Dies liegt daran, dass mit Ausnahme von Benutzernamensräumen zum Erstellen anderer Namespacetypen die CAP_SYS_ADMIN-Funktion erforderlich ist. Nachdem der neue Benutzer-Namespace erstellt und die UID und GID zugeordnet wurden, verfügt der erste Prozess dieses Benutzer-Namespaces über alle vollständigen Funktionen, d. h. er kann neue Namespaces anderer Typen erstellen.

Tatsächlich ist es nicht notwendig, den obigen Vorgang (Erstellen von zwei Namespaces) in zwei Schritte aufzuteilen. Wir können mehrere Namespaces gleichzeitig erstellen, indem wir die Freigabe aufheben:

Bei der Implementierung von unshare wird tatsächlich CLONE_NEWUSER | CLONE_NEWUTS übergeben, und zwar ungefähr wie folgt:

Freigabe aufheben(CLONE_NEWUSER | CLONE_NEWUTS);

Im obigen Fall stellt der Kernel sicher, dass zuerst CLONE_NEWUSER ausgeführt wird, und führt dann das verbleibende CLONE_NEW* aus, wodurch es möglich wird, einen neuen Container zu erstellen, ohne den Root-Benutzer zu verwenden. Diese Regel gilt auch für die Klonfunktion.

Grundlegendes zur UID- und GID-Zuordnung

In der vorherigen Demonstration haben wir die Zuordnung von Benutzern zwischen Benutzernamensräumen erwähnt. Lassen Sie uns nun dieselbe Demonstration verwenden, um zu verstehen, was die Zuordnung ist. Lassen Sie uns zunächst die ID und den Benutzernamensraum des aktuellen Benutzers überprüfen:

Führen Sie dann den Befehl unshare --user /bin/bash aus, um einen neuen Benutzernamensraum zu erstellen. Beachten Sie, dass diesmal kein Parameter -r vorhanden ist:

$ unshare --user /bin/bash 

Im neuen Benutzernamensraum wird der aktuelle Benutzer zu „nobody“ und die ID lautet 65534.

Dies liegt daran, dass wir die Benutzer-ID und die Gruppen-ID des übergeordneten Benutzernamensraums noch nicht dem untergeordneten Benutzernamensraum zugeordnet haben. Dieser Schritt ist erforderlich, damit das System die Berechtigungen von Benutzern in einem Benutzernamensraum in anderen Benutzernamensräumen steuern kann (z. B. das Senden von Signalen an Prozesse in anderen Benutzernamensräumen oder den Zugriff auf in anderen Benutzernamensräumen gemountete Dateien).

Wenn keine Zuordnung vorhanden ist und getuid() und getgid() verwendet werden, um die Benutzer-ID und die Gruppen-ID im neuen Benutzernamensraum abzurufen, gibt das System die in der Datei /proc/sys/kernel/overflowuid definierte Benutzer-ID und die in proc/sys/kernel/overflowgid definierte Gruppen-ID zurück, die beide einen Standardwert von 65534 haben. Das heißt, wenn keine Zuordnung angegeben ist, wird die ID standardmäßig der 65534 zugeordnet.

Als nächstes schließen wir die Zuordnung des Nick-Benutzers im neuen Benutzernamensraum ab.

Die Methode zum Zuordnen von IDs besteht darin, den Dateien /proc/PID/uid_map und /proc/PID/gid_map Zuordnungsinformationen hinzuzufügen (wobei PID die Prozess-ID im neuen Benutzernamensraum ist und beide Dateien am Anfang leer sind). Das Format der Konfigurationsinformationen in diesen beiden Dateien ist wie folgt (jede Datei kann mehrere Konfigurationsinformationen enthalten):

ID-innen-ns ID-außen-ns Länge

Beispielsweise bedeutet die Konfiguration 0 1000 500, dass 1000~1500 im übergeordneten Benutzernamensraum 0~500 im neuen Benutzernamensraum zugeordnet wird.

Für den Schreibvorgang von uid_map- und gid_map-Dateien gilt eine strenge Berechtigungskontrolle. Einfach ausgedrückt: Der Eigentümer dieser beiden Dateien ist der Benutzer, der den neuen Benutzernamensraum erstellt. Daher kann das Root-Konto im selben Benutzernamensraum wie dieser Benutzer in diese Dateien schreiben. Ob dieser Benutzer die Berechtigung zum Schreiben in die Map-Datei hat, hängt davon ab, ob er über die Fähigkeiten CAP_SETUID und CAP_SETGID verfügt. Hinweis: Sie können Daten nur einmal in eine Map-Datei schreiben, Sie können jedoch mehrere Einträge gleichzeitig schreiben und die maximale Anzahl der Einträge beträgt 5.

Wir rufen das soeben geöffnete Shell-Fenster auf, das erste Shell-Fenster, und beginnen mit der Ausführung der Benutzerzuordnungsoperation (ordnen den Benutzer nick dem Namen root im neuen Benutzernamensraum zu).

Der erste Schritt besteht darin, die ID des aktuellen Prozesses im ersten Shell-Fenster zu überprüfen:

Der zweite Schritt besteht darin, ein neues Shell-Fenster zu öffnen, das ich das zweite Shell-Fenster nenne. Zeigen Sie die Zuordnungsdateieigenschaften des Prozesses 3049 an:

Der Benutzer Nick ist der Besitzer dieser beiden Dateien. Versuchen wir, Zuordnungsinformationen in diese beiden Dateien zu schreiben:

Es scheint seltsam, dass ich der Eigentümer der Datei bin, aber keine Berechtigung habe, in die Datei zu schreiben! Tatsächlich liegt der grundlegende Grund darin, dass der aktuelle Bash-Prozess nicht über die Berechtigungen CAP_SETUID und CAP_SETGID verfügt:

Als nächstes legen wir die relevanten Fähigkeiten für das /bin/bash-Programm fest:

Kopieren Sie den Code wie folgt:
$ sudo setcap cap_setgid,cap_setuid+ep /bin/bash

$ sudo setcap cap_setgid,cap_setuid+ep /bin/bash

Laden Sie dann Bash neu und Sie sehen die entsprechenden Funktionen:

Schreiben Sie nun die Zuordnungsinformationen in die Zuordnungsdatei neu:

$ echo '0 1000 500' > /proc/3049/uid_map
$ echo '0 1000 500' > /proc/3049/gid_map

Dieses Mal war der Schreibvorgang erfolgreich. Da wir die Zuordnungsinformationen später nicht manuell eingeben müssen, können wir die Funktion von /bin/bash mit dem folgenden Befehl auf die ursprüngliche Einstellung zurücksetzen:

$ sudo setcap cap_setgid,cap_setuid-ep /bin/bash 

Schritt 3: Zurück zum ersten Shell-Fenster

Laden Sie Bash neu und führen Sie den ID-Befehl aus:

Der aktuelle Benutzer ist zu Root geworden (dem Root-Benutzer im neuen Benutzernamensraum). Werfen wir einen Blick auf die Fähigkeiten des aktuellen Bash-Prozesses:

0000003ffffffffff bedeutet, dass die aktuell laufende Bash über alle Funktionen verfügt.

Schritt 4. Im ersten Shell-Fenster

Überprüfen Sie die Zugriffsberechtigungen des /root-Verzeichnisses:

Keine Erlaubnis! Versuchen Sie, den Hostnamen zu ändern:

Immer noch keine Erlaubnis! Es scheint, dass der Root-Benutzer in diesem neuen Benutzernamensraum nicht im übergeordneten Benutzernamensraum funktioniert. Dies ist genau der Effekt, den Benutzer-Namespaces erzielen sollen. Beim Zugriff auf Ressourcen in anderen Benutzer-Namespaces werden die Berechtigungen verwendet, um den Zugriff auszuführen. Beispielsweise ist der Benutzer, der dem übergeordneten Benutzer-Namespace für root entspricht, nick, sodass der Hostname des Systems nicht geändert werden kann.

Der normale Benutzer Nick hat keine Berechtigung, den Hostnamen zu ändern. Kann der Hostname dann geändert werden, nachdem der Root-Benutzer im Standardbenutzer-Namespace dem Root-Benutzer im Unterbenutzer-Namespace zugeordnet wurde? Die Antwort ist nein! Dies liegt daran, dass, unabhängig davon, wie die Zuordnung durchgeführt wird, wenn ein Benutzer in einem untergeordneten Benutzernamensraum auf Ressourcen in einem übergeordneten Benutzernamensraum zugreift, die Berechtigung des von ihm gestarteten Prozesses leer ist. Daher ist der Root-Benutzer im untergeordneten Benutzernamensraum einem normalen Benutzer im übergeordneten Benutzernamensraum gleichwertig.

Beziehung zwischen Benutzer-Namespace und anderen Namespaces

Jeder Namespace unter Linux ist mit einem Benutzernamensraum verknüpft. Dieser Benutzernamensraum ist der Benutzernamensraum, zu dem der Prozess gehört, wenn der entsprechende Namespace erstellt wird. Dies ist gleichbedeutend damit, dass jeder Namespace einen Besitzer (Benutzernamensraum) hat. Dadurch wird sichergestellt, dass Vorgänge in jedem Namespace durch die Berechtigungen des Benutzernamensraums gesteuert werden. Aus diesem Grund schlägt auch das Festlegen des Hostnamens im untergeordneten Benutzer-Namespace fehl, da der zu ändernde UTS-Namespace zum übergeordneten Benutzer-Namespace gehört und die Prozesse im neuen Benutzer-Namespace über keine Funktionen des alten Benutzer-Namespace verfügen.

Am Beispiel des UTS-Namespaces befindet sich in der Struktur uts_namespace ein Zeiger auf den Benutzernamensraum, der auf den Benutzernamensraum verweist, zu dem er gehört (im Kernel v4.13, den ich überprüft habe, befindet sich die Definition der Struktur uts_namespace in der Datei /include/linux/utsname.h):

Die Definitionen anderer Namespaces sind ähnlich.

Zusammenfassen

Im Vergleich zu anderen Namespaces ist der Benutzer-Namespace etwas komplizierter. Dies liegt an der Funktionalität und der tendenziell weniger intuitiven Verwaltung von Berechtigungen. In diesem Artikel habe ich nur das Grundkonzept des Benutzernamensraums vorgestellt. Es gibt noch weitere interessante Inhalte, die darauf warten, von Ihnen entdeckt zu werden.

siehe:

Manpage für den Benutzer-Namespace
Namespaces im Einsatz, Teil 5: Benutzer-Namespaces
Namespaces im Einsatz, Teil 6: Mehr zu User-Namespaces
Linux-Funktionen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Docker-Grundlagen: Grafische Erläuterung des Linux-Namespace

<<:  Vue implementiert das Bild mit Schaltflächenwechsel

>>:  Lösung für den MySQL-Fehler „Tabelle kann nicht gelesen werden“ (MySQL-Fehler 1018)

Artikel empfehlen

Keine chinesische Spezialität: Webentwicklung unter kulturellen Unterschieden

Webdesign und -entwicklung sind harte Arbeit, als...

Umfassendes Verständnis der HTML-Grundstruktur

Einführung in HTML HyperText-Auszeichnungssprache...

Detaillierte Erläuterung des Vuex-Gesamtfalls

Inhaltsverzeichnis 1. Einleitung 2. Vorteile 3. N...

Detaillierte Erklärung zum Aktivieren des https-Dienstes in Apache unter Linux

Dieser Artikel beschreibt, wie man den https-Dien...

Docker Link realisiert die Containerverbindung

Inhaltsverzeichnis 1.1. Netzwerkzugriff zwischen ...

Detailliertes Tutorial zur Installation von MySQL 8 in CentOS 7

Vorbereiten Umweltinformationen zu diesem Artikel...

So beheben Sie den MySQL-FEHLER 1045 (28000) - Zugriff wegen Benutzer verweigert

Problembeschreibung (die folgende Diskussion besc...

Eine kurze Diskussion über Yahoos 35 Regeln zur Front-End-Optimierung

Zusammenfassung: Ob bei der Arbeit oder im Vorste...

So legen Sie eine feste IP-Adresse in einer virtuellen CentOS7-Maschine fest

Da meine Entwicklungsumgebung darin besteht, Cent...

Analyse und Lösung zur Leistungsoptimierung von Vue.js-Anwendungen

Inhaltsverzeichnis 1. Einleitung 2. Warum brauche...