Che cos'è un contenitore LXC senza privilegi?


20

Cosa significa se un contenitore Linux (contenitore LXC) è chiamato "senza privilegi"?

Risposte:


20

I contenitori LXC non privilegiati sono quelli che fanno uso degli spazi dei nomi utente ( ). Vale a dire una funzione del kernel che consente di mappare un intervallo di UID sull'host in uno spazio dei nomi all'interno del quale può esistere di nuovo un utente con UID 0.

Contrariamente alla mia percezione iniziale di contenitori LXC non privilegiati per un po ', ciò non significa che il contenitore debba essere di proprietà di un utente host non privilegiato. Questa è solo una possibilità.

Rilevante è:

  1. che è definito un intervallo di UID e GID subordinati per l'utente host ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... e che questo intervallo è mappato nella configurazione del contenitore ( lxc.id_map = ...)

Quindi anche i rootcontenitori non privilegiati possono essere posseduti, poiché gli UID efficaci dei processi contenitore sull'host finiranno all'interno dell'intervallo definito dalla mappatura.

Tuttavia, per rootte devi prima definire gli ID subordinati. A differenza degli utenti creati tramite adduser, rootnon avranno un intervallo di ID subordinati definiti per impostazione predefinita.

Tieni inoltre presente che l'intera gamma che fornisci è a tua disposizione, quindi potresti avere 3 contenitori con le seguenti linee di configurazione (mostrata solo la mappatura UID):

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

supponendo che rootpossieda gli UID subordinati tra 100000 e 400000. Tutta la documentazione che ho trovato suggerisce di usare 65536 ID subordinati per contenitore, alcuni usano 100000 per renderlo più leggibile dall'uomo, però.

In altre parole: non è necessario assegnare lo stesso intervallo a ciascun contenitore.

Con oltre 4 miliardi (~ 2^32) possibili ID subordinati significa che puoi essere generoso quando gestisci gli intervalli subordinati con gli utenti host.

Contenitore non privilegiato di proprietà ed eseguito da root

Per strofinarlo di nuovo. Un guest LXC non privilegiato non deve essere eseguito da un utente non privilegiato sull'host.

Configurazione del contenitore con un mapping UID / GID subordinato come questo:

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

dove l'utente rootdell'host possiede quel dato intervallo di ID subordinato, ti permetterà di confinare gli ospiti ancora meglio.

Tuttavia, esiste un importante vantaggio aggiuntivo in tale scenario (e sì, ho verificato che funzioni): è possibile avviare automaticamente il contenitore all'avvio del sistema.

Di solito, durante la ricerca del Web per informazioni su LXC, viene indicato che non è possibile avviare automaticamente un ospite LXC senza privilegi. Tuttavia, questo è vero solo per impostazione predefinita per quei contenitori che non si trovano nella memoria di sistema per i contenitori (di solito qualcosa del genere /var/lib/lxc). Se lo sono (che di solito significa che sono stati creati da root e sono stati avviati da root), è una storia completamente diversa.

lxc.start.auto = 1

farà il lavoro abbastanza bene, una volta inserito nel tuo contenitore di configurazione.

Ottenere autorizzazioni e configurazione corrette

Ho lottato un po 'con questo, quindi sto aggiungendo una sezione qui.

Oltre allo snippet di configurazione incluso tramite il lxc.includequale di solito va sotto il nome /usr/share/lxc/config/$distro.common.conf(dove si $distrotrova il nome di una distro), dovresti controllare se c'è anche un /usr/share/lxc/config/$distro.userns.confnel tuo sistema e includerlo anche. Per esempio:

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

Inoltre aggiungi i mapping degli ID subordinati:

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

il che significa che l'host UID 100000 è root dentro lo spazio dei nomi utente del guest LXC.

Ora assicurati che le autorizzazioni siano corrette. Se il nome del tuo ospite fosse archiviato nella variabile d'ambiente $lxcguest, eseguiresti quanto segue:

# 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

Ciò dovrebbe consentire di eseguire il contenitore dopo che il primo tentativo potrebbe aver fornito alcuni errori relativi alle autorizzazioni.


4
Buona risposta - ma lxcnon è una necessità per questo tipo di cose. È possibile creare un contenitore dello spazio dei nomi di qualsiasi tipo utilizzando lo util-linuxstrumento unshare. Puoi inserire detto contenitore usando lo util-linuxstrumento nsenter. Quest'ultimo strumento consente anche di aggiungere processi in esecuzione a un contenitore già creato dall'esterno. Il supporto dello spazio dei nomi è implementato nel kernel.
Mikeserv,

4
@mikeserv: vuoi dire che non hai bisogno di LXC per usare Userns ? Sapevo che. So anche che Docker ora ha una propria biblioteca che utilizza queste strutture. Ma come containerizzeresti un intero sistema senza l'aiuto delle strutture offerte da LXC? E perché dovresti farlo? Intendo contenere una singola applicazione e combinata con chrootquesto può aiutare, ma LXC combina vari spazi dei nomi (UTS, mount ecc ...) per containerizzare l'intero sistema.
0xC0000022L

2
Bene ... Come ho unsharegià detto, lo fa già in modo ammirevole per qualsiasi / tutti i vari spazi dei nomi - e ti offrirà anche un /procmontaggio separato e privato con un singolo cli-switch. Se la tua singola applicazione è inite la tua chrootè initramfs, otterrai un intero contenitore in pochi secondi.
Mikeserv,

0

Per il follow-up su 0xC0000022L, la cui soluzione ha funzionato bene per me, ho scritto uno script perl aumenta-uid-gid.pl per automatizzare le necessarie modifiche di proprietà necessarie in modo che i file all'interno dei contenitori LXC siano correttamente mappati.

Senza di essa, con questa proposta di installazione, un file all'interno del container LXC rootfs appartenente a 0 / root sull'host principale verrà, all'interno del contenitore LXC stesso, mappato a 65534 / nobody. Per essere mappati su 0 / root all'interno del contenitore LXC, devono appartenere a 100000 sull'host.

Questo è descritto qui https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/ e lo script può essere ottenuto direttamente su gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.