Kontejnery Rootless Podman jsou opravdu skvělá funkce, která uživatelům umožňuje spouštět téměř všechny kontejnery v jejich domovském adresáři, aniž by vyžadovali jakákoli další oprávnění.
Kontejnery bez kořenů využívají prostor jmen uživatelů, jak jsem vysvětlil v tomto blogu.
Někdy uživatelský jmenný prostor a další vrstvy zabezpečení kontejneru, jako je SELinux, znesnadňují sdílení obsahu uvnitř kontejneru. Viděli jsme mnoho uživatelů, kteří chtěli sdílet systémové adresáře do svých kontejnerů, ale selhali s chybami oprávnění. Tyto adresáře jsou obvykle sdíleny prostřednictvím nějakého skupinového přístupu, což uživateli umožňuje číst/zapisovat obsah v adresářích.
[ Také by se vám mohlo líbit: Kontejnery bez kořenů využívající Podman ]
Uživatel může mít například adresář /mnt/engineering
na jejich systému, který vlastní root
a skupina eng
a s oprávněními nastavenými na 770.
Podívejme se na příklad.
Přidejte eng
skupina:
# groupadd eng
Vytvořte sdílený adresář:
# mkdir /var/lib/mycontainers/
Změňte skupinový přístup k adresáři:
# chown root:eng /var/lib/mycontainers/
Změňte oprávnění tak, aby skupina mohla zapisovat do adresáře:
# chmod 770 /mnt/engineering
Změňte typ SELinux adresáře tak, aby jej kontejnery mohly používat:
# chcon -t container_file_t /mnt/engineering
Dále se podívejme na oprávnění v adresáři:
# ls -lZ /mnt/engineering/ -d
drwxrwx---. 2 root eng unconfined_u:object_r:user_tmp_t:s0 40 Feb 9 07:24 /mnt/engineering/
Nyní může být uživatel přidán do eng
skupina:
$ grep eng /etc/group
Eng:x:14905:dwalsh
Přihlaste se do systému a ujistěte se, že uživatel je v eng
skupina:
$ 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
Ujistěte se, že uživatel může číst/zapisovat obsah v adresáři:
$ touch /mnt/engineering/test
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
Nyní spusťte kontejner pomocí tohoto svazku, ale kontejneru bylo odepřeno oprávnění:
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
ls: cannot open directory '/mnt/engineering/': Permission denied
Protože víme, že SELinux neblokuje, protože jsme štítek nastavili správně, co se stalo?
Uživatelský jmenný prostor
Problém je uživatelský jmenný prostor.
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh)
Všimněte si, že --userns=keep-id
příznak se používá k zajištění toho, že UID uvnitř kontejneru není root, ale běžné UID uživatele. Všimněte si výše, že když spustím id
příkaz mimo kontejner, moje skupiny zahrnují eng
skupina, ale když je kontejner spuštěn, eng
skupina se nezobrazuje. Z hlediska zabezpečení je to dobrá věc, protože kdyby procesy kontejneru unikli, neměly by přístup k adresářům, ke kterým mám skupinový přístup. Pokud uživatelé chtějí udělit přístup, mají problém.
Problém je v tom, že je obtížné udělit přístup ke kontejneru těmto adresářům. Vytvoření eng
skupina uvnitř kontejneru by neodpovídala eng
skupina na hostiteli, protože uživatelský jmenný prostor kompenzuje skutečné UID skupiny.
Naštěstí OCI Runtime crun
podporuje speciální funkci pro únik těchto dalších skupin do kontejneru. Tato schopnost je zahrnuta v podman run
manuálová stránka:
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.
A dále vysvětleno v crun
manuálová stránka:
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.
Pokud nastavím tuto anotaci, můj rootless Podman má nyní přístup ke svazku, jak je vidět níže:
$ 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
Používáme anotaci, protože specifikace OCI v současné době nemá způsob, jak to sdělit OCI Runtime. Navrhli jsme jej přidat do specifikace. V současné době není k dispozici žádné jiné prostředí OCI Runtime než crun
to zvládne, včetně runc
. Možná v budoucnu bude tato funkce přidána do OCI.
containers.conf
Pokud chce uživatel, aby všechny jeho kontejnery sdílely skupiny uživatelů, mohl by přidat tuto anotaci do containers.conf
v jejich domovských adresářích.
$ cat ~/.config/containers/containers.conf
[containers]
annotations=["run.oci.keep_original_groups=1",]
Nyní může i výchozí Podman vytvářet obsah ve svazku a uživatelské procesy mimo kontejner vidí správný obsah.
$ 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
[ Začínáte s kontejnery? Podívejte se na tento bezplatný kurz. Nasazení kontejnerových aplikací:technický přehled. ]
Závěr
Sdílení obsahu z hostitele do kontejneru prostřednictvím připojení svazku může být někdy blokováno různými bezpečnostními prvky kontejnerů. Naštěstí Podman a crun
mají pokročilé funkce, které umožňují konkrétním kontejnerům sdílet tento obsah a containers.conf
umožňuje uživatelům nastavit svůj systém na všechny kontejnery, aby získali přístup k těmto svazkům.