Ahoj,
po nedávném článku o sandboxingu pomocí systemd jsem se vrátil k řešení jednoho staršího problému s přístupovými právy na linuxovém filesystému (dále FS). Pro tuto diskusi to ještě o něco zjednoduším:
- na serveru má účet uživatel Pepa (pepa), klidně s plnohonotným přístupem přes SSH, domovský adresář /home/pepa,
- Pepa provozuje na serveru www stránky, celou webovou aplikaci má třeba v /home/pepa/www,
- provoz té aplikace zajišťuje nějaký HTTP server (Apache atd.) běžící pod účtem www-data,
- Pepa chce uvnitř adresáře nastavit přístupová práva pro HTTP server (přesněji: pro uživatele www-data, dále už jen "uživatel Webdata"), a to odlišně pro různé soubory/složky: k některým souborům nemá Webdata přístup vůbec, některé může jen číst, některé i zapisovat atd.,
- kromě Pepy a Webdata nemá do /home/pepa/www nikdo jiný přístup.
Výše uvedené lze obecně zajistit i pomocí "obyčejných" práv FS, nejjenoduššeji asi tak, že se uživateli
www-data přidá doplňková skupina (
supplementary group)
pepa a uživatel Pepa si ve své složce
www ohlídá přístupová práva pro skupinu.
Problém ale nastává v případě, že chceme uživateli Webdata povolit vytvářet soubory (třeba ve složce
/home/pepa/www/upload). Povolit to lze, ale Pepa tím ztratí kontrolu nad touto složkou. Vlastníkem nově vytvořených souborů pak bude uživatel
www-data a ten si jako vlastník může dělat se svými soubory cokoliv, včetně toho, že k nim Pepovi zamezí přístup (vytvoří složku
/home/pepa/www/upload/not-for-pepa, uloží do ní nějaký soubor a zakáže k ní přístup všem kromě vlastníka - Pepa pak se složkou už nic neudělá.
Proti tomu nepomohou třeba ani posixové ACL, protože ať je na
/home/pepa/www vytvoříme libovolně včetně těch
default, tak jakmile v nich povolíme uživateli Webdata vytvářet soubory, může si on (Webdata) se svými nově vytvořenými soubory jako vlastník dělat co chce, včetně toho, že všechna ACL odstraní.
Jediný, kdo dokáže takto vytvořené soubory obecně odstranit (nebo aspoň zpřístupnit), je uživatel
root. Jenže původní myšlenka byla umožnit
Pepovi správu svého domovského adresáře včetně jeho webové aplikace.
Napadá vás, jak to řešit? V Linuxu je v tomto jen dvoúrovňová hierarchie: uživatel root je nadřazený všem ostatním. Já bych potřeboval, aby byl Pepa nějak "nadřazen" uživateli Webroot. Neuniklo mi nějaké jiné řešení? Vlastníka souboru při jeho vytváření podle mne nelze nijak ovlivnit (na rozdíl od skupiny - set-gid).
Dalo by se to nějak hezky řešit právě přes systemd a jeho sandboxing? Třeba takový Docker to vlastně umí (hierarchie: root na fyzickém serveru -> root v kontejneru -> ostatní uživatelé v kontejneru) a stačí mu na to jen jmenné prostory jádra.
Příklad jsem původně zjednodušil pro lepší vysvětlení. Ve skutečnosti to ale většina z nás provozuje na serverech složitěji: například běží jeden Nginx (uživatel
www-data, jediný Nginx je zde např. kvůli sdílení jedné IP adresy pomocí TLS SNI) a ten komunikuje s několika dalšími "aplikačními" procesy (třeba WSGI, CGI), z nich by měl idálně každý běžet pod odděleným uživatelem (
app1,
app2, ...), aby se co nejméně ovlivňovaly (čti: aby si vzájemně neviděly do svých dat). A kód/data těch několika webů spravuje jeden nebo více uživatelů jako byl Pepa (ještě se dá zjednodušit, že jeden Pepa administruje jednu aplikaci, ale i té musí umět omezit třeba zápis do souborů, které na server Pepa sám zapsal, tj. Pepa nemůže být přímo uživatelem
app). Další zjednodušení může být v tom, že uživateli
www-data nebude potřeba povolit vytváření souborů, to budou smět jen (dle nastavení) uživatelé
app.