GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum kann Podman mein Image nicht ziehen?

Eine der aufregendsten neuen Funktionen von Podman sind Container ohne Root. Rootless ermöglicht es, fast jeden Container als normalen Benutzer auszuführen, ohne erhöhte Rechte und mit großen Sicherheitsvorteilen. Das Ausführen von Containern ohne Root-Rechte ist jedoch mit Einschränkungen verbunden.

Ein Benutzer hat eine Frage zu einem dieser Probleme gestellt:Warum konnten sie ein bestimmtes Bild nicht mit wurzellosem Podman abrufen?

Ihr Bild hat nach dem Herunterladen Fehler ausgegeben, wie das folgende:

ERRO[0005] Error pulling image ref //testimg:latest: Error committing the finished image: error adding layer with blob "sha256:caed8f108bf6721dc2709407ecad964c83a31c8008a6a21826aa4ab995df5502": Error processing tar file(exit status 1): there might not be enough IDs available in the namespace (requested 4000000:4000000 for /testfile): lchown /testfile: invalid argument

Ich erklärte, dass ihr Problem darin bestand, dass ihr Bild Dateien hatte, die UIDs über 65536 gehörten. Aufgrund dieses Problems würde das Bild nicht in die Standard-UID-Zuordnung von rootless Podman passen, was die Anzahl der verfügbaren UIDs und GIDs begrenzt.

Die Folgefragen waren natürlich:

  • Warum gibt es diese Einschränkung?
  • Warum können Sie kein Bild verwenden, das auf normalem Podman im Rootless-Modus funktioniert?
  • Warum sind die genauen verwendeten UIDs und GIDs wichtig?

Ich beginne damit, zu erklären, warum wir andere UIDs und GIDs als der Host verwenden müssen, und erkläre dann, warum der Standardwert 65536 ist – und wie man diese Nummer ändert.

Mapping des Benutzernamensraums

Rootlose Container werden innerhalb eines Benutzernamensraums ausgeführt , was eine Möglichkeit ist, die Benutzer und Gruppen des Hosts dem Container zuzuordnen. Standardmäßig ordnen wir den Benutzer, der Podman gestartet hat, als UID/GID 0 in Rootless-Containern zu.

Auf meinem System kann mein Benutzer (mheon ) ist UID 1000. Wenn ich einen Rootless-Container als mheon starte mit podman run -t -i --rm fedora bash , und führen Sie dann top aus Im Container scheine ich UID 0 zu sein – root.

Auf dem Host jedoch die bash Der Prozess gehört immer noch meinem Benutzer. Sie können dieses Ergebnis sehen, wenn ich podman top ausführe auf meinem Hostsystem:

mheon@Agincourt code/podman.io (release_blog_1.5.0)$ podman top -l user group huser hgroup

USER GROUP HUSER HGROUP

root root 1000 1000

Der USER und GROUP Optionen sind der Benutzer und die Gruppe, wie sie im Container erscheinen , während der HUSER und HGROUP Optionen sind der Benutzer und die Gruppe, wie sie auf dem Host erscheinen .

Lassen Sie uns ein einfaches Beispiel zeigen. Ich mounte /etc/ , die voller Dateien ist, die root gehören, in einen rootlosen Container. Dann zeige ich seinen Inhalt mit ls :

mheon@Agincourt code/libpod (master)$ podman run -t -i -v /etc/:/testdir --rm fedora sh -c 'ls -l /testdir 2> /dev/null | head -n 10'

total 1700

-rw-r--r--. 1 nobody nobody 4664 May 3 14:39 DIR_COLORS

-rw-r--r--. 1 nobody nobody 5342 May 3 14:39 DIR_COLORS.256color

Ich habe keine Berechtigung, diese Dateien zu ändern, obwohl ich im Container root bin. Ich kann nicht einmal viele davon sehen:Beachten Sie den 2> /dev/null nach ls um Fehler zu quetschen, weil ich viele Berechtigungsfehler bekomme, selbst wenn ich versuche, sie aufzulisten.

Auf dem Host gehören diese Dateien root, UID 0 – aber im Container gehören sie nobody . Das ist ein spezieller Name, den der Linux-Kernel verwendet, um anzugeben, dass der Benutzer, dem die Dateien tatsächlich gehören, nicht im Benutzernamensraum vorhanden ist. UID und GID 0 auf dem Host werden nicht in den Container gemappt, also statt Dateien im Besitz von 0:0 , gehören sie nobody:nobody aus der Perspektive des Containers.

Unabhängig davon, welcher Benutzer Sie in einem Rootless-Container zu sein scheinen, handeln Sie immer noch als Ihr eigener Benutzer, und Sie können nur auf Dateien zugreifen, auf die Ihr Benutzer auf dem Host zugreifen kann. Dieses Setup macht einen großen Teil der Sicherheitsattraktivität von Rootless-Containern aus – selbst wenn ein Angreifer aus einem Container ausbrechen kann, ist er immer noch auf ein Nicht-Root-Benutzerkonto beschränkt.

Zusätzliche UIDs/GIDs zuweisen

Ich habe bereits gesagt, dass ein Benutzernamensraum Benutzer auf dem Host Benutzern im Container zuordnet, und habe ein wenig beschrieben, wie dieser Prozess für root im Container funktioniert. Aber Container haben im Allgemeinen andere Benutzer als nur root – was bedeutet, dass Podman zusätzliche UIDs zuordnen muss, damit Benutzer eins und höher im Container existieren können.

Mit anderen Worten, jeder Benutzer, der vom Container benötigt wird, muss zugeordnet werden. Dieses Problem verursachte den obigen ursprünglichen Fehler, weil das Image eine UID/GID verwendete, die nicht in seinem Benutzernamensraum definiert war.

Die newuidmap und newgidmap ausführbare Dateien, die normalerweise von den shadow-utils bereitgestellt werden oder uidmap Pakete, werden verwendet, um diese UIDs und GIDs dem Benutzernamensraum des Containers zuzuordnen. Diese Tools lesen die in /etc/subuid definierten Zuordnungen und /etc/subgid und verwenden Sie sie, um Benutzernamensräume im Container zu erstellen. Diese setuid Binärdateien verwenden zusätzliche Privilegien, um unseren Rootless-Containern Zugriff auf zusätzliche UIDs und GIDs zu geben – etwas, wofür wir normalerweise keine Berechtigung haben. Jeder Benutzer, der rootless Podman ausführt, muss einen Eintrag in diesen Dateien haben, wenn er Container mit mehr als einer UID ausführen muss. Jeder Container verwendet standardmäßig alle verfügbaren UIDs, obwohl die genauen Zuordnungen mit --uidmap angepasst werden können und --gidmap .

Ein normaler Nicht-Root-Benutzer unter Linux hat normalerweise nur Zugriff auf seinen eigenen Benutzer – eine UID. Wenn Sie die zusätzlichen UIDs und GIDs in einem Rootless-Container verwenden, können Sie als ein anderer Benutzer agieren, was normalerweise Root-Rechte erfordert (oder sich als dieser andere Benutzer mit seinem Passwort anmelden). Die ausführbaren Zuordnungsdateien newuidmap und newgidmap Verwenden Sie ihre erhöhten Berechtigungen, um uns Zugriff auf zusätzliche UIDs und GIDs gemäß den in /etc/subuid konfigurierten Zuordnungen zu gewähren und /etc/subgid ohne root zu sein oder die Berechtigung zu haben, sich als Benutzer anzumelden.

Jeder Benutzer, der rootless Podman ausführt, muss einen Eintrag in diesen Dateien haben, wenn er Container mit mehr als einer darin enthaltenen UID ausführen muss.

Ändern der Standardanzahl von IDs

Nun zur Frage der standardmäßigen Anzahl von UIDs und GIDs, die in einem Container verfügbar sind:65536. Diese Zahl ist keine feste Grenze und kann mit dem oben erwähnten /etc/subuid nach oben oder unten angepasst werden und /etc/subgid Dateien.

Zum Beispiel auf meinem System:

mheon@Agincourt code/libpod (master)$ cat /etc/subuid
mheon:100000:65536

Diese Datei hat das Format <username>:<start_uid>:<size> , wobei start_uid ist die erste UID oder GID, die dem Benutzer zur Verfügung steht, und size ist die Anzahl der verfügbaren UIDs/GIDs (beginnend mit start_uid und endet bei start_uid + size - 1 ).

Wenn ich diese 65536 beispielsweise durch 123456 ersetzen würde, hätte ich 123456 UIDs in meinen Rootless-Containern zur Verfügung.

"Warum 65536 als Standard wählen?" ist eine Frage für die Betreuer des Linux-Benutzererstellungstools useradd , da die anfänglichen Standardwerte ausgefüllt werden, wenn ein Benutzer erstellt wird, und nicht von Podman. Ich wage jedoch zu vermuten, dass diese Einstellung ausreicht, um die meisten Anwendungen ohne Änderungen am Laufen zu halten (sehr alte Linux-Versionen hatten nur 16-Bit-UIDs/GIDs, und höhere Werte sind immer noch etwas ungewöhnlich).

Hinweis: Die /etc/subuid und /etc/subgid Dateien dienen zum Anpassen von Benutzern, die bereits vorhanden sind. Standardeinstellungen für neue Benutzer werden an anderer Stelle angepasst.

Der Standardwert 65536, den neue Benutzer erhalten, ist nicht fest codiert. Dies wirkt sich jedoch nicht auf bestehende Benutzer aus. Es wird in /etc/login.defs gesetzt Datei, mit dem SUB_UID_COUNT und SUB_GID_COUNT Optionen. Wir haben tatsächlich darüber diskutiert, den Standardwert nach unten zu verschieben, da es sich anfühlt, als würden die meisten Container wahrscheinlich mit etwas mehr als 1000 UIDs/GIDs gut funktionieren und alle weiteren sind verschwendet.

Wichtig ist, dass dieser Wert einen Abschnitt von UIDs/GIDs darstellt, die auf dem Host zugewiesen sind und einem bestimmten Benutzer zur Verfügung stehen, um rootless Container auszuführen. Wenn ich diesem System einen weiteren Benutzer hinzufügen würde, würde er einen weiteren Abschnitt von UIDs erhalten, wahrscheinlich beginnend bei 165536, standardmäßig wieder 65536 breit.

Root hat die Berechtigung, diese Limits zu ändern, normale Benutzer jedoch nicht. Ansonsten könnte ich das Mapping ein wenig auf mheon:0:65536 ändern und bilde den echten Root-Benutzer auf dem System in meine Container ohne Root ab, die dann einfach in systemweiten Root-Zugriff geschwenkt werden können.

Überlappung von UID und GID verhindern

Als allgemeine Sicherheitsregel sollten Sie vermeiden, System-UIDs/GIDs (normalerweise unter 1000 nummeriert) und idealerweise alle UIDs/GIDs, die auf dem Hostsystem verwendet werden, in einen Container zu lassen. Diese Vorgehensweise verhindert, dass Benutzer Zugriff auf Systemdateien auf dem Host haben, wenn sie Rootless-Container erstellen.

Wir möchten auch, dass jeder Benutzer einen eindeutigen Bereich von UIDs/GIDs relativ zu anderen Benutzern hat – ich könnte einen Benutzer alice hinzufügen zu meinem /etc/subuid mit genau der gleichen Zuordnung wie mein Benutzer (alice:100000:65536 ), aber dann hätte Alice Zugriff auf meine wurzellosen Container und ich auf ihre.

Es ist möglich, die Größe Ihrer Benutzerzuweisung zu erhöhen, wie bereits erwähnt, aber Sie müssen diese Regeln aus Sicherheitsgründen befolgen. Ich werde sie noch einmal auflisten:

  • Keine UID/GID unter 1000.
  • Keine UID oder GID geht in den Container, wenn er auf dem Host verwendet wird.
  • Überlappen Sie keine Zuordnungen zwischen Benutzern.

Letzteres ist der Hauptgrund dafür, dass wir keine höheren UID- und GID-Zuordnungen abbilden möchten. Wir könnten einem Benutzer potenziell eine riesige Auswahl geben, einschließlich alles von 100.000 bis zu UID_MAX , und stellen Sie etwas mehr als 4,2 Millionen UIDs zur Verfügung – aber dann wäre keine mehr für andere Benutzer übrig.

Abschluss

Mit Podman 1.5.0 und höher haben wir eine neue, experimentelle Option hinzugefügt (--storage-opt ignore_chown_errors ), um alle UIDs und GIDs zu komprimieren und so Container als Einzelbenutzer auszuführen (der Benutzer, der den Container gestartet hat). Diese Einstellung löst das anfängliche Problem des Artikels, erlegt dem Container jedoch eine Reihe zusätzlicher Einschränkungen auf – Details dazu überlassen Sie am besten einem anderen Artikel.

Die UID- und GID-Einschränkungen, die Rootless-Containern auferlegt werden, können unbequem sein, aber Sie werden selten darauf stoßen. Die meisten Images und Container verwenden weit weniger als die 65536 verfügbaren UIDs und GIDs. Diese Einschränkungen sind einige der Kompromisse von Rootless-Containern, bei denen wir etwas Komfort und Benutzerfreundlichkeit für größere Sicherheitsverbesserungen opfern.


Linux
  1. Führen Sie Container unter Linux ohne sudo in Podman aus

  2. Rootless Podman als Nicht-Root-Benutzer ausführen

  3. Technologievorschau:Ausführen eines Containers in einem Container

  4. Verwenden von Dateien und Geräten in Podman-Containern ohne Root

  5. So debuggen Sie Probleme mit Volumes, die in Rootless-Containern gemountet sind

Wie Cirrus CLI Podman verwendet, um rootless Builds zu erreichen

4 Step Openldap-Container Podman Easy

1 DNS-Server-Container Podman schmutzig einfach

Warum kann ein normaler Benutzer eine Datei nicht „chown“?

Übertragen Sie Daten in einen MySQL-Container

Welches Betriebssystem läuft in meinem Docker-Container?