Někdy se uživatelé podivují nad omezeními režimu bez kořenů pro kontejnerové motory Buildah a Podman. S režimem rootless posouváme hranice toho, co může dělat neprivilegovaný uživatel. Jednou z mých prací je práce s týmy jádra a týmy souborového systému, aby byl rootless lepší. V tomto článku vysvětluji, proč je připojování obrazů obtížnější v režimu bez kořenů.
[ Také by se vám mohlo líbit: Vyvážení zabezpečení Linuxu a použitelnosti ]
Montáž bez kořenů
Normální uživatel nemůže připojit souborový systém, pokud není v jmenném prostoru uživatele spolu s vlastním jmenným prostorem připojení . Jmenný prostor připojení umožňuje procesům v něm připojovat systémy souborů, které nevidí jmenný prostor připojení hostitele. Toto omezení jádra chrání hostitelský operační systém před potenciálními útoky, kdy by uživatel mohl připojit obsah přes /tmp
nebo dokonce v jejich domovském adresáři a pak oklamat další procesy v systému nebo administrátory, aby použili přípojné body.
Jakmile se uživatelský proces připojí k uživatelskému jmennému prostoru a novému jmennému prostoru připojení, jádro umožňuje připojení pouze určitých souborových systémů. V době psaní tohoto článku umožňuje jádro souborové systémy sysfs, procfs, tmpfs, bind mount a fuse. Nedávno jsme dostali opravu do upstream jádra na podporu překryvných souborových systémů, což bude velké zlepšení, ale v současnosti většina distribucí tuto podporu nemá. Rád bych získal podporu NFS, ale s tím jsou spojena bezpečnostní rizika. Doufejme, že jádro tyto problémy vyřeší a nakonec bude podporováno.
Bezkořenové kontejnerové enginy jako Podman a Buildah si při spuštění automaticky vytvoří svůj vlastní uživatelský jmenný prostor a připojí jmenný prostor. Když proces kontejnerového enginu skončí, jmenné prostory uživatele a připojení zmizí a proces uživatele se vrátí zpět do jmenného prostoru připojení hostitele. V tomto okamžiku již nejsou připojení vytvořená při spouštění nástrojů viditelná pro jiné procesy na hostiteli a nejsou jimi použitelná.
Proč je to důležité?
Jednou ze skvělých funkcí Buildah je umožnit uživatelům získat přístup k nízkoúrovňové sémantice stavby kontejnerů. Většina tvůrců obrázků kontejnerů se zasekne pouze u jednoho způsobu vytváření kontejnerů – v podstatě pomocí Containerfiles nebo Dockerfiles. Buildah bud
podporuje vytváření s těmito soubory. Buildah také umožňuje uživatelům vytvářet kontejnery pomocí nízkoúrovňových primitiv. Uživatelé jej mohou použít k vytvoření adresáře, naplnění adresáře obsahem, vytvoření obrázku a jeho odeslání do registru.
# ctr=$(buildah from scratch)
# mnt=$buildah mount $ctr)
# dnf -y --install-root $mnt httpd
# buildah config --entrypoint .... $ctr
# buildah commit $ctr IMAGE
# buildah push IMAGE REGISTRY
To vše funguje skvěle, když běží jako root, ale když se to uživatelé pokusí spustit v režimu bez root, jejich skripty vybuchnou.
$ mnt=$(buildah mount $ctr)
cannot mount using driver overlay in rootless mode. You need to run it in a `buildah unshare` session
Problém je mnt=$(buildah mount $ctr)
odmítne připojit obraz s překryvným ovladačem, pokud jste neprovedli buildah unshare
.
Podrobnější pohled
Když spustíte buildah
příkazy, jako je bud
a run
, v režimu bez kořenů, buildah
příkaz zadá jmenné prostory uživatele a připojení. Dobře připojí systém souborů kontejneru a spustí příkazy. Po dokončení příkazu buildah
ukončí, což způsobí zničení jmenných prostorů. Když to uděláte pomocí mount
příkaz, připojený souborový systém nebyl nikdy vidět v jmenném prostoru připojení hostitele. Buildah nyní zkontroluje tuto situaci a nahlásí uživateli, že musí vydat buildah unshare
první.
buildah zrušit sdílení
Buildah a Podman mají speciální příkaz unshare
. Tento příkaz vytvoří a zadá uživatelský jmenný prostor, aniž by vytvořil kontejner nebo s ním interagoval. Ve skutečnosti je docela zajímavé prozkoumat tento režim, abyste plně porozuměli tomu, co uživatelský jmenný prostor dělá. Probíhá buildah unshare
příkaz spustí příkaz shellu ve jmenných prostorech spuštěných jako root v uživatelském jmenném prostoru. Nyní můžete spustit jakýkoli příkaz, včetně buildah
výše popsané příkazy. Protože tyto příkazy jsou již ve jmenných prostorech, buildah mount
příkaz bude fungovat stejně jako v kořenovém režimu. Vše se děje uvnitř jmenných prostorů a uživatel dostane to, co očekává.
Nyní může uživatel použít výše uvedené příkazy a vytvořit skript shellu. Tento skript shellu je pak spuštěn přímo pomocí buildah unshare
příkaz.
$ cat > buildahimage.sh < _EOF
ctr=$(buildah from scratch)
mnt=$buildah mount $ctr)
dnf -y --install-root $mnt httpd
buildah config --entrypoint .... $ctr
buildah commit $ctr IMAGE
buildah push IMAGE REGISTRY
< _EOF
chmod +x /buildahimage.sh
buildah unshare ./buildimage.sh
[ Začínáte s kontejnery? Podívejte se na tento bezplatný kurz. Nasazení kontejnerových aplikací:technický přehled. ]
Sbalit
Je smutné, že nemůžeme opravit vše v jádře, abychom uživatelům poskytli očekávané prostředí bez rootu, a to především kvůli bezpečnostním obavám. Ale můžeme se přiblížit. A samozřejmě můžete vždy pracovat v rootuálním režimu, pokud potřebujete další funkce.