To je zajímavé, kolik lidí kope do LP. A proč?
Protože služba se spustí pod rootem místo pod špatně definovaným uživatelem.
Není také pravda, že aby bylo možné službu (unit file) vytvořit, tak dotyčný už má rootovská práva?
Pokud ano, tak to znamená, že dotyčný už roota má a v čem je tedy problém?
Tak co, už je LP dost ukamenovaný?
Pokud ano, tak to znamená, že dotyčný už roota má a v čem je tedy problém?
Takže když má správce roota (jako že má, od toho je to správce), tak to znamená, že mají běžet všechny služby pod rootem a je to vlastně jedno? :-D
Problém je v tom, že správce nastavil, že daná věc má běžet jako User=něco a místo, aby to běželo jako user něco, nebo to selhalo, pokud user něco neodpovídá pravidlům, tak se to spustí jako root. Může se jednat třeba o překlep, místo User=petr může někdo napsat User=0etr. A už to běží jako root. Petra to jistě potěší, ale co ty ostatní?
To si rovno môžeš písať Lennartom. Keď nepochopí ani takéto základné bezpečnostné prvky, je to zbytočne zabitý čas a viem si ho predstaviť využiť lepšie.
Zhodou okolností som na tento bug natrafil skoro hneď po vidaní a chcel som to vidať ako správičku, ale potom som si hovoril, prečo vlastne.
Tusis ze ti neco prileze s aktualizaci? A co kdyz nekdo naisntaluje rekneme apache ... a z nejakyho duvodu failne vytvoreni userera ... to se pak ten apache, aniz by si toho nekdo vsimnul, pekne pusti pod rootem ... ostatne, stejne jako ve widlich, tam taky vsechno bezi pod systemem nebo adminem zejo ...
Nehlede na to, ze ses negramotnej, protoze ono se to pusti pod rootem i v pripade, ze ten user normalne existuje, da se na nej prihlasit, ale curak poettering se proste rozhod, ze kazdej user zacinajici cislem je root.
O tom ze bys tusil ze se celkem bezne startujou servisy pod user accountama po prihlaseni toho kteryho usera ani nemluve .. mno a kdyz se proste prihlasi 0124vomacka ... tak se mu to spusti pekne pod rootem.
Ve Windows běží pod "systémem" tedy účtem SYSTEM jen ty nejdůležitější služby. Účet SYSTEM je lokálním administrátorem.
Ostatní služby pak běží pod Local Service či Network Service - to jsou neadministrátorské účty které se liší jen tím, jak se autentifikují po síti.
Nic vám samozřejmě nebrání spouštět služby pod libovolnými účty.
Problém je, že když USER=sqldb dám USER=3qldb, tak při SQL injection může kdokoliv cokoliv nejenom v DB, ale na celé mašině. A proč?
- Admin se překlepl
- systemd si myslel, že "3qldb" je číslo uživatele
- systemd zjistil, že "3qldb" není číslo, takže zahodil volbu USER
- systemd to bral tak, že když není platný UID, má použít default hodnotu
- systemd má jako default hodnotu to nejhorší, co může mít - roota
- a útočník má pak volný ruce na cokoliv.
Jak by to mělo fungovat:
1) USER byl čistě jméno uživatele
2) Pro UID byla volba UID
3) Parse error -> odmítne to spustit
4) USER nebo UID není v systému -> odmítne to spustit
3) Není zadáno UID nebo USER -> odmítne to spustit
Chybu může udělat každý, ale pokud se z ní někdo nepoučí a trvá na nesmyslu, tak je důraznější upozornění v podobě drsnější kritiky na místě.
Bohužel spousta zařízení přístupných s default heslem je realita dnešního internetu a rozsáhlých botnetů.
Nicméně tento problém není způsobený touto konkrétní "chybou" systemd a myslím si, že ani nemůže. Je to stejné jako tvrdit, že výrobce nožů může za to, že tudle Franta běžel s nožem v ruce, viděl ho Pepa, tak taky běžel s nožem v ruce, ale narazil do manželky a dořezal ji.
Takže výrobce nože na rukojeť nenapsal: Neběhejte s nožem a výrobce může za to, že Pepova manželka je dořezaná. Tak je to kretén, když řekne, že nic opravovat nebude.
Bohužel souhlasím s výrobcem nožů, že není třeba nic opravovat a o těch co tvrdí, že je to kretén, si myslím své. A bohužel mám zvláštní potřebu to říkat všem okolo.
To jsme se nepochopili. Já netvrdím že tato chyba může za nějaké botnety nebo co . .. Já tvrdím, že fallback na roota default a to s tou 0 je totální vagínovina a nemělo se to tam objevit. Ovšem psal jsem ten příspěvek (jako reakci) proto, abych tě upozornil, že ne všechny služby si uživatel instaluje sám a má tedy kontrolu nad unitfile. Nic o botnetech, nožích, Pepovi, Frantovi . . . . apod.
Díky.
Souhlasím, že se služba rozběhne pod rootem, když uživatel začíná číslem není zamýšlená vlastnost. Nicméně za bezpečnostní díru to nepovažuju, protože:
1. Unit file zavádí root uživatel, který by měl být dostatečně uvědomělý, aby si to zkontroloval
2. Výstup při spuštění této služby píše, že služba běží pod rootem
3. Automatická instalace služby z balíčkovacího systému je psaná lidmi, kteří jsou také uvědomělí a ověří, zda se služba pouští pod rootem.
Myslím si, že LP má pravdu, když tiket uzavřel s tím, že se nejedná o bug.
Nesouhlasím s názorem, že LP je kretén, naopak si myslím, že je to velmi inteligentní člověk.
Celkově je to podle mě díra, protože instaluješ pod rootem a v podstatě ti takto může přes unit-file (jak psala Kate i pokud tam dá User=root) získat práva administrátora. Třeba já o tom nevěděl, resp. nenapadlo mě to, neřešil jsem to, snažím se to používat co nejméně. Oba si to můžeme zkontrolovat. Ale co tzv. linuxový desktop pro ostatní uživatele? Vždyť takto lze jednoduše přijít k právům roota - stačí si nainstalovat nějaký takto zmanipulovaný balíček (automatická instalace z .deb/.rpm) - ani bů, ani bé, tu máš roota a hrej si . . . .
Podle vás je díra, že root může získat práva roota? Podle mne to žádná díra není, to že root má práva roota je přece úplně normální… A běžný uživatel nemá právo User změnit, vždy se to spouští pod jeho účtem.
User=root se tam ani dávat nemusí – služba se normálně spouští pod rootem, volba User je volitelná a umožňuje to změnit.
Jo, jenže jedna věc je instalace a druhá spuštění - když si uživatel vezme např. *.deb a instaluje ho s právy roota, tak se mu "rozbalí" do filesystému. Pokud mu ale intalátor službu zrovna nastartuje a bude tam User=root nebo nic, tak třeba deb balíček xyz.deb získá práva roota - na Widlích se tě to aspoň zeptá.
Resp. pokud by ti např při apt update nějaký balíček změnil své unit file na User=root a restl se, tak se dá říct, že nějaká 3. strana rozhoduje o tom, jestli si sama na tvému systému přidělí roota - a znova opakuji - pak (z logu) už může být pozdě . . Dokonce i logy by po sobě mohla uklidit . .. . To nevypadá moc bezpečně
User=root se tam ani dávat nemusí – služba se normálně spouští pod rootem, volba User je volitelná a umožňuje to změnit.
Jo, a přesně takhle se dělá bezpečný software. Admin chce omezit práva pro spouštěnou binárku, ono to nejde, tak se to spustí jako root...
S takovou se klidně můžu dočkat toho, že se nepovede zinicializovat nspawn, tak to systemd spustí přímo na daném systému.
Rozkaz zněl jasně, musíme to spustit. Nebylo čas lámat si hlavu jak...
Tomáš Crhonek, 9:21: Když admin něco chce, musí to systému nějak říct. Asi mám větší fantazii, než je běžné, ale dovedu si představit milion způsobů, jak chyba v jednotkovém souboru, kterou není možné nijak detekovat, může způsobit nějakou škodu. Stačí třeba do příkazů, které se spouští, zadat chybný příkaz. Systemd nemá jak zjistit, že jste chtěl do pre příkazu napsat rm -r /tmp/app, ale místo toho jste tam napsal rm -r / tmp/app. Můžete mít jednotku, která se spouští pod rootem, ale vzdává se nějakých capability – opět, když to zadáte špatně, nikdo nezjistí, že jste to myslel jinak. Některé služby dělají postaru su na uživatele samy – opět, když na příslušný parametr zapomenete, služba poběží pod rootem.
Od toho systemd vypisuje ta varování, když se mu něco nezdá. Ale jak byste to chtěl udělat, aby jednotkové soubory byly vždy bezpečné? Volba User bude povinná, ExecStartPre a ExecStartPost budou povinné, ve volbách Exec bude zakázáno rm a dalších asi milion podmínek, které budou bránit tomu, aby správce mohl napsat něco nebezpečného? Nebo kde má být ta hranice?
Asi mám větší fantazii, než je běžné, ale dovedu si představit milion způsobů, jak chyba v jednotkovém souboru, kterou není možné nijak detekovat, může způsobit nějakou škodu. Stačí třeba do příkazů, které se spouští, zadat chybný příkaz.
Stále vidím zásadní rozdíl mezi tím, kdy software ignoruje známou lvalue jen na základě hodnoty a mezi tím, kdy admin, možná omylem, napíše ExecStart=/bin/rm -r --no-preserve-root /.
Nebo kde má být ta hranice?
Tohle je fakt absurdní.
Ta hranice má být tam, co může systemd kontrolovat a co může systemd ovlivnit, co je v jeho gesci. Tzn je naprosto absurdní argumentovat tím, že do ExecStart si můžu dát příkaz pro odpálení atomové bomby a argumentovat tím, zda by to měl systemd kontrolovat.
Takže znova po sté: systemd by měl kontrolovat lvalue. Pokud lvalue zná (je to pro něj známá konfigurační volba), měl by se pokusit zpracovat její hodnotu. Pokud zpracovat hodnotu nelze, neměl by tuto lvalue ignorovat, ale měl by ohlásit chybu a celou unitu prohlásit za neplatnou. (+ jako bonus možnost nastavit striktní režim, že to nebude ignorovat ani neznamé lvalue, to bych si s chutí nastavil, ostatním to necpu)
Tímto způsobem běžný software hlídá chyby admina. Ano, pochopitelně existuje další milion možností, jak admin může systému uškodit. Ale to přece neznamená, že úplně rezignujeme na jakoukoliv kontrolu. (Kdysi BASIC na Didaktiku taky psal jen syntax error - a člověče najdi si to, dnešní kompilery poměrně přesně programátora navedou na výskyt chyby v kódu - podle tebe je to naprosto zbytečné, protože tu chybu lze ignorovat.)
Pane Jirsáku, stále si nerozumíme a stále se to motá dokola...
Když uděláte chybu (a to jednou uděláte), tak byste měl být přece rád, že systém zabrání (a tohle je v jeho silách), abyste vylil jakési neznámé binárce vnitřnosti systému k dispozici, přestože se pod uživatelem pepazdepa neměla k ničemu dostat. Když spouštíte nějakou službu, budete radši, aby za každou cenu jela, nebo aby vám nevyventilovala informace z jiných účtů či systému (nebo jej dokonce neupravila)? Nebavíme se tu o tom, že máte OS tip ťop, ale co se stane, když nebude.
SB, 11:20: Já vám rozumím. Systém té chybě může zabránit – ale jedině tehdy, pokud o ní předem ví.
Jednotkové soubory fungují tak, že mají nějaké volby, a těm volbám se zadávají hodnoty, které mají nějakou syntaxi. Pokud je ta syntaxe neznámá, systemd vypíše hlášku do logu a ignoruje jí. Možná řešení toho problému jsou dvě. Buď je možné určit, že volba User může mít libovolnou hodnotu – pak to skončí na chybu, že uživatel neexistuje, a budete spokojen. Jenže se tím zazdí možnost do budoucnosti přidat další volby pro položku User (třeba prefixem @ nebo + určit, že se má s názvem zacházet jinak – jako to má spousta jiných voleb v jednotkových souborech). Čímž se nesystémově zabrání jedné z milionu možností, jak může správce udělat chybu při konfiguraci jednotek. Druhá možnost je speciálně v případě User změnit varování na chybu. Proč ale zrovna v případě volby User, proč ne taky u jiných voleb?
Nejde o to, že ta služba má za každou cenu běžet. Jde o to, že s jednotkovými soubory se pracuje tak, že se neznámé volby ignorují. Pokud bude nějaké aplikace pracovat s jednotkovými soubory a nebude znát volbu Description, opravdu to má být důvod, proč s tím souborem odmítne pracovat? Když já si do jednotkových souborů přidám informace o tom, na kterých nodech clusteru se má služba spouštět, opravdu to má zabránit spuštění takových služeb, dokud neprotlačím do systemd a všech ostatních aplikací patch, že má tyhle volby ignorovat?
Já beru, že tu spousta lidí chce, aby se systemd choval jinak. Ale nikdo tu neměl tu odvahu, aby napsal, jak přesně se to zacházení s jednotkovými soubory má změnit. Třeba že se všechna varování mají změnit na chyby. Nebo že se se s volbu User má zacházet jinak. Ono je jednoduché, když vidím nějakou „chybu“, rychle vymyslet nějakou záplatu, která tu jednu domnělou díru zalepí – bez ohledu na cokoli jiného. Ale promýšlet to v celku, jak to ovlivňuje celkovou koncepci, zda tím náhodou nerozbiju něco jiného, jestli je to opravdu dostatečný důvod, proč porušit koncepci a zavést nesystémovou výjimku – to už je něco jiného.
Opravdu existují různý kategorie parametrů.
Třeba blbý rm, když mu nedám cestu, padne na hubu, protože mu chybí informace, kterou nemá jak získat. když vynechám -v, příkaz proběhne (jenom se chová trochu jinak).
Když se má něco automaticky spustit, tak je potřeba vědět, pod jakým uživatelem. Když mu to nikdo jednoznačně nezadá, nesmí hádat. Když už "hádá", musí "uhodnout" alternativu, která je nejbezpečnější.
Ehm. Zmanipulovaný balíček který vytvoří unit file s User=0neco je jeden z nejkrkolomnějších způsobů jak získat roota přes zmanipulovaný balíček. Proboha, pokud počítáš se scénářem zmanipulovaného balíčku, tak má jeho tvůrce bambilión a jeden způsob získání roota. A pokud trváš na krkolomných řešeních, úplně stejně jako přes ten unit file to jde získat přes sysv init skript.
V tomhle případě můžeš tedy za díru považovat samotnou instalaci balíčků pod rootem. Protože podvržený balík si může dělat v systému prakticky co chce a může zneužít init systém tisíci a jedním způsobem. Pokud chci přes podvržený balíček spouštět něco pod rootem pomocí systemd, proč bych se měla obtěžovat blbým User=123foobar, když můžu napsat rovnou User=root nebo User=0?
A hlavně, proč blbnout s jakýmkoliv initem, když můžu svým podvrženým balíčkem prostě do /bin vrazit shell s nastaveným SUID bitem?
NULL, 10:07: Právě jste překonal hranici mezi „opravdu o tom toho tak málo ví“ a „aha, ona je to jen čistá groteska“. Vám tedy prostě vadí, že root má na Linuxu neomezená práva, a viníte z toho systemd.
Mohl byste nastínit vaši představu, jak by se asi do Linuxu instaloval systémový software (nebo třeba jádro) tak, aby se nemohl spustit žádný kód pod rootem? Mohl byste nastínit, jak byste provozoval služby tak, aby žádná z nich nevyžadovala práva roota? Nebo co se vám nelíbí na systémových jednotkách, které může nainstalovat jenom root a které mohou běžet pod rootem? Chtěl byste, aby při každém startu takové jednotky musel root zadat heslo? Nebo jak byste si to představoval?
O ničem takovém jsem nepsal. Kde jsem napsal že nechci aby se cokoliv pouštělo pod rootem?
Aha, nikde.
Jenom jsem nastínil možnost, že takto může unita které třeba tebou v directivě User byly nastavena nižší práva získat vyšší. To mi jako problém připadá. Týká se to celého instalační processu? Ok, to ale neznamená že je to v pořádku.
Jak bych si to představoval? Asi nějak tak, že přestaneš tvrdit blbiny ad absurdum co kde kdo řekl a že to Velký Vizionář vyřeší, když už píše nový linuxový desktop ;-)
A nějak prakticky? Třeba že services rozdělí na systémové a ostatní a pro přidání do rootvských to budeš muset schválit ručně při instalaci, při změně . . . Může to být podle uživatelů kteří to mohou modifikovat a pouštět default, možností je víc, buď přes nějaký "kontroler" nebo právama na složky . . . Tím, že se budeš ostatním vysmívat a tvrdit že se nic neděje se to určitě nevyřeší. A stejně na to jednou dojde, když už má být systemd ta budoucnost lin. desktopu . . .
Balíčkovací systémy zpravidla nepřepisují uživatelsky změněné konfigurační soubory. Takže unita která má nastavená nižší práva šmahem nezíská vyšší.
Abys ovšem tohle mohl využít přes balíčkovač jako bezpečnostní chybu, musel bys přepsat celou service, změnit unit file… Prostě, přes podvržený balíček lze získat práva roota podstatně snazsším způsobem než takhle (navíc je to podstatně nápadnější)
Navíc se to NIJAK netýká této chyby a přes sysv init / upstart / bsd init jde udělat to samé.
"zpravidla" - to je něco mezi možná a asi, nebo kam to tak zařadit?
Proč bys musel měnit celou service? Stačí ti jeden řádek v *.service. No možná se to netýká, já taky nepsal že ano, této chyby, ale manažer služeb by asi měl řešit práva, pod kterýma to má běžet. Možná by tam sehrál roli ten fallback na roota . ..
V SELinuxu se toho dá nastavit dost a dá se tam taky nastavit, které položky který program může modifikovat a které ne a kam daný program nesmí. Já to používal akorát na Centosu pro Mailing a pro Apache, resp. httpd. Proto jsem taky psal "ale to už jenom tipuji a záleželo by i na nastevení."
Ne, aktualizace, ve které je ten unit file, může pocházet zvenčí a pod rootem na tvým stroji proběhne apt / dnf, pod rootem jede systemd. Ale to neznamená, že pod rootem musí jet to, co systemd spustí. A neznamená to, že roota na tvým stroji musí mít i ten, kdo ten řádek do souboru napsal...
A pokud budu mít balíček ze dvou dister, používajícich stejný balíčkovací systém, kde jedno akceptuje čísla na začátku user name a druhý ne, tak si nevědomky na tom striktnějším můžeš eskalovat práva. Jestli tohle není o bezpečnosti, tak co sakra o té bezpečnosti je?
Když se ta jedna distribuce rozhodne opatchovat systemd a místo volby User bude používat Usr, je to ten samý problém. Tohle je prostě obecně neřešitelný problém, systemd se to ve skutečnosti vůbec nijak netýká, a kde kdo se do toho strefuje jenom proto, že to někdo spojil se systemd a strefovat se do systemd je módní.
Patr M., NULL: Ve skutečnosti se tím akorát vyvalila obrovská neznalost, která panuje mezi „správci“. Několik lidí tady bez uzardění píše o tom, že je pro ně ohromné překvapení, že když spustí instalaci nějakého balíku pod rootem, provede se pod rootem cokoli, co je součástí instalace toho balíčku. To jste doteď nevěděli, že každý instalační balíček má možnost připojit skripty, které se provedou před instalací balíčku a po jeho instalaci (a jiné před a po odinstalaci)? Debianí balíčky mají preinst a postinst skripty, RPM mají skriptlety, ebuildy mají sekce pkg_preinst a pkg_postinst (a celý ebuild je shellový skript), ostatní balíčkovací systémy mají nepochybně něco podobného. Systemd s tím vůbec nijak nesouvisí, když budete mít špatně udělaný balíček, spustí vám pod rootem při instalaci balíčku nečekaný kód klidně na Devuanu. Mimochodem, ty pre- a post-instalační skripty se používají mimo jiné právě proto, aby zkontrolovaly podmínky nutné pro používání toho balíčku, takže například právě založí toho uživatele, kterého daná služba používá.
Nechtěli byste si místo kritizování něčeho, čemu nerozumíte, radši nastudovat základy správy balíčků?
Ten problém řešitelný je. Prostě directiva User bude poviná a hotové.
To víš že to vím, určitě i Petr M, ale tady snad ten Vizionář to měl konečně udělat správně ne? Hraje si na spásu v podobě system managera a jenom tam dává další díry, protože dřív jsi musel při restartu služby toto udělat s rootem a nemohl nikdo jiný. Dnes ti systemd toho roota klidně půjčí. Paráda.
A hned by spousta lidí na Rootu začala řvát, že je to hrozné, že jejich SysVinit skripty nic takového nemají a normálně se spouští pod rootem.
Nedělej ze sebe idiota. Ano, rc skripty jako takové možná běží pod rootem, ale když si tam admin dá:
# su -c 'id' 0kokotlennart
uid=1006(0kokotlennart) gid=1006(0kokotlennart) groups=1006(0kokotlennart)
tak to prostě jede.
(A ne, fakt už podruhé nemusíš psát absurdnost s tím, co se stane když tam admin zapomene dát to username. User=0kokotlennart v systemd danou věc spustí jako root, su 0kokotlennart pod existujícím uživatelem nebo vůbec, pokud user neexistuje.)
Jul 04 10:58:03 raid systemd[1]: /etc/systemd/system/t.service:3: Invalid user/group name or numeric ID, ignoring: 0kokotlennart
Jul 04 10:58:03 raid systemd[1]: Starting t.service...
Jul 04 10:58:03 raid id[8748]: uid=0(root) gid=0(root) groups=0(root)
Jul 04 10:58:03 raid systemd[1]: Started t.service.
Ale klidně si to tom napiš další referát, jak je to vlastně správně...
JE to KRETÉN. Root něco nainstaluje, to si vytvoří uživatele 0LPjedebil a pod tímto uživatelem se to spustí. Opravdu je potřeba kontrolovat každou kravinu, jak se chová ve skutečnosti, když je nastavená jinak? Co všechno si má admin zkontrolovat? Protože pokud nad každou takovou kravinou mávneme rukou, nakonec budeme muset kontrolovat úplně všechno, včetně zdrojáků, protože "root má být uvědomělý". No jestli ono nebude nakonec jednodušší, napsat si vlastní systém, ne?
Ono je potřeba si uvědomit rozdíly mezi chybama. Chyba může být za určitých okolností ignorována a děje se tak zcela běžně, ale nemůžu něco pustit jako root, když mi konfigurák tvrdí něco jinýho, třeba nesmyslnýho. Když se přihlásím do systému jako neexistující uživatel 0hacker s nečekaně chybným (neexistujícím) heslem, má mně systém přihlásit jako roota, nebo mě má poslat do Lenarta?
Opravdu je potřeba kontrolovat každou kravinu, jak se chová ve skutečnosti, když je nastavená jinak?
Zkontrolovat si konfig po každé změně je nanejvýš vhodné u každého software. Většina software na to má nějaký nástroj.
Druhá otázka je, jak by se měl software při chybě chovat. Podle některých lidí i zde v diskusi je možné řádek s divnou hodnotou ignorovat. K čemu to potom vede jsem demonstroval na příkladu MySQL. Tam ignorování ze strany software vedlo až k poškození dat.
Tzn. chyba by nikdy neměla vést k horšímu stavu. Pokud admin zadá (v tomto případě) User a toto není možné z libovolného důvodu provést, není možné mít jako fallback roota. Kdyby byl fallback nobody, tak se o tom ani nebavíme. Default má být bezpečný. Osobně preferuji variantu, že software s vadným konfigurákem vůbec nenaběhne. V případě systemd by se dalá unita mohla prostě ignorovat jako celek.
2MP: Ono je hlavne mnohem jednodussi nepouzivat distra se zhuverilosti systemd.
2Heron: A jak prosimte pri kontrole konfiguraku zjistis, ze ta naprosto jasna konfigurace, ktera naprosto jasne rika, ze si prejes pustit neco pod existujicim uzivatelem 0kokotlennart ... to ve skutecnosti spusti pod rootem? Takze budes pri kazdy aktualizaci procitat zdrojaky a zkoumat u kazdy jedny konfiguracni volby, jestli zrovna tvoji variantu ne pochopi jinak nez bys cekal?
Jinak v pripade systemovych veci je s deseti otaznikama i ignorovani nevalidniho nazvu parametru. Spousta daleko min podstatnych veci te vyfuckuje i s tim.
A jak prosimte pri kontrole konfiguraku zjistis, ze ta naprosto jasna konfigurace, ktera naprosto jasne rika, ze si prejes pustit neco pod existujicim uzivatelem 0kokotlennart ... to ve skutecnosti spusti pod rootem?
Kontrola konfiguráku:
# systemd-analyze verify t.service
/etc/systemd/system/./t.service:3: Invalid user/group name or numeric ID, ignoring: 0kokotlennart
To, že to ten řádek ignoruje a spustí pod rootem je samozřejmě špatně, ale o tom už tady diskutujeme druhý den, to nemusím opakovat.
Další je je samozřejmně to, že toho uživatele můžu v systému mít (useradd to nekontroluje, případně si to napíšu přímo do passwd nebo do ldapu) a přes to pod ním nelze spustit službu přes systemd.
Chápu, že podle tebe by v případě chybné syntaxe User neměl systemd vypisovat varování, ale rovnou chybu a spouštění jednotky přerušit. Má to být jedna jediná volba, která má mít takovéhle speciální zacházení? Nebo kterých dalších voleb se to má týkat? Nebo budeme čekat, až zase někdo vymyslí nějaký nesmysl a zadá to na GitHubu jako issue, a takhle budeme budovat ad-hoc seznam voleb, které mají speciální zacházení?
chybné syntaxe
Tohle je nádherná ukázka absurdity, do které se tato diskuse stočila.
Pro mě o žádnou syntaxe nejde.
User= pro mě znamená nastavení konfigurační hodnoty na string, který je za tím znakem =.
To, že pro někoho přišlo jako geniální nápad odhadovat, zda ta věc za tím '=' je číslo nebo řetězec a podle toho určit, zda se jedná o UID nebo o UserName, je podle mě zásadní chyba. Chyba návrhu. Tohle má být oddělené.
Jenže někdo si řekl, že hodnota nebude hodnota, ale že se bude aktivně parsrovat (viz šaškárna s ExecStart, když první argument už není plná cesta k binárce, ale někomu přišlo hrozně fajn tam narvat další znaky (které v absolutní cestě nemají co dělat), takže se bude odhadovat co je cesta, co není cesta a co je řídící znak, místo toho, aby určilo jiným parametrem (viz navrhovaný ExecMod), jak přesně se bude s daným příkazem zacházet.
Mimochodem, krásná ukázka toho, co se stane, když software odhaduje datový typ a použije nesprávný:
var_dump(md5('240610708'));
var_dump(md5('QNKCDZO'));
var_dump(md5('240610708') == md5('QNKCDZO'));
string(32) "0e462097431906509019562988736854"
string(32) "0e830400451993494058024219903391"
bool(true)
Funkce MD5 vrací 128b číslo, toto číslo je převedeno na nějaký string, dva stringy jsou porovnávané, porovnávátko odhadne, že jde o float, float je moc velký, nevejde se, tak to ořeže a výsledkem porovnání je true... (A fakt nepiště, co všechno je tam špatně a jak to udělat lépe, na to to téma už se popsalo stovky stránek jinde.)
S automatickým odhadem (většinou samozřejmě špatným) datového typu je vůbec super sranda. Tuhle jsem něco importovat do Calcu. Další nepoužitelný software.
Tomáš Crhonek, 11:23: Za prvé, to, že se pro uživatelské jméno a UID používá jedna položka, je naprosto běžné. Podobně jako se třeba používá jedna položka pro zadání hostname nebo IP adresy. Za druhé, ten problém spočívá v něčem úplně jiném. Problém je v tom, že systemd má omezenou množinu hodnot, které považuje za validní vstup pro User, a když tam někdo zadá hodnotu mimo tuto množinu, vyhodnotí systemd celou volbu User jako nevalidní a ignoruje jí.
Na tom, že tenhle formát konfiguračních souborů, kdy se před hodnoty přidávají různé znaky a tím se mění jejich význam, se shodneme. Ale ten formát je takhle zvolený, a za mnohem horší bych považoval dělat nějakou nesystémovou výjimku pro jednu volbu. Pokud už by se na tom mělo něco změnit, ať se změní typ volby User, ať je to libovolný text (třeba jako Description), a validita ať se posuzuje až za běhu podle toho, zda na daném systém daný uživatel skutečně existuje. Sice se tím rozbije statická analýza, protože User=@#!$ projde syntaktickou validací bez problémů, ale správci, kteří píšou do jednotkových souborů náhodné údaje a doufají, že to bude dělat to, co chtějí, budou spokojeni.
Naprosto běžný je, že někteří diskutující tady to mají trochu otočený.
Třeba jeden, co minulý týden zuřil, když registrátor u domény vezme z DNS bezpečnostní údaje, který se týden nezměnily a mají být dle definice propagovány, a začne je propagovat. Prý to vede k hypotetické chybě, ale popsat zneužitelnost neumí. A tady, kde je evidentní, že odladím něco na systému, který nepodporuje číslo jako první znak username, přenesu to na systém, který to podporuje (třeba s pomocí LDAP) a ono to samo eskaluje práva, tak se do roztrhání bije za to, že je to správně, protože to tak někdo definoval. Zvláštní to jedinec.
A že je něco běžný neznamená, že je to ta nejlepší alternativa. Třeba běžně používaný IPv4 pro připojení různých embedded věcí, co se pak nevidí skrz NATy a při vypnutí serveru dodavatele je z nich cihla.
A pokud mají být v konfiguráku atributy, je lepší použít třeba XML a tyhle modifikátory hodit jako atribut tagu. A sorry, rozpoznání XML od jinýho souboru je přece triviální věc, takže nevidím důvod, proč by třeba rok nemělo jít používat oba formáty.
Kdo chce, hledá způsoby, kdo ne, hledá důvody.
Petr M, 12:34: Zneužitelnost jsem popsal. Pokud něco odladíte na systému, který číslici na prvním místě username nepodporuje, máte v username v tom jednotkovém souboru username, které začíná písmenem. Když to přenesete na jiný systém, systemd to bude stále vyhodnocovat jako platnou syntaxi, a pak bude záležet jenom na tom, zda daný účet na systému existuje nebo neexistuje. Zkuste příště vymyslet nějaký příklad, kde dojde k nějakému problému. A mimochodem, pokud jednotkový soubor nevzniká v rámci instalace nějakého balíčku, který i vytvoří příslušného uživatele, ale ten jednotkový soubor jenom přenášíte mezi systémy, a ani si nezkontrolujete, zda zadaný arbitrární uživatel na cílovém systému existuje, je to vaše chyba. A představte si, že úplně stejně to funguje třeba s cestama ke spustitelným souborů. Vytvoříte jednotkový soubor na jednom systému, zadáte tam cestu k existujícímu programu, pak jednotkový soubor přenesete na jiný systém, kde ta cesta neexistuje – a představte si to, systemd má takovou drzost, že tu jednotku nespustí.
V tom, že XML formát by byl pro tyhle konfigurační soubory daleko lepší, se shodneme. Předpokládám, že spousta ostatních diskutujících bude mít za to, že XML je to poslední, co systemd ještě chybí, aby to byl ten úplně nejhorší software v celém univerzu.
Budování ad-hoc seznamu voleb, které mají speciální zacházení, je špatně. Na tom se shodneme. Momentálně ten seznam roste. Jak píše tato zprávička, přibyla tam položka "systemd neumí spustit jednotku pod uživatelem, jehož username začíná číslicí".
Jen nějak nechápu, proč vaše reakce formulujete tak, jako že vám ten seznam vadí, ale sám do něj nutíte další položku.
Systemd má prostě tři možnosti:
- prosadit do Linuxu podmínku, aby username nemohlo začínat číslicí
- upravit svůj program tak, aby akceptoval pravidlo Linuxu, že username může začínat číslicí
- připsat na seznam výjimek položku "Linux sice dovoluje, aby username začínalo číslicí, ale Systemd s tím neumí pracovat ve volbě User"
Karel 11:25: Ne, seznam položek jednotkových souborů, které mají speciální zacházení, je stále prázdný.
Systemd umí spustit jednotku pod uživatelem, jehož jméno začíná číslicí, akorát takového uživatele musíte zadat pomocí UID. Jediná skutečná chyba je to, že syntaxe volby User není zdokumentovaná. To, že některé hodnoty nejde do jednotkového souboru zadat jednoduše, je normální – třeba cestu k souboru, která obsahuje mezeru, tam taky nevložíte tak, že jednoduše cestu i s mezerou zkopírujete a vložíte.
upravit svůj program tak, aby akceptoval pravidlo Linuxu, že username může začínat číslicí
A pak přijde někdo, kdo si do /etc/passwd dá jako username kus programu v Perlu, a bude se to opakovat celé znova.
@Filip Jirsák:
Očekával bych, že to bude podporovat alespoň POSIX, jako všechny ostatní nástroje:
3.278 Portable Filename Character Set
The set of characters from which portable filenames are constructed.
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -
3.431 User Name
A string that is used to identify a user; see also User Database. To be portable across systems conforming to POSIX.1-2008, the value is composed of characters from the portable filename character set. The <hyphen> character should not be used as the first character of a portable user name.
Skutečná chyba?
1) Nedokumentovaný chování volby user=
2) Volba user= není jednoznačná - existuje-li minimálně jeden systém, kde user name může být číslo a současně se to číslo neshoduje s uid, systém nemůže uhodnout, co ten string reprezentuje.
3) Parsuje se string, kde nejsou jenom číslice, jako integer
4) V situaci, kdy je evidentní, že něco nemá být spuštěno pod rootem (definováno user= a za rovnítkem není root - evidentně kvůli omezení práv a pro to je vždycky dobrý důvod) se služba spustí jako root bez omezení
5) Neexistuje bezpečný default pro user= nebo povinnost explicitně specifikovat uživatele.
6) systemd má na starost někdo, kdo když se dával rozum, šel si potřetí stoupnout do fronty pro aroganci (podruhý to bylo, když se rozdávala empatie).
Takze znova hovadko, copak asi tak udelas, kdyz ten (podle tebe blbej admin) napise servise, ze se ma spustit pod userem 123franta ... a ten user v systemu normalne existuje a da se na nej prihlasit. ... Jo aha, kreten jako ty to pusti pod rootem, protoze to je prece logicky zejo ...
Nj, to je tak, kdyz je nekdo dement jako ty ...
A ještě jednou:
Kdo to říká,
ten to je,
na toho to
pasuje
Když mi řeknou, že se to má spustit pod uživatelem 123franta, tak jim řeknu, že vlastnost systému je, že to nejde, jinak se to spustí pod rootem a doporučím jim použít jinou distribuci, pokud na tomto požadavku trvají. Předpokládám, že by na tom netrvali. :-)
Někdo hledá problémy a jiní hledají cestu.
Zásada defenzivního programování:
Pokud máš možnost, aby tě kompilátor nepustil dál při chybě, využij ji.
Obdobně, zásada defenzivní administrace by měla být:
Pokud máš možnost, aby se systém nespustil dál při chybě, využij ji
Jak vidím, systemd jde proti téhle logice. Chyba tam je, dokonce detekovaná, ale odbude se (někdy) warningem a jede se dál. Lennart je prostě superman, nedělá chyby a podle sebe soudí ostatní.
Ne, mělo by to fungovat:
1 - Hodnotu USER parsovat jako int
2 - Byl to int - použít to jako UID
3 - Nebyl to int - použít to jako jako username
4 - (rezerva, pokud username má nějakou zvláštní syntax, použije se zvláštním způsobem, to bude implementováno v budoucnosti, nyní jen goto 5)
5 - UID nebo username je platný - použít ho
6 - UID ani username nejsou platné - ERROR
Nj, ale to by se nikdy nepouzil ten uzasnej default s rootem .... ;D. A navic by to zcela jiste bylo pomaly ...
Takze spravnej soudruh to v ramci plneni na 130% .... udela nasledovne ...
1) nastartuj servisu pod rootem
2) zjisti, jestli nahodou neni v konfiguraci neco co umis
3) kdyz tam nahodou je, hod si kostkou (= libovolnym, ale hlavne rychlym zpusobem vyber jestli se ti libi nebo ne)
4) kdyz se ti libi prehod provoz na nej
Vidis, a sem i o 2 kroky rychlejsi nez ty ...;D
Netřeba vymýšlet kolo, když coreutils ( chown, setfacl, …) to už dávno řeší. Hodnota se použije jako username, a pokud takový uživatel neexistuje, tak se zkusí použít jako UID. UID lze vynutit tak, že se před číslo napíše plus (+), protože to stále lze parsovat jako číslo pomocí strtol a username jej nemůže obsahovat.