I container Podman senza root sono una funzionalità davvero interessante che consente agli utenti di eseguire quasi tutti i container nella loro home directory senza richiedere privilegi aggiuntivi.
I container senza root sfruttano lo spazio dei nomi utente, come ho spiegato in questo blog.
A volte lo spazio dei nomi utente e altri livelli di sicurezza del contenitore come SELinux rendono più difficile condividere il contenuto all'interno del contenitore. Abbiamo visto molti utenti che vogliono condividere le directory di sistema nei loro contenitori ma falliscono con errori di autorizzazione. Queste directory sono generalmente condivise tramite un accesso di gruppo, che consente all'utente di leggere/scrivere il contenuto nelle directory.
[ Potrebbe piacerti anche: Contenitori rootless con Podman ]
Ad esempio, l'utente potrebbe avere una directory /mnt/engineering
sul loro sistema, che è di proprietà di root
e gruppo eng
e con autorizzazioni impostate su 770.
Diamo un'occhiata a un esempio.
Aggiungi il eng
gruppo:
# groupadd eng
Crea la directory di condivisione:
# mkdir /var/lib/mycontainers/
Modifica l'accesso di gruppo per la directory:
# chown root:eng /var/lib/mycontainers/
Modifica le autorizzazioni in modo che il gruppo possa scrivere nella directory:
# chmod 770 /mnt/engineering
Cambia il tipo SELinux della directory in modo che i contenitori possano usarlo:
# chcon -t container_file_t /mnt/engineering
Quindi, diamo un'occhiata alle autorizzazioni sulla directory:
# ls -lZ /mnt/engineering/ -d
drwxrwx---. 2 root eng unconfined_u:object_r:user_tmp_t:s0 40 Feb 9 07:24 /mnt/engineering/
Ora l'utente può essere aggiunto a eng
gruppo:
$ grep eng /etc/group
Eng:x:14905:dwalsh
Accedi al sistema e assicurati che l'utente sia nel eng
gruppo:
$ 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
Assicurati che l'utente possa leggere/scrivere contenuto nella directory:
$ touch /mnt/engineering/test
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
Ora esegui un contenitore usando questo volume, ma il contenitore ottiene l'autorizzazione negata:
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
ls: cannot open directory '/mnt/engineering/': Permission denied
Poiché sappiamo che SELinux non sta bloccando poiché abbiamo impostato correttamente l'etichetta, cosa è successo?
Spazio dei nomi utente
Il problema è lo spazio dei nomi utente.
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh)
Nota che il --userns=keep-id
flag viene utilizzato per garantire che l'UID all'interno del contenitore non sia root ma l'UID normale dell'utente. Notare sopra che quando eseguo id
comando al di fuori del contenitore, i miei gruppi includono eng
gruppo, ma quando il contenitore viene eseguito, il eng
il gruppo non si presenta. Dal punto di vista della sicurezza, questa è una buona cosa perché se i processi del contenitore sono sfuggiti, non avrebbero accesso alle directory a cui ho accesso di gruppo. Se gli utenti vogliono concedere l'accesso, hanno un problema.
Il problema è che è difficile concedere l'accesso al contenitore a queste directory. Creazione di un eng
il gruppo all'interno del contenitore non corrisponderebbe a eng
gruppo sull'host perché lo spazio dei nomi utente compensa l'UID del gruppo reale.
Fortunatamente l'OCI Runtime crun
supporta una funzione speciale per trasferire questi gruppi aggiuntivi nel contenitore. Questa capacità è trattata in podman run
pagina man:
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.
E ulteriormente spiegato nel crun
pagina man:
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.
Se imposto quell'annotazione, il mio Podman senza root ora ha accesso al volume, come mostrato di seguito:
$ 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
Usiamo un'annotazione poiché la specifica OCI attualmente non ha un modo per comunicarlo al runtime OCI. Abbiamo suggerito di aggiungerlo alle specifiche. Al momento, nessun altro runtime OCI diverso da crun
può gestirlo, incluso runc
. Forse in futuro questa funzione verrà aggiunta all'OCI.
containers.conf
Se l'utente desidera che tutti i suoi contenitori condividano i gruppi di utenti, può aggiungere questa annotazione a containers.conf
nelle loro directory home.
$ cat ~/.config/containers/containers.conf
[containers]
annotations=["run.oci.keep_original_groups=1",]
Ora anche il Podman predefinito può creare contenuto nel volume e i processi utente al di fuori del contenitore vedono il contenuto corretto.
$ 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
[ Iniziare con i container? Dai un'occhiata a questo corso gratuito. Distribuzione di applicazioni containerizzate:una panoramica tecnica. ]
Conclusione
La condivisione del contenuto dall'host in un container tramite il montaggio del volume può talvolta essere bloccata da varie funzionalità di sicurezza dei container. Fortunatamente Podman e crun
dispongono di funzionalità avanzate per consentire a contenitori specifici di condividere questo contenuto e containers.conf
consente agli utenti di configurare il proprio sistema su tutti i container per accedere a questi volumi.