Rootlose Podman-Container sind eine wirklich coole Funktion, mit der Benutzer fast alle Container in ihrem Home-Verzeichnis ausführen können, ohne dass zusätzliche Berechtigungen erforderlich sind.
Rootlose Container nutzen den Benutzernamensraum, wie ich in diesem Blog erklärt habe.
Manchmal erschweren der Benutzernamensraum und andere Container-Sicherheitsebenen wie SELinux die gemeinsame Nutzung von Inhalten innerhalb des Containers. Wir haben viele Benutzer gesehen, die Systemverzeichnisse in ihren Containern freigeben möchten, aber mit Berechtigungsfehlern scheitern. Diese Verzeichnisse werden normalerweise über einen Gruppenzugriff freigegeben, der es dem Benutzer ermöglicht, Inhalte in den Verzeichnissen zu lesen/schreiben.
[Das könnte Ihnen auch gefallen: Rootless-Container mit Podman]
Beispielsweise könnte der Benutzer ein Verzeichnis /mnt/engineering
haben auf ihrem System, das root
gehört und Gruppe eng
, und mit Berechtigungen auf 770 festgelegt.
Schauen wir uns ein Beispiel an.
Fügen Sie den eng
hinzu Gruppe:
# groupadd eng
Erstellen Sie das Freigabeverzeichnis:
# mkdir /var/lib/mycontainers/
Ändern Sie den Gruppenzugriff für das Verzeichnis:
# chown root:eng /var/lib/mycontainers/
Ändern Sie die Berechtigungen, damit die Gruppe in das Verzeichnis schreiben kann:
# chmod 770 /mnt/engineering
Ändern Sie den SELinux-Typ des Verzeichnisses, damit Container es verwenden können:
# chcon -t container_file_t /mnt/engineering
Sehen wir uns als Nächstes die Berechtigungen für das Verzeichnis an:
# ls -lZ /mnt/engineering/ -d
drwxrwx---. 2 root eng unconfined_u:object_r:user_tmp_t:s0 40 Feb 9 07:24 /mnt/engineering/
Nun kann der Benutzer zum eng
hinzugefügt werden Gruppe:
$ grep eng /etc/group
Eng:x:14905:dwalsh
Melden Sie sich beim System an und vergewissern Sie sich, dass sich der Benutzer im eng
befindet Gruppe:
$ id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh),10(wheel),14905(eng) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Stellen Sie sicher, dass der Benutzer Inhalte im Verzeichnis lesen/schreiben kann:
$ touch /mnt/engineering/test
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
Führen Sie nun einen Container mit diesem Volume aus, aber dem Container wird die Berechtigung verweigert:
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
ls: cannot open directory '/mnt/engineering/': Permission denied
Da wir wissen, dass SELinux nicht blockiert, da wir das Label korrekt gesetzt haben, was ist passiert?
Benutzernamensraum
Das Problem ist der Benutzernamensraum.
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh)
Beachten Sie, dass die --userns=keep-id
Flag wird verwendet, um sicherzustellen, dass die UID innerhalb des Containers nicht root ist, sondern die reguläre UID des Benutzers. Beachten Sie oben, wenn ich die id
ausführe Befehl außerhalb des Containers enthalten meine Gruppen den eng
Gruppe, aber wenn der Container ausgeführt wird, wird der eng
Gruppe taucht nicht auf. Aus Sicherheitssicht ist dies eine gute Sache, denn wenn die Containerprozesse entkommen würden, hätten sie keinen Zugriff auf Verzeichnisse, auf die ich Gruppenzugriff habe. Wenn Benutzer Zugriff gewähren möchten, haben sie ein Problem.
Das Problem ist, dass es schwierig ist, diesen Verzeichnissen Zugriff auf den Container zu gewähren. Erstellen eines eng
Gruppe innerhalb des Containers würde nicht mit eng
übereinstimmen Gruppe auf dem Host, da der Benutzernamensraum die tatsächliche Gruppen-UID versetzt.
Zum Glück ist die OCI Runtime crun
unterstützt eine spezielle Funktion, um diese zusätzlichen Gruppen in den Container zu übertragen. Diese Fähigkeit wird im podman run
behandelt Manpage:
man podman run
...
Note: if the user only has access rights via a group, accessing the de‐
vice from inside a rootless container will fail. The crun(1) runtime
offers a workaround for this by adding the option --annotation
run.oci.keep_original_groups=1.
Und weiter erklärt im crun
Manpage:
man crun
…
run.oci.keep_original_groups=1
If the annotation run.oci.keep_original_groups is present, then crun
will skip the setgroups syscall that is used to either set the addi‐
tional groups specified in the OCI configuration, or to reset the list
of additional groups if none is specified.
Wenn ich diese Anmerkung setze, hat mein wurzelloser Podman jetzt Zugriff auf das Volume, wie unten zu sehen:
$ podman run -ti --annotation run.oci.keep_original_groups=1 --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
-rw-------. 1 dwalsh dwalsh 0 Feb 9 12:36 test
Wir verwenden eine Anmerkung, da die OCI-Spezifikation derzeit keine Möglichkeit hat, dies der OCI-Laufzeit mitzuteilen. Wir haben vorgeschlagen, es in die Spezifikation aufzunehmen. Derzeit keine andere OCI-Laufzeit außer crun
kann damit umgehen, einschließlich runc
. Vielleicht wird diese Funktion in Zukunft zum OCI hinzugefügt.
containers.conf
Wenn der Benutzer möchte, dass alle seine Container die Benutzergruppen teilen, kann er diese Anmerkung zur containers.conf
hinzufügen in ihren Home-Verzeichnissen.
$ cat ~/.config/containers/containers.conf
[containers]
annotations=["run.oci.keep_original_groups=1",]
Jetzt kann sogar der Standard-Podman Inhalte im Volume erstellen, und Benutzerprozesse außerhalb des Containers sehen den korrekten Inhalt.
$ podman run -ti --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 touch /mnt/engineering/test2
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
-rw-r--r--. 1 dwalsh dwalsh 0 Feb 9 13:36 test2
[ Erste Schritte mit Containern? Schauen Sie sich diesen kostenlosen Kurs an. Containerisierte Anwendungen bereitstellen:Eine technische Übersicht. ]
Schlussfolgerung
Das Freigeben von Inhalten vom Host in einen Container über Volume-Mounting kann manchmal durch verschiedene Sicherheitsfunktionen von Containern blockiert werden. Zum Glück Podman und crun
verfügen über erweiterte Funktionen, die es bestimmten Containern ermöglichen, diesen Inhalt und containers.conf
zu teilen ermöglicht es Benutzern, ihr System für alle Container einzurichten, um Zugriff auf diese Volumes zu erhalten.