Was ist ein nicht privilegierter LXC-Container?

20

Was bedeutet es, wenn ein Linux-Container (LXC-Container) "unprivilegiert" heißt?

0xC0000022L
quelle

Antworten:

20

Unprivilegierte LXC-Container verwenden Benutzernamensräume ( ). Dh einer Kernel - Funktion , die eine Reihe von UIDs auf dem Host in einen Namensraum kartieren ermöglicht innerhalb von denen ein Benutzer mit UID 0 wieder vorhanden sein.

Im Gegensatz zu meiner anfänglichen Wahrnehmung von nichtprivilegierten LXC-Containern für eine Weile bedeutet dies nicht, dass der Container einem nichtprivilegierten Hostbenutzer gehören muss. Das ist nur eine Möglichkeit.

Relevant ist:

  1. dass für den Host-Benutzer ein Bereich von untergeordneten UIDs und GIDs definiert ist ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... und dass dieser Bereich in der Containerkonfiguration abgebildet ist ( lxc.id_map = ...)

So rootkönnen auch nichtprivilegierte Container Eigentümer sein, da die effektiven UIDs der Containerprozesse auf dem Host innerhalb des durch das Mapping definierten Bereichs landen.

Dazu müssen rootSie jedoch zuerst die untergeordneten IDs definieren. Im Gegensatz zu Benutzern, die über erstellt wurden adduser, rootwird standardmäßig kein Bereich von untergeordneten IDs definiert.

Denken Sie auch daran, dass Ihnen der gesamte Bereich zur Verfügung steht, sodass Sie 3 Container mit den folgenden Konfigurationszeilen haben können (nur UID-Zuordnung wird angezeigt):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

Angenommen, rootdie untergeordneten UIDs liegen zwischen 100000 und 400000. Alle Dokumente, die ich gefunden habe, schlagen vor, 65536 untergeordnete IDs pro Container zu verwenden. Einige verwenden jedoch 100000, um die Lesbarkeit zu verbessern.

Mit anderen Worten: Sie müssen nicht jedem Container den gleichen Bereich zuweisen.

Mit über 4 Milliarden (~ 2^32) möglichen untergeordneten IDs können Sie die untergeordneten Bereiche großzügig an Ihre Hostbenutzer weitergeben.

Unprivilegierter Container, der Eigentum von root ist und von root ausgeführt wird

Um das noch einmal einzureiben. Ein nicht privilegierter LXC-Gast muss nicht von einem nicht privilegierten Benutzer auf dem Host ausgeführt werden.

Konfigurieren Sie Ihren Container mit einer untergeordneten UID / GID-Zuordnung wie folgt:

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

Wenn der Benutzer rootauf dem Host diesen untergeordneten ID-Bereich besitzt, können Sie die Gäste noch besser einschränken.

Es gibt jedoch einen wichtigen zusätzlichen Vorteil in einem solchen Szenario (und ja, ich habe überprüft, dass es funktioniert): Sie können Ihren Container beim Systemstart automatisch starten.

Wenn Sie im Internet nach Informationen zu LXC suchen, werden Sie normalerweise darauf hingewiesen, dass es nicht möglich ist, einen nicht privilegierten LXC-Gast automatisch zu starten. Dies gilt jedoch standardmäßig nur für solche Container, die sich nicht im systemweiten Speicher für Container befinden (in der Regel so etwas wie /var/lib/lxc). Wenn dies der Fall ist (was normalerweise bedeutet, dass sie von root erstellt und von root gestartet wurden), ist dies eine ganz andere Geschichte.

lxc.start.auto = 1

wird den Job ganz nett machen, sobald du ihn in deine Containerkonfiguration gesetzt hast.

Richtige Berechtigungen und Konfiguration

Ich habe selbst ein bisschen damit zu kämpfen, also füge ich hier einen Abschnitt hinzu.

Zusätzlich zu dem Konfigurations-Snippet, über lxc.includedas normalerweise der Name /usr/share/lxc/config/$distro.common.conf(wo $distroist der Name einer Distribution) angegeben wird, sollten Sie prüfen, ob sich /usr/share/lxc/config/$distro.userns.confauf Ihrem System auch ein befindet , und dies auch einschließen. Z.B:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

Fügen Sie außerdem die untergeordneten ID-Zuordnungen hinzu:

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

Dies bedeutet, dass sich die Host-UID 100000 root im Benutzernamensraum des LXC-Gasts befindet.

Stellen Sie nun sicher, dass die Berechtigungen korrekt sind. Wenn der Name Ihres Gastes in der Umgebungsvariablen gespeichert wäre, würden $lxcguestSie Folgendes ausführen:

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

Auf diese Weise können Sie den Container ausführen, nachdem bei Ihrem ersten Versuch möglicherweise einige berechtigungsbezogene Fehler aufgetreten sind.

0xC0000022L
quelle
4
Gute Antwort - ist aber lxckeine Notwendigkeit für so etwas. Mit dem util-linuxTool können Sie einen Namespace-Container beliebiger Art erstellen unshare. Sie können diesen Container mit dem util-linuxTool eingeben nsenter. Mit dem letzteren Tool können Sie auch laufende Prozesse zu einem bereits erstellten Container hinzufügen, ohne diesen zu verwenden. Die Namespace-Unterstützung wird im Kernel implementiert.
mikeserv
4
@mikeserv: Du meinst, du brauchst kein LXC, um von Usern Gebrauch zu machen ? Ich wusste, dass. Ich weiß auch, dass Docker jetzt eine eigene Bibliothek hat, die diese Einrichtungen nutzt. Aber wie würden Sie ein ganzes System ohne die von LXC angebotenen Einrichtungen containerisieren? Und warum würdest du es tun? Ich meine, eine einzige Anwendung zu enthalten und mit chrootdieser zu kombinieren, kann helfen, aber LXC kombiniert verschiedene der Namensräume (UTS, Mount usw.), um das gesamte System zu containerisieren.
0xC0000022L
2
Nun ... Wie ich schon sagte, unsharefunktioniert dies bewundernswert für jeden / alle der verschiedenen Namespaces - und Sie erhalten sogar ein separates, privates /procMount mit einem einzigen CLI-Switch. Wenn Ihre einzige Anwendung ist initund Sie chrootist initramfsdann erhalten Sie einen ganzen Container in Sekunden flach.
mikeserv
0

Um followup auf 0xC0000022L, deren Lösung funktionierte gut für mich, habe ich einen increase-uid-gid.pl Perl - Skript der notwendige Besitz zu automatisieren Änderungen erforderlich , um Dateien innerhalb des LXC Behälters richtig abgebildet.

Ohne diese Option wird bei dieser vorgeschlagenen Konfiguration eine Datei in LXC-Container-Rootfs, die zu 0 / root auf dem Haupthost gehört, im LXC-Container selbst 65534 / nobody zugeordnet. Um im LXC-Container auf 0 / root abgebildet zu werden, müssen sie zu 100000 auf dem Host gehören.

Dies ist hier beschrieben https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/ und das Skript kann direkt von gitlab https://gitlab.com bezogen werden /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

Sie
quelle