udev & D-Bus & HAL helyett DeviceKit helyett udisks+UPower - 2. rész: A D-Bus fontosabb szolgáltatásai és biztonsági modellje

A sorozat részei: 1 2 3 4

A D-Buson keresztül elérhető fontosabb szolgáltatások

A rendszeren futó különböző D-Bus példányok (pl. session D-Bus) elsődleges feladata, hogy keretet biztosítson különböző szoftverkomponensek együttműködéséhez. A rendszer D-Busról emellett azonban elmondható, hogy - mivel privilegizált és felhasználói szoftverkomponensek között közvetít, ezáltal bizonyos SETUID programfájlok kiváltására és a legkevesebb privilégium elvének megközelítésére alkalmas - a modern UNIX rendszerek biztonsági modelljének fontos építőkövévé kezd válni. A rendszer D-Bushoz csatlakozó, és azon jól ismert (well known) nevek alatt szolgáltatásokat biztosító démonokat ebben a blogbejegyzésben szolgáltató ágensnek nevezem. A szolgáltató ágensek a felhasználó - általában rendszergazdai jog híján közvetlenül el nem végezhető - utasításait hajtják végre, valamint multicast szórással az általuk felügyelt alrendszerek - többnyire végső soron a kernelből érkező - eseményeit is továbbítják a felhasználói felület vagy más érdeklődő szoftverkomponens felé. A rendszer D-Busunkon jelen levő szolgáltató ágensek (és jól ismert névvel nem rendelkező egyéb ügyfelek) listáját megkaphatjuk a következő parancs kiadásával:
dbus-send --system --dest=org.freedesktop.DBus --print-reply --type=method_call /org/freedesktop/DBus org.freedesktop.DBus.ListNames

Egy-egy ilyen szolgáltató ágens képességeiről gyorsan vázlatos képet kaphatunk, ha lekérdezzük az általuk biztosított D-Bus interfészek XML formátumú leírását. Az alábbi, NetworkManagert bemutató példa - amely az első részben már taglalt org.freedesktop.DBus.Introspectable.Introspect metódusra épít- nyomán ezt bármelyik szolgáltatással megtehetjük:

dbus-send --system --dest=org.freedesktop.NetworkManager --print-reply --type=method_call /org/freedesktop/NetworkManager org.freedesktop.DBus.Introspectable.Introspect

Az alábbiakban vázlatpontszerűen bemutatok néhány fontosabb szolgáltató ágenst:

-NetworkManager: Az org.freedesktop.NetworkManager nevű jól ismert D-Bus címet birtokolja. Lehetővé teszi, hogy a közönséges felhasználók is igényeiknek megfelelően konfigurálják a számítógép hálózati beállításait, és az így keletkezett konfigurációt el is tárolja. Lehetővé teszi továbbá a hálózat menedzselését is, ami rendszergazdai jogok nélkül egyébként nem lenne lehetséges. Az ilyen hálózati menedzselési feladatok közé tartozik többek között a vezeték nélküli (vagy vezetékes) hálózat ki- és bekapcsolása, kapcsolódás az elérhető közelségben levő WiFi SSID-khoz, VPN szolgáltatókhoz, stb. A NetworkManager felhasználói felületét a Gnome nm-applet programja, a KDE plasmoid NetworkManagementje, és hasonló szoftverek biztosítják, amelyek természetesen a kizárólag a rendszer D-Buson keresztül érintkeznek a NetworkManager démonnal.

-UPower: Az org.freedesktop.UPower nevű jól ismert D-Bus címet birtokolja. A számítógép áramellátást felügyeli. A tápegységekkel és egyéb energiagazdálkodással kapcsolatos eszközök (AC tápegység, akkumulátor, laptopfedél, stb.) eseményeit (pl. csatlakoztatás, leválasztás, töltörrségi szint változása, nyitás, csukás, stb.) továbbítja a kerneltől a felhasználói felületek felé, lehetővé teszi ezen eszközök adatainak (gyártó, típus, kapacitás, várható élettartam, elhasználtság, stb.) lekérdezését, valamint különböző energiagazdálkodási műveletek (alvó állapotba lépés, hibernálás, stb.) végrehajtását. Az UPower rendszer funkcióit korábban az org.freedesktop.Hal címen elérhető HAL démon látta el, ennek fejlesztése azonban abbamaradt, és átvette a helyét a DeviceKit alrendszer. A DeviceKit projekt azonban rövid életűnek bizonyult, és a helyét több - az Udev projekt égisze alatt futó - kisebb alrendszer vette át. Ezek egyike az UPower.

-udisks: Az UPowerhez hasonlóan a HAL projekt leszármazottja, és az Udev szárnyai alatt kötött ki. Az org.freedesktop.UDisks címen kínálja szolgáltatásait. Fő feladta a blokkeszközök kezelése, és azok eseményeinek közvetítése a felhasználó felé. Lehetővé teszi, hogy a felhasználói felületek érzékeljék új blokkeszközök csatlakoztatását, és különféle műveleteket végezzenek rajtuk, mint pl. mountolás (olyan módon, hogy az adott felhasználó megfelelő jogokkal rendelkezzen a felmountolt fájlrendszeren), formázás, partícionálás, titkosítás, LVM kezelés, swap-eszközök kezelése, sőt a közeljövőben loop-eszközök (pl. CD vagy DVD képmásfájlok) felmountolására is képes lesz.

-PackageKit: Az org.freedesktop.PackageKit nevű jól ismert D-Bus címet birtokolja. Privilegizált démonja a packagekitd különböző backendek (pl. apt, yum, zypp) segítségével a rendszer szoftvercsomagjainak karbantartását (pl. telepítés, eltávolítás, frissítések keresése, frissítés) végzi. A rendszer D-Buson keresztül hozzá csatlakozó frontendekkel (mint pl. a KDE-féle Apper) kiegészülve lehetővé teszi, hogy rendszergazdai jog nélkül kezeljük a szoftvercsomagokat és repository-kat.

A D-Bus biztonsági modelljének központi eleme: PolicyKit (és ConsoleKit)

Szó volt már róla, hogy a rendszer D-Bus és szolgáltatásai a UNIX-ok biztonsági modelljének részévé kezdenek válni. Ha azonban a szolgáltató ágensek a felhasználóktól érkező minden kérést feltétel nélkül végrehajtanának, azzal nem igazán mozdítanák előre a biztonság ügyét. Az előző részben már ismertetett dbus-daemon man oldal bemutatja a dbus-daemon XML alapú konfigurációs fájljait. A <policy> elem megvalósít egyfajta biztonsági modellt, ez azonban csak a D-Bus kommunikációra vonatkozik, azaz alacsony szinten dolgozik, a D-Bus üzeneteket szűri tűzfalszerűen. Akár UNIX felhasználó és csoport szinten adhatjuk meg benne, hogy ki milyen D-Bus üzeneteket küldhet és fogadhat, milyen D-Bus neveket/címeket birtokolhat, stb.

A D-Bus rendszer biztonsági modelljének egy magasabb szintje a PolicyKit démonra épül. A polkitd a rendszer D-Bus példányhoz kapcsolódva az org.freedesktop.PolicyKit1 néven keresztül nyújt szolgáltatásokat D-Bus többi ügyfelének. Amint azt a PolicyKit man oldala leírja, a PolicyKit alapvetően a következőképpen működik:

Rendszerindításkor a polkitd nevű démon csatlakozik a rendszer D-Bushoz, és az org.freedesktop.PolicyKit1 D-Bus néven, a /org/freedesktop/PolicyKit1/Authority objektum org.freedesktop.PolicyKit1.Authority interfészén keresztül válik elérhetővé. Ezen felül a felhasználói munkamenetekben (pl. Gnome, KDE session-ök) is van egy-egy processz, amely a polkitd-től eltérően természetesen nem root-ként, hanem az adott felhasználó nevében fut. Ezt az utóbbi processztípust autentikációs ágensnek hívják, nem igényel magának jól ismert nevet a D-Bus-on, és a org.freedesktop.PolicyKit1.AuthenticationAgent interfészen keresztül biztosít szolgáltatásokat, amelyeket a polkitd vesz igénybe. Annak érdekében, hogy a polkitd megtalálja a jól ismert névvel nem rendelkező autentikációs ágenseket, induláskor minden ágens beregisztrálja magát a polkitd-nél az org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent metódus segítségével.

Amint erről már szó volt, a rendszer D-Buson keresztül elérhető szolgáltató ágensek (pl. NetworkManager, UPower, udisks, stb.) többnyire root joggal futnak, és a felhasználó asztali környezetéből D-Buson keresztül érkező utasításokat hajtják végre. Az utasításokat hordozó üzeneteket maga a D-Bus szűri, a PolicyKit célja pedig az, hogy segítsen a szolgáltató ágenseknek eldönteni egy adott felhasználói kérésről, hogy jogos vagy sem. Ennek érdekében a szolgáltató ágenseknek a felhasználók számára felkínált szolgáltatásai (pl. bizonyos metódusok meghívása, változók értékének megváltoztatása, stb.) ún. akciókká képződnek le a PolicyKit rendszerben. A legtöbb szolgáltató ágenst tartalmazó programcsomag a PolicyKit számára értelmezhető konfigurációs fájlokat is tartalmaz, amelyben definiálja az adott ágenshez tartalmazó akciókat, az egyes akciókhoz tartozó felugró üzenetek szövegezését különféle nyelveken, a felugró üzenettel együtt megjelenítendő ikont, és az akció alapértelmezett elbírálására vonatkozó utasításokat (pl. aktív munkamenetek számára engedélyezett, inaktív munkamenetek számára tiltott, stb.). Az akciókat leíró fájlok a /usr/share/polkit-1/actions könyvtárban vannak, formátumukat a PolicyKit man oldala írja le.

Azt, hogy egy konkrét esetben hogyan engedélyezzen, illetve engedélyezzen-e egyáltalán egy adott akciót a polkitd, a pklocalauthority man oldalon leírt .pkla konfigurációs fájlokban, és néhány hozzájuk kapcsolódó konfigfájlban adhatjuk meg. UNIX user és group szinten szabályozhatjuk, hogy ki jogosult az adott akció végrehajtására aktív (előtérben levő), illetve inaktív (pl. gyors felhasználóváltás során háttérbe került és zárolt) munkamenetben, valamint azt,hogy az engedélyezés feltétel nélküli legyen-e, vagy a felhasználótól bekérjük a saját vagy valamely rendszergazdai jellegű felhasználó jelszavát. Megadhatjuk azt is, hogy a rendszergazdai autentikációnál mely felhasználó vagy felhasználók jelszavát kell megadnia a felhasználónak. Alapértelmezetten a root az egyetlen rendszergazdai autentikációra használt felhasználói fiók, de ez megváltoztatható, sőt megadhatunk több felhasználói fiókot is, amelyek közül a felhasználó választhat. A .pkla fájlokat a /var/lib/polkit-1/localauthority és a /etc/polkit-1/localauthority könyvtárakban keresi a polkitd. Az előbbi könyvtárban általában a disztribútor által szállított alapértelmezett beállítások vannak, utóbbiban pedig a felhasználó, illetve a rendszergazda saját beállításai.

Mivel a D-Bus alapú UNIX rendszerek biztonsági modelljének fontos komponense a PolicyKit, és a PolicyKittel kapcsolatos legjellemzőbb adminisztrátor teendő a .pkla fájlok szerkesztése, úgy gondolom, hogy a rendszergazdák számára az egész D-Bus rendszerrel kapcsolatban talán nincs fontosabb gyakorlati tudnivaló a .pkla fájlok ismereténél. Ha tehát az a kérdés, hogy vállalati környezetben hogyan engedélyezzük a felhasználóknak a szoftverfrissítést anélkül, hogy elárulnánk nekik a root jelszót, ugyanakkor új programok telepítését tiltsuk meg a számukra, akkor a válasz: RFTM!

A PolicyKit felugró üzeneteinek megjelenítését és a jelszavak bekérését természetesen nem maga a polkitd démon, hanem az adott munkamenet autentikációs ágense végzi. Az autentikáció menete a következő:

1. A felhasználó valamilyen privilegizált feladat végrehajtását kezdeményezi az aktuális munkamenetének asztali környezetében, pl. megváltoztatja egy rendszerszintű hálózati kapcsolat beállításait az nm-appletben vagy a KDE plasmoid networkmanagement rendszerében.
2. Az asztali környezet (többnyire a D-Buson keresztül) utasítja a rendszergazdai jogokkal futó szolgáltató ágenst (pl. a NetworkManagert az org.freedesktop.NetworkManager címen) a feladat végrehajtására.
3. A szolgáltató ágens (a PolicyKit man oldalán található ábrán "Mechanism" néven szerepel) meghatározza az adott művelethez tartozó akció nevét, és megkérdezi a org.freedesktop.PolicyKit1 néven hallgatózó polkitd-től, hogy az adott felhasználó az adott munkamenetben jogosult-e végrehajtani a szóbanforgó akciót. Ez a kérdés a polkitd egyik legfontosabb metódusán, a org.freedesktop.PolicyKit1.Authority.CheckAuthorization metóduson keresztül történik.
4. A polkitd a /usr/share/polkit-1/actions, valamint a /var/lib/polkit-1/localauthority és a /etc/polkit-1/localauthority könyvtárakban levő konfigfájlok alapján megállapítja, hogy a felhasználó jogosult-e végrahajtani az adott akciót, és ha igen, akkor feltétel nélkül megteheti-e ezt vagy autentikálnia kell-e hozzá.
5. Amennyiben autentikáció szükséges, a polkitd kikeresi a hozzá beregisztrált autentikációs ágensek közül azt, amelyik a szóbanforgó felhasználó adott munkamenetében található, és a D-Buson keresztül utasítja arra, hogy jelenítse meg a szükséges párbeszédablakot a felhasználónak, és végezze el a a szükséges autentikációt.
6. Az autentikációs ágens elvégzi az autentikációt, az eredményét pedig visszaküldi a polkitd-nek.
7. A polkitd a konfigfájlokból kiolvasott értékek és az autentikációs ágenstől kapott eredmény alapján eldönti, hogy jogos-e a felhasználónak az akcióra irányuló kérelme, és az eredményről tájékoztatja a szolgáltató ágenst ("Mechanisn") pl. a NetworkManagert.
8. A szolgáltató ágens a polkitd-től visszakapott eredménytől függően végrehajtja vagy megtagadja az akció végrehajtását, az eredményekről tájékoztatja az felhasználó asztali környezetének az akciót eredetileg kezdeményező komponensét.

Amint a fentiekből kitűnik, mind a szolgáltató ágensnek, mind a polkitd-nek mind magának a dbus-daemonnak szüksége van olyan információkra, amelyek alapján megállapíthatják, hogy egy befutó D-Bus kérés mögött melyik felhasználó melyik munkamenete (esetleg annak pontosan melyik processze áll), illetve hogy az adott munkamenet éppen aktív vagy inaktív. esetleg zárolt-e? A sorozat első részében már említett SO_PEERCRED opció, illetve a dbus-daemonnak olyan metódusai, mint a org.freedesktop.DBus.GetConnectionUnixUser, org.freedesktop.DBus.GetConnectionUnixProcessID, stb. szolgálnak némi információval ebben a kérdéskörben, de ez elégtelen a munkamenetek állapotának felméréséhez, illetve annak megállapításához, hogy mely processz mely munkamenethez tartozik, vagy hogy az adott munkamenet a számítógép mely konzoljához tartozik, illetve hogy az adott konzol mely hardvereszközökből áll, stb. A munkamenetekre, felhasználókra, konzolokra vonatkozó információ legnagyobb részét egy külön erre a célra létrehozott D-Bus szolgáltató ágens, a ConsoleKit biztosítja.

A felhasználók munkameneteinek van egy komponense (pl. a pam_ck_connector.so PAM modul), amely a munkamenet indulásakor beregisztrálja a munkamenetet a rendszer D-Bus-on org.freedesktop.ConsoleKit név alatt elérhető console-kit-daemonhoz, és támogatja a démont abban, hogy a munkamenet minden processzét azonosítani tudja, azaz bármely processzről meg tudja állapítani, hogy az adott munkamentbe tartozik-e. A console-kit-daemon azon kívül, hogy munkamenetek, processzek, felhasználók és konzolok (a ConsoleKit nevezéktanában "seat"-ek) auditálásával támogatja és kiegészíti a PolicyKit rendszert, az Udev-vel karöltve átveszi a néhai Resource Manager feladatait, sőt a felhasználók számára is biztosít néhány szolgáltatást, pl. meglepő módon innen hajthatják végre a velhasználói felületek a gép leállítását vagy újraindítását a org.freedesktop.ConsoleKit címen található /org/freedesktop/ConsoleKit/Manager objektum org.freedesktop.ConsoleKit.Manager.Stop és org.freedesktop.ConsoleKit.Manager.Restart metódusaival.

Amint a ConsoleKit honlapja utal rá, a ConsoleKit aktív fejlesztése befejeződött, és lassan átveszi a helyét a systemd systemd-loginctl szolgáltatása. Ez a ConsoleKit-éhez nagyban hasonló szolgáltatásokat biztosít. A két rendszer között a legalapvetőbb eltérés az adott PID-hez tartozó session azonosításának módja. A ConsoleKit (a pam_ck_connector.so PAM modulon keresztül) egy XDG_SESSION_COOKIE nevű változót állít be minden általa követett munkamenet első processzének rendszerváltozói között, ami aztán továbböröklődik a munkamenet összes processzére, ezáltal a PID ismeretében a /proc/PID/environ fájlokból kiolvashatja, hogy mely processzhez mely session cookie tartozik. A módszer előnye, hogy a különböző UNIX változatok között jól hordozható, de hátránya, hogy bármely processz törölheti ezt a változót a saját rendszerváltozói közül (vagy átírhatja az értékét), ezáltal kivonva magát a ConsoleKit ellenőrzése alól. A systemd nem rendszerváltozókkal dolgozik, hanem egyszerűen a Linux-specifikus control group-okat felhasználva csoportosítja a processzeket, ezáltal sokkal gyorsabb és hatékonyabb követést megvalósítva. A módszer előnye többek között, hogy különleges privilégiumok nélkül a processzek nem tudják kivonni magukat a systemd ellenőrzése alól.

A ConsoleKit és a systemd-loginctl minden további nélkül működhet egymás mellett párhuzamosan, az openSUSE 12.1 esetében pontosan ez történik. A D-Bus biztonsági modelljének tesztelése céljából próbáljuk ki az alábbiakat:

Hozzuk létre (esetleg a /var/lib/polkit-1/localauthority könyvtárból történő átmásolással) a /etc/polkit-1/localauthority/50-local.d/org.freedesktop.consolekit.system.stop.pkla fájlt, majd a tartalmát módosítsuk az alábbiak szerint:

[org.freedesktop.consolekit.system.stop]
Identity=unix-group:users
Action=org.freedesktop.consolekit.system.stop
ResultAny=auth_admin
ResultInactive=auth_admin
ResultActive=auth_admin

Semmilyen démon újraindítása vagy újratöltése nem szükséges, mert a polkitd a dbus-daemonhoz hasonlóan követi a konfigfájlok változásait, és automatikusan beolvassa azokat. A fenti konfigurációmódosítás eredményeképpen a számítógépnek a közönséges felhasználók asztali környezeteiből D-Bus-on keresztül történő leállításához adminisztrátori jelszó megadása szükséges. Hogy tényleg így van-e, kipróbálhatjuk a következő parancs kiadásával (közönséges felhasználóként egy grafikus környezetből indított terminálemulátor parancssorában):

dbus-send --system --dest=org.freedesktop.ConsoleKit --print-reply --type=method_call /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop

Ha nem rontottunk el semmit, a parancs kiadásának nyomán az asztali környezet egy autentikációs párbeszédablakot dob fel, és csak sikeres autentikációval állíthatjuk le a gépet.

Ezzel tulajdonképpen a végére is értem a D-Bus vázlatos ismertetésének. A későbbiekben várható blogbejegyzések a D-Bushoz szorosan kapcsolódó - dinamikusan, és egészen váratlan irányokba fejlődő - rendszerekről, az Udevről és a systemd-ről fognak majd szólni.

A sorozat részei: 1 2 3 4

Hozzászólások

Hoppá, a PackageKit-ről elfeledkeztem! Pótolva.

Köszi, szép munka! Nagyon tetszik benne, ahogy a gyakorlati megvalósítást is ismerteted, így áll össze teljes képpé az egész. Nagyon várom az újabb részeket is.

Esetleg azt tudod, hogy mitől áll le *azonnal* a zene, amint elváltok a beloginolt session-ről? Illetve hogy szólhat, egyáltalán? A /dev/snd/ eszközökre a modern disztrók már nem adnak a juzereknek unix hozzáférést, pedig a pulseaudio a user UID-jával fut, az alap csoport-tagságokkal.
(Fedora 16-nál volt egy ConsoleKit bug, ott találkoztam ezzel érintőlegesen és még nem volt időm utánanézni.)

Pár percet próbálkoztam vele, hogy kiderítsem, de nem bírtam rájönni. Biztos, hogy a ConsoleKit keze van a dologban. Érdekesség, hogy ha az X-ről való elkapcsolás után belépek egy szöveges virtuális terminálon, újra megszólal a zene. Tehát addig szól a zene, amíg a tiéd az aktív session. Még akkor is, ha a zenelejátszó egy másik session-ödben van. Azt hiszem, a ConsoleKit lehet az is, ami elveszi a /dev könyvtárban levő alsa eszközfájról a számodra rw jogot biztosító posix acl-t. Mondjuk ezen felül más is történik, mert az acl kézi visszarakásától nem indul újra a zene. Valami olyasmit tudok elképzelni, hogy a pulseaudio démonod hallgatózik a rendszer D-Buson és figyeli a ConsoleKit szignáljait. De ez csak tipp.

Na, jó. Egy kis audit eredményeképpen rájöttem, hogy a /lib/udev/rules.d/70-udev-acl.rules-en keresztül az Udev által is meghívott /lib/udev/udev-acl programot a ConsoleKit is meghívja (seat_active_session_changed paraméterrel) a /usr/lib/ConsoleKit/run-seat.d/udev-acl.ck symlinken keresztül. Ha ezt a symlinket eltávolítod, a ConsoleKit nem fogja aktualizálni a /dev könyvtárban található eszközfájlok jogosultságait, így nem hallgat el a zene, ha terminált váltasz. Persze csak azután távolítsd el, hogy beléptél, különben már a kezdetek kezdetétől hiányozni fog a jogosultság a zenehallgatáshoz. arról se feledkezz meg, hogy ezután ha valaki más is belép a gépre, ő sem fog rendelkezni a megfelelő jogosultságokkal. Szóval nem sok értelme van törölni ezt a symlinket,főleg hosszú távon. Amúgy ha systemd alapú a rendszered, akkor hatástalan ez a symlinktörlés, mert a systemd a ConsoleKit-től függetlenül elvégzi ugyanezt a feladatot (a posztban erre utaltam, amikor azt írtam, hogy ezek az új rendszerek átveszik a Resource Manager feladatait).

Ez nagyon alapos volt, köszönöm én is, jó volt végigolvasni.

Viszont émelyítően bonyolultnak érzem, egyszerűen tiltakozik ellene a szépérzékem. Az elnevezések is, miért van pl. a PolicyKit1 végén az 1-es?

--
Java apps are nothing more than sophisticated XML-to-exception converters.

dap hozzászólása nyomán beszúrtam egy kis utalást a Resource Managerre, de nem dolgoztam fel valami alaposan ezt a témát. Úgy tűnik, elég sok jóságot tud a ConsoleKit. Aki nem hiszi, járjon utána!

Szia(sztok)
Nagyon jó írás de mégse tudom userként a Network Managert haszálni (még úgy se ha root jogokat adok az usernek)
Root-ként persze megy
Véletlenül alapjaiból telepitettem Debian Wheezyt
E leírás alapján próbáltam:

http://szit.hu/doku.php?id=oktatas:linux:grafikus_fel%C3%BClet:h%C3%A1l…

/usr/share/polkit-1/actions filet azt írták nem szabad piszkálni

/etc/networks.interface

auto wlan0
iface wlan0 inet dhcp
wireless-essid [ESSID-m]
wireless-mode [Infrastructure]

de igy is próbáltam

auto wlan0
wpa-ssid ssidém
wpa-psk jelszavam

Wifi kártya Beoadcom BCM4312

lsmod | grep wl
wl 2418946 0
lib80211 12829
cfg80211 114445

A felhasználó tagja a netdev csoportnak

A jogokkal van a baja szerintem
Device disconnect failed

(32) Not authorized Disconnect connections

Szerkeszteni se engedi a beállítottakat, a hozzádas ablak feljön de nem enged semmit változtatni
Mit rontok el?

kösz a segítséget