cistsi reseni? A bude to fungovat ikdyz nekdo vypne firewall ... treba z duvodu ladeni cehokoliv.
Jen mozna bylo dobre napsat radku o te kopii unit souboru. Kopirovat to cele (asi ekvivalent systemctl edit --full nginx) zajisti, ze ani update nginxu nezmeni nic z unit souboru. maximalne muze pouzit nove. V etc staci mit jen fragment, co opravdu chci pretizit. Ale asi je to jedno.
Je to tak správně. Např. aplikace na serveru běžící se může dotazovat na porty, kde server naslouchá, aby mohla vytvořit správné absolutní odkazy (třeba při přesměrování na HTTPS, nebo odkaz posílaný e-mailem). Když server naslouchá na správném portu, funguje to samo od sebe, když je na jiném portu a komunikace se na něj přesměrovává, musí se aplikaci explicitně sdělit, jaké jsou ty správné údaje.
Poslednou dobou dosť často počujem o Nginx.... vie mi niekto vysvetliť čo to reálne je? Pozeral som sa na stránky a vôbec tomu nerozumiem, tvári sa to ako balancer, web server, nejaká reverse proxy a neviem čo všetko...
a pri tom ani netuším s čím sa to používa, ak programovací jazyk, atď... ani vlastne čo to reálne vlastne je.
keď programujem webstránky a webaplikácie, vždycky som to riešil cez node.js alebo golang alebo python alebo c/c++... v využil som nejaké PaaS, IaaS a/alebo aj K8s.
Pozeral som sa na mnoho technológií okolo, konkrétne ale u Nginx som nikdy nepochopil ako sa to používa. Nevyzerá to ani ako Apache ani ako nič čo poznám.
17. 6. 2020, 00:45 editováno autorem komentáře
Nginx je webový server, stejně jako třeba Apache. Umí ale spoustu dalších věcí, třeba být reverzní proxy (před skutečným serverem) nebo třeba univerzální TCP/UDP proxy server. Podrobně jsou všechny jeho funkce popsány na domovském webu.
Většina těch funkcí je přímo svázaná s webem, takže je to prostě velmi mocný webový server. Nginx toho prostě umí hodně. Právě proto je to velmi populární kus software, přestože to asi není podle unixových principů. Pořád je to ale velmi kompaktní věc, balíček má půl mega, nainstalované to má něco přes megabajt.
Nejen HTTP(S). Nginx umožňuje pracovat nad čistým TCP spojením, má moduly pro SMTP, POP3, IMAP…
Původně byl nginx pokud vím zamýšlen víc jako load balancer nebo reverzní proxy, teprve časem se jeho hlavní náplní stalo HTTP(S).
Porušení unixového principu řešení pouze jednoho problému to zcela jistě je, ale on ten princip není jediný správný. A náběh na moloch – ona je to spíš historická zátěž, podle mne už se nginx moc do šířky nerozšiřuje. Ale přidávání nových vlastností na můj vkus není moc rychlé, zejména v porovnání s dřívějškem, kdy nginx vedle Apache vypadal neuvěřitelně inovativně.
Ono do nginx není moc co přidávat. Něco mají v komerční verzi a očividně nikomu nestojí za to to reimplementovat po svém do open source. Zbytek obstarají 3rd party moduly.
Hlavní důvod, proč nginx neroste do šíře je to, že se rozhodli nepodporovat kraviny typu .htaccess, vnořené a zkřížené nastavení pro directories a locations atp. Tím hodně (a dobře!) definovali konfigurační rámec a i to, které funkce v nginx nikdy nebudou.
Apache taky využívá PHP-FPM, ten princip je naprosto stejný.
Apache lze nastavit do stejné čistoty a velmi podobného výkonu, jako nginx. Spíš bývá překážkou to, že uživatelé apache jsou zvyklí na různé moduly, které upravují obsah nebo zpracování. Příkladem je .htaccess. To jsou věci, které apachi užírají podstatnou část výkonu a nedá se s tím nic dělat. Když je vypnete a nastavíte apache čistého, s nginx si nezadá.
U nginx máte zase výhodu toho, že si vzali za své nedopustit, aby se do něj vůbec dostaly funkce, u kterých se nedá výkon vyřešit. Nginx Vám prostě nepovolí rekurzivní location, nedovolí Vám složitá rewrite pravidla (ta efektivní se dají napsat jinak, mnohem lépe), nedovolí Vám hokej v tom, co je Directory a co Location...
Extrémním příkladem, jak se dá nastavení apache a PHP zničit je XAMPP.
Však se od něj taky víc nechce. Na nginxu uzavíráte https, vlastní to privilegovaný tcp port, a maximálně servíruje pár statických souborů. Na všechno ostatní jsou aplikační servery, na které nginx provoz přesměrovává (proto "reverzní proxy").
Doby kdy server vystavený do internetu byl zároveň aplikační (ve stylu apache+mod_php) jsou už naštěstí pryč. Proces vystavený do internetu díky tomu neobsahuje prakticky žádná citlivá data.
Apache i nginx jsou webové soubory – poskytují soubory přes HTTP. A oba dva umí navíc spouštět i různé skripty, jejichž výstup se pak přenese klientovy místo souboru. To spouštění skriptů ale vždy byla u webového serveru funkce navíc – jednu dobu velmi podstatná, ale její význam už zase trochu klesl, když se SPA obejdou s menším množstvím serverového kódu, protože se část (někdy značná) logiky přesouvá do prohlížeče.
A ten zbytek kolikrát tvoří proxované api jiného http serveru, jako uwsgi / gunicorn, nebo webového frameworku který sám o sobě http api poskytuje.
Pokud jde o čitou reverzní proxy, je dost zajímavý envoy. https://www.envoyproxy.io/docs/envoy/latest/
Jinak i přímo Petr Krčmář má o nginxu dobře stravitelnou přednášku: https://www.youtube.com/watch?v=MRpKBh7J0eo
Pokud znáte spíš Apache a chcete jej nějak moderně (víc po vzoru nginxu) konfigurovat, docela se mi líbil tento článek: https://arstechnica.com/information-technology/2020/05/apache-101-0-wordpress-in-15-minutes/
Pokud nginx běží jako www-data, tak i privátní klíče HTTPS certifikátů musí být čitelné tímto uživatelem. To znamená, že například děravá PHP aplikace se může k těmto souborům dostat. To nevypadá jako moc velké zlepšení v bezpečnosti.
Pokud nginx startuje jako root, ale zahodí oprávnění před obsluhou příchozích požadavků, tak může načíst vše předem a pak už se bez oprávnění obejde, takže privátní klíče mohou být čitelné jen rootovi a děravá aplikace má smůlu. Navíc takový proces běžící jako root nepředstavuje riziko, neboť nepřijde do styku s nedůvěryhodnými daty.
Navíc naslouchání na privilegovaných poretech by bylo lepší řešit přes socket activation nebo podobný mechanismus, který službě předá otevřený socket, aby neprivilegovaný nginx neměl možnost otvírat jiné porty.
17. 6. 2020, 01:03 editováno autorem komentáře
Počkejte, nespletl jste si to s indiánem s mod_php? nginx jsem pár let nedělal takže možná teď kážu bludy, ale co si pamatuju tak tam se php pouštělo přes php-fpm, který úplně v klidu pustíte pod jiným uživatelem, a s trochou hraní s permissions je to řešitelné.
(jasně, tohle článek neřeší, to by bylo téma na seriál)
U druhého odstavce máte s rootem plnou pravdu do chvíle, než potřebujete, aby si mohl konfigurák editovat i neprivilegovaný uživatel, Což uznávám že není typický use case, ale občas se to hodí.
Jinak téhož cíle jde dosáhnout i druhou cestou kterou používám drahně let pomocí setcap CAP_NET_BIND_SERVICE=eip $JAIL_ROOT/usr/sbin/httpd
což může pomoci i pokud si někdo chce pouštět apache z neprivilegovaného účtu ručně i bez hraní s su/sudo
To preci neni pravda... proces PHP (v nginx php-fpm) bezi typicky pod svym vlastnim uzivatelem.
Uz leta provozuji NGINX bez roota podobnym zpusobem (jen delam preklad portu v iptables). A php-fpm bezi pod vlastnim uzivatelem. Navic kazdy projekt/web ma vlastniho php-fpm demona, ktery bezi kazdy pod jinym uzivatelem - takze si ani nemohou vzajemne na data (v pripade dobre nastavenych pristupovych prav).
Ano, to je pravda. Asi by bylo vhodnější v článku použít jako příklad jiného uživatele než www-data.
Default (bezpečné): nginx(root)=>nginx_worker(www-data)=>php-fpm(www-data)
Článek (nebezpečné): nginx(www-data)=>nginx_worker(www-data)=>php-fpm www-data)
Možnost (bezpečné): nginx(jinyuzivatel_nez_ostatni)=>nginx_worker(www-data)=>php-fpm(www-data)
Možnost (bezpečné):
nginx(jinyuzivatel_nez_ostatni)=>nginx_worker(druhy_jinyuzivatel_nez_ostatni)=>php-fpm(treti_jinyuzivatel_nez_ostatni)
Jste si jistý tím, že nginx načte privátní klíče při startu a pak zahodí oprávnění roota? Když nginxu řeknete, že má přenačíst konfiguraci, přenačte i klíče. Takže buď celou dobu běží alespoň jeden proces pořád s právy roota, a nebo to nefunguje tak, jak píšete, a nginx potřebuje přístup ke klíčům celou dobu běhu.
Neustále běží jeden proces jako root. Debian 10:
root 1092 0.0 0.0 10596 1020 ? Ss Jun13 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 1093 0.0 0.0 12056 5064 ? S Jun13 1:22 nginx: worker process
www-data 1094 0.0 0.0 11260 4560 ? S Jun13 0:01 nginx: worker process
www-data 1095 0.0 0.0 11392 4548 ? S Jun13 0:12 nginx: worker process
www-data 1096 0.0 0.0 11260 4556 ? S Jun13 0:05 nginx: worker process
www-data 1097 0.0 0.0 11260 4568 ? S Jun13 0:00 nginx: worker process
www-data 1098 0.0 0.0 11260 3648 ? S Jun13 0:00 nginx: worker process
www-data 1099 0.0 0.0 11260 3648 ? S Jun13 0:00 nginx: worker process
www-data 1100 0.0 0.0 11260 4548 ? S Jun13 0:00 nginx: worker process
Pokud nginx běží jako www-data, tak i privátní klíče HTTPS certifikátů musí být čitelné tímto uživatelem. To znamená, že například děravá PHP aplikace se může k těmto souborům dostat. To nevypadá jako moc velké zlepšení v bezpečnosti.
To už je na Vás, jak si nastavíte uživatele pro nginx a jak pro PHP.
Opravdu není dobrý nápad mít hlavní proces NGINX pod stejným uživatelem jako PHP-FPM. To už je lepší ho spouštět pod rootem.
Existují dvě varianty. Pokud použijete systemctl edit
, vznikne override file, který obsahuje jen změny proti distribučnímu souboru. Chová se pak jako záplata nad původním konfigurákem, který se běžně aktualizuje.
Druhou variantou je použití přepínače --full
, což způsobí zkopírování souboru na nové místo, přesně jak je uvedeno v článku. Pak se vždy používá celý nový soubor, bez ohledu na stav toho původního.
Oba přístupy jsou validní, záleží na tom, co přesně potřebujete. V tomto případě se dá v klidu použít i override a dopsat do něj těch pár řádek.
zajimavy clanek, ale VUBEC mi to neprijde jako dobry napad.
normalni sluzba otevre pod rootem co potrebuje (porty,logy,privatni klice!!!) a pak prava zahodi. Sance ze v tom budou mit chybu je relativne mala.
pokud to pustite pod jinym uzivatelem, tak uz uzivatele zmenit nemuze (to muze jen root) takze sice nehrozi proniknuti az na roota, ale zase je vyrazne vyssi sance ze vam pronikne na daneho uzivatele a muze smazat logy (zahladit po sobe stopy) a zcizit klice, coz je docela smutne.
Sance je vyssi proto, ze jde o cely zbytek te aplikace, vic kodu, vic rizika. Predtim bylo riskantni jen to po zahozeni prav.
Zakomponujete chattr +a httpd.log vhodně do logrotate a neprovede nic.
Druhá věc jsou klíče - php nebo další zhůvěřilosti je nepřečtou (ani z paměti), a ty klíče stejně v raměti reálně máte i po zahození práv, takže pak záleží na jakou vulnerabilitu narazíte (v obvyklé implementaci), takže nějaké riziko máte vždycky. (a bez HSM to nevyřešíte, ale to už jsme v jiné lize)
normalni sluzba otevre pod rootem co potrebuje (porty,logy,privatni klice!!!) a pak prava zahodi.
Ne, to není normální postup – to je workaround vynucený tím, že to dříve nijak nešlo. Normální je samozřejmě aplikaci vůbec nedávat práva, která nepotřebuje. Což umožňují právě capabilities.
pokud to pustite pod jinym uzivatelem, tak uz uzivatele zmenit nemuze (to muze jen root)
To není pravda, opět je to jedna z capability.
zcizit klice
Pokud aplikace načte klíče při startu, může pak příslušný soubor smazat. K tomu nepotřebujete vůbec žádná zvláštní oprávnění.
Sance je vyssi proto, ze jde o cely zbytek te aplikace, vic kodu, vic rizika.
Jenže vy té aplikaci dáváte práva, která vůbec nepotřebuje. K ničemu z toho, co jste napsal, není root potřeba.
"Je zvykem, že webový server běží s právy roota."
Ehm, fakt? A to je zvykem kde? Mně tedy HTTP servery běží pod zvláštními uživateli a pod rootem ledatak startují a zahajují poslech na privilegovaných portech. Nenapadlo mě, že to někdo vážně na produkčních prostředích prasí jinak. S takovou by mi musely pod rootem běhat tři čtvrtiny služeb. Jenže to bych asi musel nejdříve zešílet.
Tiez nejak nechapem v com je to toto riesenie "bezpecnejsie".
pod rootom bezi len prvy proces Nginx tie co pracuju z okolim uz pod inim uzivatelom. (Standard od prvej verzie Nginx co bola pouzitelna)
Takto len spravime konfiguraciu ktora na inich unix-like systemoch nepojde. A vyrobime si problemy ktore by sme standardne nemuseli riesit (pidfile, pristup k certifikatom, portom)
Vyhoda je ze uz od zaciatku spustas sluzbu iba s takymi pravami ake potrebuje. Cize napriklad keby ti niekto podstrcil inu binarku alebo koli zlej konfiguracii alebo z ineho dovodu by nginx nezmenil toho pouzivatela tak system garantuje ze bude stale sluzba spustena len s pravami ake potrebuje. Keby sa napriklad v nginx objavila zranitelnost v casti kodu ktora sa vykonava este pod pravami roota (napriklad pri otvarani portov) tak opat tym zabranis niekomu zneuzit sluzbu k eskalacii prav.
Tiez je to vyhoda z pohladu manazmentu nastaveni. Je tym explicitne priamo definovane ze sluzba ma bezat s takymi a takymi pravami. Nemusis byt odbornik na nginx aby si videl ze sluzba sa spusta s nejakymi obmedzeniami a otvaranie privilegovanych portov ma vyslovene dovolene. To sa hodi zvlast ked sprava systemu a prava sluzby je v rukach samostatnej skupiny ludi.
Vseobecne si myslim, ze clanok sa prilis zameriava na toho non-root pouzivatela. Systemd ma kopec inych nastaveni ktore ti umoznia obmedzit prava a dosah tej konkretnej sluzby omnoho viac. Napriklad cez DevicePolicy=strict
vies obmedzit pristup k zariadeniam, vies nastavit limit na vyuzitie CPU/RAM. PrivateUsers
ti umozni spustit proces v samostatnom user namespace, takze sluzba bude mat vsetkych ostatnych pouzivatelov mapovanych na "nobody". PrivateTmp
da sluzbe privatny /tmp, co je inak pomerne casty vektor pouzivany na eskalaciu prav. Vies kompletne skryt obsah adresarov a povolit iba tie ktore aplikacia realne potrebuje aj ked samotny pouzivatel by inak mal pravo k takym adresarom pristupovat.. Tych moznosti je vela a konkretne zmena pouzivatela z root na nobody je jedna z tych co vie nginx spravit aj sam o sebe, tak to vyznie ako zbytocna vec.
To záleží na komplexnosti potřeb toho či kterého řešení. Když třeba zrovna ten nginx používáte jen jako reverzní proxy, vyrábět si na to kontejner je jednoduše zbytečně náročný overkill. Totéž platí třeba pro thttpd bez CGI a jiné službičky.
Když tam naopak máte deset děravých webů v PHP co tam provádějí radši nikdo nechce vědět co, dává to samozřejmě podstatně lepší smysl. Ale vyrábět si image pro každou drobnost je fakt zbytečně komplikované o tom, že je pak docela fajn ještě si navíc udržovat repository třeba kvůli migracím nebo o starostech se storage ani nemluvě. A to jsme se ještě nedostali k mikroserverům, kde je pár mega paměti a minimální storage.
Nedá se to tedy úplně paušálně říci. Za to lze paušálně říci, že hned ta první věta článku je nesmysl.
Jsou pro to případy užití, ale generalizovat to nejde. Taky jde o to, co považujete za kontejner. Jestli něco, co je připraveno s podobnou péčí a důrazem na bezpečnost, jako holá distribuce, nebo jestli kontejner, který stáhnete od třetí strany. Pokud od třetí strany, tak jak důvěryhodná je, jaké má nastavené procesy kvality atp.
Veškerý přínos kontejnerů bývá ve výsledku hodně diskutabilní. Nejčastěji se potkávám s tím, že to zlevní vývoj a deployment projektu, ale za cenu škod při následné správě.
Jako o bezpečnostním opatření bych o tom moc neuvažoval. Na Linuxu máte capabilities, na BSD chroot a jails. Pokud je Vás zájem zaostřen na bezpečnost, tak toto jsou ty správné nástroje. Kontejnery jsou proti tomu z hlediska bezpečnosti jen z nouze ctnost.
Zapomněl jste citovat zbytek. Ten hlavní proces nic nedělá, jen spawnuje workery pod jiným UID. Třeba v Apache je defaultní konfigurák, kde je non-root uživatel (apache, www-data nebo tak něco). Majoritní distribuce dělají žádné nebo jen minimální zásahy do upstream konfiguráků (je to best-practise), takže pokud není tvůrce distribuce úplný mimoň, tak se prostě stát nemůže, že by web běžel pod rootem (ale donutit ho nejspíš můžete).
Kromě toho jsou oprávnění dále osekána (SELinux, AppArmor).
Mohl byste se prosím rozepsat, jak si přesně představujete ten útok pomocí OpenSSL? klíč je generovaný lokálně, jediná 3rd party komponenta je certifikát (navíc uložený v CT logu) - nějak tu nesedí poměr ztráty (pro CA, na kterou se provalí že dala exploit do certifikátu) vs možný benefit, takže celý scénář se jeví býti značně akademickým.
Vůbec nemusí jít o cílený útok na konkrétní instanci. Stačí chyba buffer overflow v OpenSSL, která někde něco přepíše. Vzhledem k tomu, že nginx typicky servíruje jen statické soubory a aplikační kód je v jiném procesu, který může běžet pod jiným uživatelem, radši zpřístupním privátní klíč na disku té části nginxu, která servíruje statické soubory (a která k němu má stejně přístup – pokud se zase nedozvím, že ten kód pod rootem i navazuje TLS a workeru předá jen klíč spojení), než spouštět cokoli (a zejména kód OpenSSL) pod rootem.
Fedora/Red Hat pro mod_ssl používá modifikovaný OpenSSL s certifikací FIPS, což jiné SSL/TLS balíky nemají a nikdo se pro certifikaci a následnou údržbu nehlásí a pro komerční/průmyslové nasazení to je nutné.
Pokud byste chtěl zaútočit na httpd přes klíče, musel byste být root, protože nikdo jiný k nim nemůže. Když už jste root, můžete cokoliv, takže tento vektor útoku je maximálně teoretický a bez benefitu.
Pokud budete útočit přes HTTPS stream, tak se dostanete jenom do workeru a ne na roota. Pokud máte dojem/víte, že v OpenSSL jsou takové excesy v buffer overflow, asi se o tom bude brzo psát, ale kritických zranitelností je v OpenSSL málo (2002, 2002, 2013, 2016). Důležité zranitelnosti jsou také, ale ty ze sítě nejdou využít.
Pokud vás trápí, že Apache HTTPD neodděluje SSL/TLS od workeru, můžete (v RHEL/CentOS) použít i ten nginx, v distribucích je.
Mně na tom vadí to, že se začne tím, že část procesu běžící pod rootem jenom spawnuje workery, na tom přece není co zkazit. No, dobře. Jenže pak si někdo vzpomene, že se pod rootem také načítají privátní klíče. Přes OpenSSL, které nemá dobrou pověst co se týče kvality kódu a kvality vývoje. Jasně, v poslední době se to výrazně zlepšilo, když vybublalo na povrch, jaký průšvih to je. Certifikace FIPS řeší kryptografii – ale řeší i bezpečnost kódu? Pokud je privátní klíč někde na tokenu, tak v OpenSSL může být třeba chyba umožňující spuštění kódu, a z hlediska kryptografie je to celé v pořádku, privátní klíč je v bezpečí – ale ta knihovna rozhodně bezpečná není. No a pak se vrátím k tomu hlavnímu procesu, který tedy má načtený ten privátní klíč, jenže TLS pak dělá worker. Takže buď hlavní proces předá privátní klíč workeru (běžícímu pod neprivilegovaným uživatelem – jenže to se ten privátní klíč dostane do spárů toho neprivilegovaného uživatele). A nebo nebo, pokud má privátní klíč zůstat opravdu jen v moci roota, musí ten hlavní proces řešit i navázání spojení a TLS až do okamžiku, kdy už není privátní klíč potřeba. Takže se z jednoduchého masteru, který „jenom spawnuje workery“ (a také např. parsuje konfiguraci, to tu nezaznělo) najednou stává docela komplikovaný proces, který má docela dost vstupů. A tohle všechno běží pod rootem.
Pro mne je tohle stopka, nechci, aby všechno tohle běželo pod rootem. Ochrana privátního klíče serveru mi za tohle nestojí, dokážu ho ochránit jinak. Navíc k privátnímu klíči nemá přístup jenom webserver, ale také ten, kdo řeší obnovu certifikátu. CSR musí být privátním klíčem podepsána. Budu také CSR podepisovat pod rootem? Navíc spousta běžných aplikací vytváří nový CSR při každé obnově certifikátu a dělají vše pod jedním uživetelem, včetně komunikace ACME protokolem. To všechno také budu spouštět pod rootem? Zkrátka ten přístup „k privátnímu klíči může jen root“má také spoustu negativ, a oprávnění roota jsou strašně silná a zbytečná pro práci s privátním klíčem – vždyť jde jen o přečtení souboru a nějaké kryptografické operace. K tomu nejsou potřeba žádná administrátorská oprávnění.
Takže budu mnohem radši řešit to, aby web server nikdy žádná práva roota neměl, a vedle toho budu řešit to, aby uživatel, který má přístup k privátnímu klíči, nespouštěl žádný „uživatelský“ kód ve smyslu CGI, PHP nebo jiných server-side webových aplikací. Připadá mi takový přístup mnohem bezpečnější.
Zapomínáte na SELinux apod - root už není absolutní root a impakt master procesu httpd je v podstatě nula. Je zde též riziko komplexnosti kódu - pokud něco vylepšíte tím, že to bude složitější, není jisté zda si celkově nepohoršíte (a nenaděláte problémy chybnou konfigurací). FIPS (a jiné certifikace) komplikují přijímání záplat a refaktoring kódu - jenže o to jde (omezit zbrklé změny, jako kdysi třeba v Debianu).
Poslední odstavec - asi jste myslel oddělit krypto od uživatelského kódu - to se řeší přes php-fpm a fastcgi.
Obecně OpenSSL rozhodně není takový bezpečnostní průšvih, jak naznačujete - viz můj odkaz výše. Jsou tam obskurní části/moduly, ale ty se právě do solidních distribucí nedostanou, případně jde o chyby s nízkými dopady na bezpečnost. To že nějaký projekt má více CVE, ještě neznamená, že je ten kód tak špatný (případně mluvíte o 10+ let staré historii).
Pořád jde o to, že je zbytečné dávat webserveru práva roota. Jediné, k čemu je skutečně potřebuje, je naslouchání na nízkém portu – a to je řešitelné přes capabilities. To, že privátní klíč bude číst jenom root, je pak čistě rozhodnutí správce.
Problém komplexnosti kódu je právě to zbavování se oprávnění. Pokud se server nastartuje rovnou pod uživatelem s omezenými oprávněními, nepotřebuju vůbec kód řešící zbavení se oprávnění, ani nemusím řešit, kdy se má provést kód s vysokými oprávněními a co odložit až do části s nízkými oprávněními.
Oddělení uživatelského kódu znamená nejen oddělení kryptografie, ale oddělení všech zbytných věcí – loadbalancing, alespoň část síťové komunikace a parsování protokolu. Jasně, s FastCGI zase komunikuji síťovým protokolem, ale ten je trochu kompaktnější než HTTP a na druhé straně je můj server, ne internet.
Nemluvím o 10+ let staré historii, jenom o cca 5+ let staré historii. A nejde mi tolik ani o CVE, ale spíš o jakousi kulturu toho kódu a projektu. To jsou věci, které jsou v kódu vidět i po pěti letech, i když se nové věci budou psát dobře a i když se zjevné chyby opraví.
Navíc pověst OpenSSL je jen část problému. Druhou částí je obecně TLS – potřebujete tam dělat různé triky kvůli bezpečnosti, další triky kvůli rychlosti. Pro provoz nejsou potřeba žádná speciální oprávnění. Za téhle konstelace to provozovat pod rootem je pro mne zbytečné riziko – podle mne je to učebnicový příklad kódu, který by pod rootem běžet neměl. Argument, že je potřeba načíst privátní klíč z disku a neumožnit stejnému procesu ten klíč načíst znova podle mne v žádném případě neobstojí – k tomu nejsou vůbec potřeba oprávnění roota.
Ještě jednou - se SELinuxem sice vidíte root, ale ten root u httpd démona nemůže skoro nic. Můžete použít ještě capabilities (od RHEL7), ale systémově to použito není, protože SELinux je mnohem silnější nástroj. Jistě, můžete nosit pásek i kšandy, ale...
OpenSSL se používá kvůli FIPS. Do alternativ se nikomu nechce, protože to stojí peníze, a protože se rychle přišlo na to, že jedna věc je RFC/norma a druhá věc realita, takže uchodit cokoliv jiného, aby to fungovalo se vším, je oříšek a dojdete nejspíš ke stejně nepřehlednému kódu.
Navíc pověst OpenSSL je jen část problému. Druhou částí je obecně TLS – potřebujete tam dělat různé triky kvůli bezpečnosti, další triky kvůli rychlosti. Pro provoz nejsou potřeba žádná speciální oprávnění. Za téhle konstelace to provozovat pod rootem je pro mne zbytečné riziko – podle mne je to učebnicový příklad kódu, který by pod rootem běžet neměl. Argument, že je potřeba načíst privátní klíč z disku a neumožnit stejnému procesu ten klíč načíst znova podle mne v žádném případě neobstojí – k tomu nejsou vůbec potřeba oprávnění roota.
Já si myslím, že se na to nedíváte úplně správně. OpenSSL i Nginx se snaží, aby tam nebyly bezpečnostní problémy a k tomu cíli se to bude přibližovat. Určité riziko zůstane, ale ne moc vysoké.
Proti tomu stavíte řešení, které naruší standardy (či zvyklosti) v jiných ohledech. Např. klíče mimo keystore, speciální oprávnění, oprávnění k logům, ... Tímto řešením se to bude od ideálu zase vzdalovat.
Pokud mám zvolit nestandardní řešení, měl bych k tomu mít opravdu dobré důvody. Rizika zrovna z nginx a openssl jsou okrajová proti rozvrtání dalších věcí.
Řešením je, jak psal pan Keršláger, využít SElinux. Není to 100% řešení, stejně jako Vaše řešení není 100%. První navrhované je však správně i systematicky, druhé už je custom. Já, pro případ strachu z dopadů rizik doporučuju předřadit reverzní proxy zajišťující SSL offloading. To je třetí řešení a taky není 100%.
OpenSSL i Nginx se snaží, aby tam nebyly bezpečnostní problémy
Ano, snaží. Přesto je snaha omezit běh aplikací pod rootem na minimum. Nejdřív se do webového serveru implementovalo to, že se připojí na port a pak se vzdá rootovských oprávnění. Pak se implementovaly capabilities, aby se aplikace vůbec nemusel spouštět pod rootem, když jenom potřebuje naslouchat na nízkém portu. Pak se přidal SElinux.
Všichni se smaží, to nikomu neupírám, ale pořád nejjednodušší a nejspolehlivější řešení je vůbec procesu roota nedávat.
Proti tomu stavíte řešení, které naruší standardy (či zvyklosti) v jiných ohledech.
Stejné narušení zvyklostí bylo to, že se Apache zbavil rootovských oprávnění po startu. Před tím standardně běžel pořád pod rootem.
klíče mimo keystore
Nevím, čemu říkáte keystore – nginx načítá klíče ze souboru na disku.
speciální oprávnění
K tomu přece oprávnění slouží. SElinux je daleko větší specialita, než normální oprávnění na souboru. Navíc běžný nginx běží pod speciálním uživatelem, servíruje statické soubory a pak přes síť komunikuje s jinými aplikacemi, které poskytují dynamické stránky. Tyhle aplikace často běží i na jiném zařízení. Takže jediné, co se po správci chce, je to, aby nebyl líný, a vytvořil třeba pro php-fpm jiného uživatele, než pod jakým běží nginx. Což je v každém případě dobrý nápad. Co je na tom speciálního? Navíc by to měla řešit rovnou distribuce.
Tímto řešením se to bude od ideálu zase vzdalovat.
Ne, řešení, kdy se server vůbec nespouští s právy roota, když je nepotřebuje, je přiblížení se k ideálu.
Řešením je, jak psal pan Keršláger, využít SElinux.
Nakonfigurovat správně SElinux je podstatně složitější, než nakonfigurovat v systemd capabilities a vytvořit pro nginx speciálního uživatele. Navíc je trochu na hlavu dát nginxu úplně zbytečně roota a pak ho všemi možnými způsoby omezovat, když mu toho roota vůbec nemusím dávat.
První navrhované je však správně i systematicky, druhé už je custom.
Systematicky správně je nespouštět server pod rootem, když nepotřebuje rootovská oprávnění. Webový server potřebuje rootovská oprávnění jenom pro naslouchání na nízkém portu, a k tomu stačí použít capability.
Já vidím následující rizika – proces, který jenom servíruje statické soubory a odpovědi, které dostane od jiných procesů, bude mít přístup k privátnímu klíči serveru a k webovým logům. Za mne jsou tahle rizika minimální. Pokud by útočník přes to dokázal server napadnout tak, aby mohl modifikovat odpovědi nebo soubory, bude prakticky jedno, že získal privátní klíč k certifikátu – může podvrhovat provoz přímo na serveru. Takže skutečné riziko je to, že by útočník mohl jenom přečíst soubor s privátním klíčem. A to je velmi málo pravděpodobné, nebyla by to žádná nevratná katastrofa, a kdybych se toho opravdu bál, můžu ten privátní klíč po startu server znepřístupnit.
Jaká další rizika vidíte vy?
@Filip Jirsák
O tomhle by se dala vést sáhodlouhá diskuse. Protože to už je o poměřování rizik a jejich dopadů. OpenSSL chyby obsahovat samozřejmě může, stejně jako hlavní proces nginxu. Otázkou, kterou bych si kladl je, jestli při ručním přenastavení práv k logům, přenastavení logrotate, přístupu ke klíčům etc. nemůžete udělat sérii dalších chyb (nemluvě o tom, že takové přenastavení může vyvolat kaskádu minoritních problémů, které zase budete řešit custom úpravami v jiných částech systému).
Takže tu proti sobě stojí:
a) výchozí nastavení, poměrně dobře zkoumané a provozované, laděné + riziko 0day zranitelností
b) ruční nastavení, se snížením rizika 0day zranitelností, ale se zvýšením rizika udělání jiné chyby, kterou ale můžete zjistit jen Vy sám (nedá se předpokládat, že stejné custom řešení zvolí moc lidí, každý už si to udělá po svém).
Takovou situaci bych spíš řešil předřazením reverzní proxy na jiném serveru, případně v jailu, který by se staral o SSL offloading. Na něm už můžete zvolit libovolnou z obou dobrých variant. Rizika nesnížíte, ale odstraníte 90 % dopadů.
Např Nextcloud nainstalovaný jako snap baliček. I když tam je to prý omezeno na jiné úrovni, podobně jako docker.
root 614 0.0 0.0 4636 1596 ? Ss 03:28 0:00 /bin/sh /snap/nextcloud/21521/bin/run-httpd -k start -DFOREGROUND root 1911 0.0 0.0 4636 1720 ? S 03:29 0:00 \_ /bin/sh /snap/nextcloud/21521/bin/httpd-wrapper -k start -DFOREGROUND root 1946 0.0 0.0 51092 4732 ? S 03:29 0:01 \_ httpd -d /snap/nextcloud/21521 -k start -DFOREGROUND root 1947 0.0 0.0 1266220 4260 ? Sl 03:29 0:00 \_ httpd -d /snap/nextcloud/21521 -k start -DFOREGROUND root 1948 0.0 0.0 1266220 4260 ? Sl 03:29 0:00 \_ httpd -d /snap/nextcloud/21521 -k start -DFOREGROUND root 1949 0.0 0.0 1266220 4260 ? Sl 03:29 0:00 \_ httpd -d /snap/nextcloud/21521 -k start -DFOREGROUND
Ano, snap je v sandboxu. Flatpak taky. Ovšem záleží na tvůrci konkrétních balíčků, někteří totiž nepoužívají žádná omezení. V každém případě je vždy na uvážení uživatele, co si pustí do systému (a za jakou cenu). Snapy/Flatpaky přímo od distribuce by mohly být nastaveny slušně.
Distribuce jsou historicky vycepované (a ty lepší mají bugtracking), ale na netu (bohužel) najdete ledacos a často nemáte ani kam chybu nahlásit.
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
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)
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.
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.
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.
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ý.
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
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_service" 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 :))
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_service:
#!/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
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.
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.
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?
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?
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.
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?
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.
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í.
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.
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 :-)
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čí.
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.
Ř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...).