Cosa significa se un contenitore Linux (contenitore LXC) è chiamato "senza privilegi"?
Cosa significa se un contenitore Linux (contenitore LXC) è chiamato "senza privilegi"?
Risposte:
I contenitori LXC non privilegiati sono quelli che fanno uso degli spazi dei nomi utente ( userns ). 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 è:
usermod [-v|-w|--add-sub-uids|--add-sub-gids])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):
lxc.id_map = u 0 100000 100000lxc.id_map = u 0 200000 100000lxc.id_map = u 0 300000 100000supponendo 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.
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.
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.
chrootquesto può aiutare, ma LXC combina vari spazi dei nomi (UTS, mount ecc ...) per containerizzare l'intero sistema.
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.
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
lxcnon è una necessità per questo tipo di cose. È possibile creare un contenitore dello spazio dei nomi di qualsiasi tipo utilizzando loutil-linuxstrumentounshare. Puoi inserire detto contenitore usando loutil-linuxstrumentonsenter. 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.