Vlákno názorů k článku Web server Nginx bez práv roota s pomocí systemd od Jan Molič - Jde to i bez systemd, s využitím commandline...

  • Článek je starý, nové názory již nelze přidávat.
  • 17. 6. 2020 23:38

    Jan Molič

    Jde to i bez systemd, s využitím commandline utility capsh:

    jako root spusťte:

    /usr/sbin/capsh --keep=1 --user=www-data \
       --inh=cap_net_bind_service \
       --addamb=cap_net_bind_service \
       --caps=cap_net_bind_service+eip \
       -- -c 'python3 -m http.server 80'

    výsledek:

    Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

    v processlistu vidíte, že pythoní http server je spuštěn jako www-data a přitom poslouchá na portu 80:

    root      18567  0.1  0.0  14480  6036 pts/5    S+   23:33   0:00      \_ /usr/sbin/capsh --keep=1 --user=mig --inh=cap_net_bind_service --addamb=cap_net_bind_service --caps=cap_net_bind_service+eip -- -c python3 -m http.server 80
    www-data  18568  1.1  0.1  24044 16876 pts/5    S+   23:33   0:00          \_ python3 -m http.server 80
  • 18. 6. 2020 12:54

    Jan Molič

    Například tehdy, když používáte runit nebo jiný init než systemd. Je fajn, že existuje utilita (capsh), která konečně podporuje ambient caps. Dřív se kvůli tomu musela kompilovat vlastní binárka s libcap-ng. Přijde mi špatné, pokud pro základní vlastnosti systému neexistuje commandline utilita.

  • 18. 6. 2020 14:37

    Filip Jirsák
    Stříbrný podporovatel

    Proč ty jiná init systémy práci s capabilities nepodporují rovnou? Pak to jejich uživatelé nebudou moc používat (když si to musí ubastlit sami), a pak radši tu aplikaci nechají běžet pod rootem…

  • 18. 6. 2020 14:50

    Miroslav Šilhavý

    Proč ty jiná init systémy práci s capabilities nepodporují rovnou?

    Na to je jednoduchá odpověď. Pro ty druhé init systémy existují někdy technické důvody (některá zařízení), ale na velkých systémech je to jen kvůli tomu, že jsou adminové líní se učit moderní systemd. Ze stejného důvodu nevyužijí ani capabilities, SELinux, ... (Prosím omluvte mě vy, co to děláte jinak, vím, že všude jsou výjimky a je nebezpečné generalizovat)

  • 19. 6. 2020 1:02

    klokan

    Myslím, že u těch, na které narážíte, nejde jen o lenost, ale i o jakousi ideologii. Jejich představa komunity je model "bazaar" dovedený do extrému, kde si každý bastlí sám na "svém stroji" a admini si vzájemně vyměňují různé pochybné skripty. Stačí si přečíst https://www.infoworld.com/article/2623488/nine-traits-of-the-veteran-unix-admin.html. Ostatně zdaleka nejde jen o systemd, totéž platí o waylandu, dbusu ale i o programovacích jazycích (rust, D atd). Základní klišé je "prosím, budiž, stávající technologie má své problémy, ale ta nová technologie je špatná, protože to říkám, a mnohem slibnější mi připadá ${něčí obskurní hobby projekt}" - sami přitom pochopitelně nevyvíjejí a nenavrhují nic.

  • 19. 6. 2020 9:11

    Ivan Brezina

    Tyhle nove projekty bohuzel narostly do takovych rozmeru, ze jejich dalsi rozvoj je nedemokraticky, nesvobodny, nelogicky ... Tezko rict jak to pojmenovat.

    Napr ansible ma ve fronte 1.6K pull requestu a 19K forku. A ti lide uz ani necekaji ze se ten pull request aplikuje. A presto ma trunk Ansible takovy fatalni bugy, jako ze treba neumi namontovat NFS.

    Podobne jsem resil proc nemuzu nastavit v Ubuntu rychlost scrolovani koleckem mysi. Jediny co jsem zjistil, ze kazdej kdo neco takovyho chce je kreten a ze takovy pozadavek je ideologicky spatne a Xinput, dbus ani jinyho to resit nebude.

    Me treba visi ve fronte pres pul roku pull request na hibernate a to jsem v mikroskupine lidi ktera takovou vec chce. A presto neni sance prosadit vlastni napad proti lidem kteri maji commit prava a konzultacemi na hibernate se zivi.

    Nakonec je z toho uplne stejna bezmoc, jako z komercniho SW.

  • 19. 6. 2020 9:18

    Petr Krčmář

    Jenže vy máte špatná očekávání. Přistupujete ke svobodnému software šířenému zdarma, jako byste byl zákazníkem komerční firmy. Tedy že si řeknete a oni to pro vás udělají. Jenže tihle vývojáři neplní vaše přání, ale řeší svoje problémy tak, jak to vyhovuje jim.

    Tady nejsou žádní oni, kteří musí dělat, jak zákazník řekne. Pokud to chcete jinak, musíte si to naprogramovat sám a pak buď poslat pull request nebo si udržovat vlastní patche. Takhle to prostě je, kdo založí projekt, ten je jeho pánem a jinak to ani být nemůže. Zároveň ale ten svobodný svět umožňuje dělat si to vedle po svém a třeba udělat veřejný fork. To je ta hlavní výhoda proti proprietárnímu software.

  • 19. 6. 2020 10:07

    klokan

    Případá mi, že to je vlastně naopak. To, že tohle jsou svobodné projekty, nic nemění na tom, že to jsou zároveň komerční produkty vyvíjené firmami ve stylu "katedrála". Stejně jako jinde rozhodují peníze, nebo případně přispívání formou kódu, sponsoringu atd. Kdo platí vývoj, ten si může klást požadavky. Kdo se chce jenom vézt zadarmo, ten je v pohodě, má na to plné právo a nic proti tomu, ale nemůže si zároveň dělat nároky na to, čemu mají upstream vývojáři - placení zaměstnanci - věnovat čas, který financuje někdo jiný.

  • 19. 6. 2020 15:02

    Jan Molič

    To je ale přesně příklad dalšího klišé, že všichni oldschooloví admini odmítají všechno nové. Tak třeba na kompu mám wayland. V rustu občas programuji a je myslím líp navržen než C. Zároveň ale používám "zbastlený" runit. Totiž jak runit, tak wayland používám ze stejného důvodu: mají dobrý návrh. Nebráním se ničemu novému, pokud toto nové je dobře navržené. Bohužel, spousta toho "nového" dneska ale zdaleka _nemá_ dobrý návrh.

    19. 6. 2020, 15:02 editováno autorem komentáře

  • 19. 6. 2020 17:59

    Filip Jirsák
    Stříbrný podporovatel

    Pokud má runit dobrý návrh, neměl by přece být problém doplnit do něj konfiguraci capabilities, cgroups apod. Pokud je to snadné, proč to ještě nikdo neudělal? Také je možné, že to má dobrý návrh, ale pro jinou dobu…

  • 20. 6. 2020 14:27

    Jan Molič

    Není potřeba do runitu nic doplňovat. To je právě ten dobrý design, že v určité verzi se software již nemění, protože to není potřeba. Runit dělá svou práci a dělá ji dobře. Nemusí integrovat dhcpd, udevd ani capsh, protože pro tyto účely existují externí utility. Služba v runitu je spustitelný soubor a co do něj vložíte, je na vás. Může vypadat třeba takhle:

    #!/bin/sh
    exec cap_net_bind_service nginx -g "daemon off;" 2>&1

    Nemyslím si, že je to málo user friendly. Ten skript "cat_net_bind_ser­vice" si však musíte zbastlit sami. A proč to nikdo neudělal? To já nevím. Asi že to nepotřeboval nebo že to považuje za nadbytečné, publikovat nějaké wrappery, které dělají pouze specifickou funkci, kterou někdo jiný nemusí přesně tak chtít. To by pak totiž mohlo vést k existenci tisíců wrapperů.

    Myslím si, že přínos systemd spočívá jen a pouze v tom, že se stal de facto standardem, který je user friendly. To je důvod, proč se ho Poetteringovi podařilo komunitě prodat. Obal prodává, známá věc. A je blbostí tvůrců těch ostatních init systémů, že tehdy nedovedli udělat pro své systémy lepší UX design, nebo že na to úplně kašlali.

    Osobně runit používám i v produkci a spokojenost je letitá. Ano, doba se změnila a z dnešního pohledu jsem "bastlič". Dokonce už bych se za to snad měl i stydět, mám takový pocit. Jenže právě ono "bastlení" je na tom IT ještě aspoň nějaká zábava, jinak se z toho stává otravná standardní dělničina (osobní pohled na věc :))

  • 20. 6. 2020 15:07

    Jan Molič

    Jo a ještě jedna věc, aby se to konkretizovalo. Takhle to používám na produkci s runitem. Jediný rozdíl je, že mi nginx běží pod userem "http".

    /service/nginx/run:

    #!/bin/sh
    mkdir -p /run/nginx
    chown http:http /run/nginx
    exec /usr/local/bin/cap_net_bind_service http /usr/sbin/nginx 2>&1

    /usr/local/bin/cap_­net_bind_servi­ce:

    #!/bin/sh
    
    [ -z "$1" -o -z "$2" ] && { echo "$0 USER COMMAND"; exit 1; }
    
    exec /usr/sbin/capsh --keep=1 --user=$1 \
       --inh=cap_net_bind_service \
       --addamb=cap_net_bind_service \
       --caps=cap_net_bind_service+eip \
       -- -c "$2"

    a v konfiguraci nginx.conf jsou podstatné tyhle věci:

    daemon off;
    user http;
    pid /run/nginx/nginx.pid;

    výstup ps faux | grep nginx:

    root      1555  0.0  0.0   2200  1084 ?        Ss   Jun01   0:00  \_ runsv nginx
    root      1668  0.0  0.0   2356   680 ?        S    Jun01   0:00  |   \_ logger -p daemon info -t nginx
    http     26481  0.6  0.4 167556 71960 ?        S    15:06   0:00  |   \_ nginx: master process /usr/sbin/nginx
    http     26497  1.3  0.1 242252 18272 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26499  0.0  0.1 241540 17712 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26501  0.0  0.0 241292 14736 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26502  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26503  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26504  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26505  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26506  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: worker process
    http     26507  0.0  0.0 241292 15216 ?        Sl   15:06   0:00  |       \_ nginx: cache manager process
    http     26508  0.0  0.0 241292 14764 ?        Sl   15:06   0:00  |       \_ nginx: cache loader process
  • 20. 6. 2020 15:54

    Filip Jirsák
    Stříbrný podporovatel

    V tomhle se neshodneme. Výsledkem to, že se reálně služba zbytečně spouští s právy roota, přestože by jí stačila capability pro naslouchání na nízkém portu. O takovém správci služeb nemůžu říct, že dělá svou práci dobře. Nezáleží na tom, že administrátor má tu možnost, záleží na tom, jestli to v praxi používá.

    Myslím si, že přínos systemd spočívá jen a pouze v tom, že se stal de facto standardem, který je user friendly.
    Pokud bych měl systemd něco vytýkat, na první místě by bylo to, že není moc user friendly. Podle mne jeho přínos spočívá v tom, že dal konečně správcům do rukou jeden nástroj, ve kterém mohou nakonfigurovat vše potřebné. Nemusí si pro všechno psát své vlastní skripty.

    Ano, doba se změnila a z dnešního pohledu jsem "bastlič".
    Pokud někdo bastlením dojde k profi výsledku, nic proti tomu nemám. Jenže tady se obávám, že už se to projevuje i na kvalitě výsledku – např. že se služba spouští se zbytečně silnými právy.

  • 19. 6. 2020 14:26

    Jan Molič

    Unixová filozofie říká, že na každou věc by měl existovat zvláštní program, který tu věc dělá dobře. Init má spouštět služby, ale zbytek může řešit řada dalších nástrojů. Přesně tak funguje runit.

    Že ty další jednotlivé nástroje nejsou kolikrát jednoduché na použití? To souhlasím. Třeba právě <i>capsh</i> není pro neznalého člověka vůbec pochopitelný, oproti jednomu řádku v konfiguraci systemd. A tak systemd válcuje všechno, protože je user friendly.

    Jenže systemd vyžaduje specifické prostředí k běhu. Jestliže pracujete v nějakém nestandardním prostředí, například po pádu systému se vám povedlo dostat se na disk a zachrootovat se tam, pak je fajn, že tam máte oddělené nástroje, pomocí nichž třeba nahodíte síť nebo provizorně spustíte konkrétní službu.

    Bohužel, Linux se té unixové filozofii čím dál víc vzdaluje. Spousta lidí se dnes zase ptá, "proč používáš runit, když všichni ostatní používají systemd?" -> jenže to je úplně stejná otázka jako v roce 2000, kdy se mi všichni smáli, že tam mám linux, zatímco všichni ostatní přece používají windows.

  • 20. 6. 2020 0:29

    klokan

    To je stokrát debatovaný argument. Realita je, že nikdo nemá jako požadavek u OS nebo aplikace, aby splňovala "unixovou filozofii". Každý má požadavek, aby byla spolehlivá, výkonná, bezpečná a snadno použitelná. No a protože je empiricky prokázané, že "unixová filozofie" tyto reálné požadavky nejen nesplňuje, ale naopak každému z nich radikálně brání (*), a protože linuxová komunita má zájem uspět a nadále se rozvíjet v reálném světě s reálnými uživateli, kteří mají reálné požadavky, tak celkem pochopitelně komunita tuto filozofii sice pozdě, ale zaplaťpámbu konečně opouští.

    (*) očekávám vehementní reakce, tak už předem nabízím pár příkladů. Proč jsou SMTP servery (postfix, sendmail etc.) mrtvé a všude se používá MS Exchange? Proč všude tam, kde je potřeba administrovat větší počet stanic na dálku, se automaticky nasazuje Windows a Active Directory? Proč je projekt systemd tak úspěšný, a to i přesto, že (na rozdíl od mnohokrát opakovaného mýtu) RedHat o něj zpočátku neměl zájem, a Canonical už vůbec ne? Proč vývojáři aplikací zásadně volí vše zahrnující frameworky, jako Qt, .NET atd. místo milionu malých, nezávislých knihoven z nichž každá dělá "jednu věc"? Proč jsou tak úspěšné služby, jako je AWS a Azure, kde je veškerá správa serverů soustředěna do jediného webového nástroje?

  • 20. 6. 2020 8:15

    Filip Jirsák
    Stříbrný podporovatel

    Unixová filozofie je takový univerzální klacek, který můžete použít na cokoli – když chcete systemd kritizovat i když ho chcete hájit. Například se samozřejmě můžeme dohadovat o tom, co má dělat správný init. Má jenom spouštět služby? Nebo má také monitorovat jejich běh? Nemá před jejich spuštěním také správně nakonfigurovat jejich prostředí?

    Bohužel, Linux se té unixové filozofii čím dál víc vzdaluje.
    Jak už jsem psal, unixová filozofie je dost gumový pojem, takže těžko hodnotit, zda se Linux vzdaluje. Ale hlavně, unixová filozofie je popis řešení, ne jeho hodnocení. Takže i kdyby se tomu linux vzdaloval, neznamená to nutně, že je to špatně.

    Spousta lidí se dnes zase ptá, "proč používáš runit, když všichni ostatní používají systemd?" -> jenže to je úplně stejná otázka jako v roce 2000, kdy se mi všichni smáli, že tam mám linux, zatímco všichni ostatní přece používají windows.
    unit, systemd, Linux i Windows mají své způsoby užití. Smát se (nebo ho spíš litovat) můžete někomu, kdo používá něco, i když by jiný nástroj byl vhodnější.

    Mne by spíš zajímalo, jestli ty nástroje spolu s runitem opravdu používáte. Nastavujete limity, capability, spouštíte služby pod neprivilegovaným uživatelem?

  • 18. 6. 2020 20:16

    Ondra Satai Nekola
    Zlatý podporovatel

    Rekneme to takhle - mam Arch. Mam ho rad (I use Arch, btw). Na server bych si ho nedal ani za karton rakouskeho veltlinu.

    Vetsina produkce bezi RH/Centos/Oracle, Debian a Ubuntu (vynechal jsem neco?). Ze maji nejaka obskurni distra pouzivana na par serverech nejake obskurni inity je dost nezajimave.

  • 19. 6. 2020 1:05

    klokan

    Upřímně řečeno, i ten Debian byste možná mohl vynechat. Jakkoli je to důležité a významné distro, komerční software třetích stran ho většinou nepodporuje a na produkční nasazení, kde se požaduje zaručená podpora, hardwarová certifikace atd se fakt nehodí.

  • 19. 6. 2020 14:29

    JVr

    Jde jen o úhel pohledu.

    Gentoo je jedno z neohebnějších dister, které najdete a z toho důvodu má neúplně bezvýznamné místo v emeded segmentu. Obecně on systemd je pro embeded nevhodný svojí "nabobtnalostí" proto se volí OpenRC. No a na těch embeded zařízeních je dnes celkem časté, že umožňují vzdálenou správu, a to na bázi nějakého toho webserveru. A tam by právě toto mohlo mít smysl ne?
    Možná to není pak server vystavený do světa s X miliony požadavků za vteřinu, ale víme, jak to je... občas se i takový webserver do světa kouká a každý krok ke zvýšení bezpečnosti se hodí ne?

  • 19. 6. 2020 14:46

    Filip Jirsák
    Stříbrný podporovatel

    Obecně on systemd je pro embeded nevhodný svojí "nabobtnalostí" proto se volí OpenRC.
    Je to reálná obava? Nebylo by systemd nakonec srovnatelně malé a efektivnější, kdyby se nepoužíval celý projekt systemd, ale jen potřebné komponenty?

  • 19. 6. 2020 16:51

    JVr

    Pokud do byl dotaz na mne tak nevím. Jen jsem uváděl příklad a ten je z praxe. Co k tomu vedlo přesně nevím, ale předpokládám, že obecně šlo to, že pokud chcete systéme efektivně osekat o všechno co pro konkrétní účely není nutné, zavádí vám do systému systemd zbytečné množství dalších závislostí, kterých se nelze tak snadno zbavit jako je glibc, dbus a další.

    Ale to asi záleží na konkrétním usecase, nicméně já chtěl jen zmínit, že existuje usecase, ve kterém má smysl capabilities využívat k tomuto účelu i mimo systemd, nikoliv zde rozvádět falme o systemd.

  • 20. 6. 2020 14:42

    Jan Molič

    No a to je právě ono. Ty jednotlivé komponenty systemd se snaží využívat i ostatní init systémy, například vývojáři gentoo forkli elogind, který lze pak použít jak v openrc, tak v runitu. Dosud se podobně daří separovat udevd. Aspoň co však čtu na netu u autorů těhle forků, není to snadné.

    Přitom systemd interně sestává fakticky z oddělených komponent (á la postfix), takže by neměl být problém ho rozdělit. Ovšem to by byla situace jako předtím, kdy existoval samostatný udevd, dhcpcd a další. Rozdíl by byl v tom, že by všechny komponenty vycházely pod stejnou verzí s jedním maintainerem.

    Možná k tomuhle "rozbíjení monolitů na mikroslužby" to nakonec zase povede. A runit pak bude načítat konfiguraci ze standardizovaných ini souborů. Opravdu vidím ten hlavní přínos systemd jen a pouze v té standardizaci konfigurace, které nebyli tvůrci jiných init systémů schopni. Prostě někdy musí přijít někdo, bouchnout do stolu a říct, že to bude takhle, jinak se lidi nedomluví.

  • 20. 6. 2020 16:00

    Filip Jirsák
    Stříbrný podporovatel

    Ona to není jen standardizace konfigurace, k tomu by systemd nebyl potřeba (třeba konfiguraci sítě pomocí jednoho souboru řešila spousta distribucí). Podle mne je podstatnější to, že správce služeb ty služby skutečně řídí a vyměňují se tam informace. Že na zpřístupnění sítě mohou zareagovat služby, které síť naslouchají, a nastartovat se – například.

  • 21. 6. 2020 11:48

    Jan Molič

    To ano, na druhou stranu závislosti (startovat služby podle sítě třeba) uměly už i jiné inity. Žádné asi ale ne tak komplexně jako systemd. Řekl bych, že největším problémem okolo systemd je jeho interní implementace, čili onen přetížený proces č 1. Trochu nechápu, proč se v tomhle Poettering neinspiroval třeba v tom runitu. Princip supervize procesů univerzálním daemonem je geniální a přitom jednoduchá věc. Vůbec v tehdejších implementacích initů existovala řada skvělých nápadů, které by stačilo pospojovat dohromady. Takže očekávám, že se systemd bude zase předělávat a nakonec možná i krájet na "mikroslužby" a pak se třeba i znovuobjeví supervize procesů jako nová cool featura. A nebo by byla cesta, napsat zbrusu nový init, ovšem kompatibilní se systemd. Nedivil bych se, kdyby to udělal Linus :-)

  • 21. 6. 2020 16:20

    Filip Jirsák
    Stříbrný podporovatel

    Co je na systemd PID 1 přetíženého? Pokud vím, jedinou jeho úlohou je spustit správce služeb systemd.

    Systemd má ještě jednu vlastnost, na kterou se často zapomíná – ohromnou zpětnou kompatibilitu, kdy umí jednoduše spouštět všechny možné služby, které jsou různě ohackované kvůli starším špatným initům. Což je možná důvod, proč systemd uspěl. Doufám ale, že systemd splní ten úkol, že pročistí ekosystém, a pak bude moci přijít opravdový moderní init, který nebude muset být zatížen minulostí – i jeho implementace pak bude moci být hezčí.

  • 22. 6. 2020 0:59

    klokan

    Neznám detaily systemd ale pokud vím, tato zpětná kompatibilita není implementována v samotném systemd (a už vůbec ne v pid1), ale formou "generátorů", což jsou externí helpery. Takže u čistě moderní instalace, kde všechno funguje pomocí unitů (což asi ještě není úplně reálné) tato část vůbec nebude v obraze.

  • 22. 6. 2020 8:42

    Filip Jirsák
    Stříbrný podporovatel

    Spousta z toho je implementováno i přímo v systemd – např. volba Type=forkign. A takových voleb je v konfiguraci spousta.

  • 22. 6. 2020 9:02

    klokan

    To je pravda, ale na to by bylo nutné přepsat obrovské množství stávajícího software a to asi nikdy úplně nemigruje do jednoho. Podobné rovnáky na zpětnou kompatibilitu jsou všude, i v jádře (např dodnes existují fork() a sendfile() jako samostatné syscally) a je tomu tak všude, i ve Windows.

  • 20. 6. 2020 0:14

    klokan

    Řekl bych, že tohle je jeden z případů, kde by systemd byl naopak velmi užitečný. Když se systém spravuje na dálku přes web, tak by jistě bylo dobré, kdyby to webové rozhraní mohlo provádět administrativní operace pomocí API, a ne parsovat a přepisovat textové soubory a skripty a doufat, že to dopadne dobře...

    K té nabobtnalosti, to se sice občas uvádí jako argument proti systemd, ale zajímalo by mě, jak je to doopravdy. Žádná data nemám, pokud nějaká opravdová máte, prosím o odkaz, rád se podívám. Lidé, co tohle tvrdí (neříkám, že to je nutně zrovna váš případ) totiž zásadně porovnávají velikost a hardwarové nároky systemd vs init (nebo openrc, runit apod) aniž by vzali v úvahu, u klasickěho initu v jakékoli formě se pro každičkou operaci a každou službu zásadně spouští nová instance shellu, a že je k tomu dále nutné připočíst minimálně cron (opět se shelly...).