Kategória: Linux všeobecne

Zmenené: 26. august 2011

Vypínanie a PolicyKit

Nie je to tak dávno, čo som písal článok o vypínaní a dialógu potvrdenia vypnutia v KDE. Príchodom nového GDM3 som sa problémom stretol znova, hoci v trochu prijateľnejšej a hlavne riešiteľnejšej podobe, a to pomocou PolicyKit. V článku ukážem ako si PolicyKit prispôsobiť na svoj obraz…

V čom je problém?

Ono to vlastne nie je problém, ale ak sa pokúsite vypnúť počítač z grafického prostredia a k počítaču je prihlásený ešte niekto, napríklad cez SSH alebo hoci cez konzolu, systém si vyžiada potvrdenie vypnutia zadaním vášho hesla. Ono je to v istých prípadoch vlastne veľmi užitočné už sa mi stalo, že som omylom vypol LTSP server, pretože ma neupozornil na to, že ho vypínať vlastne nemám, len sa odhlásiť. Stačila chvíľka nepozornosti a na chvíľu som pokazil zážitok asi desiatim ľuďom (našťastie len pri ukážke).

V prípade môjho osobného počítača ma to ale otravuje, pretože k tomu dochádza vtedy, keď kvôli nejakej úlohe (najčastejšie nový ovládač grafickej karty) potrebujem pracovať v konzole (mimo X server) a samozrejme sa zabudnem odhlásiť. Potom chcem počíta vypnúť a on chce po mne heslo… I tu to síce má opodstatnenie, pretože takto som upozornený, že je prihlásený aj niekto iný (napr. útočník), ale to nie je môj prípad. Našťastie, po prechode na XFCE je ukončovanie relácie oveľa rýchlejšie, a preto nestihnem od počítača odísť pred objavením sa dialógu, a tak sa mi nestáva, že keď sa po niekoľkých hodinách vrátim je počítač stále zapnutý a čaká na potvrdenie vypnutia (ako sa mi to stávalo pri KDE).

GDM verzie 2 na to malo konfiguračnú voľbu, ktorou sa toto overovanie dalo vypnúť, konfigurácia GDM3 je trochu problematická, najmä ak nepoužívate GNOME, takže neviem či túto voľbu má alebo nie. Každopádne však Debian na overenie práv vypnutia používa PolicyKit teda sadu (systémových) politík. Začnem teda skráteným popisom týchto politík.

Ak vás trápi len prihlásenie v konzole, tak sa neprihlasujte ako root, ale pod vlastným účtom a celým týmto problémom sa vyhnete, ale to by som prišiel o krásny príklad nastavovania…

PolicyKit

PolicyKit je, podľa oficiálnej stránky, sada nástrojov na aplikačnej úrovni, ktorá sa o definovanie a obsluhu politík (pravidiel), na základe ktorých môžu bežný používatelia vykonávať chránené (privilegované) operácie. Inými slovami, je to sada pravidiel, podľa ktorých môžu bežní používatelia robiť to, čo by inak mohol robiť iba root.

Systémové politiky sú definované pomocou tzv. akcií, ktoré sú uložené v súboroch v adresári /usr/share/polkit-1/actions/ vo formáte XML, pričom v jednom súbore môže byť (a aj je) definovaných viacero akcií. každá akcia má, okrem popisu, definované práva na vykonanie.

Zoznam definovaných akcií môžete získať pomocou príkazu pkaction aj ako bežný používateľ. Výstupom príkazu je zoznam všetkých definovaných politík, pričom ak politika nejakej akcie nie je definovaná, je to rovnaké akoby bola táto akcia používateľovi zakázaná.

Politika vypnutia

Keďže zoznam politík môže byť dosť rozsiahly, zameriam sa na politiku vypnutia/reštartu systému. Ako ju/ich nájsť? No, zo začiatku asi skôr odhadom, ale v mojom prípade som z výpisu dostupných akcií vybral štyri:

  • org.freedesktop.consolekit.system.restart
  • org.freedesktop.consolekit.system.restart-multiple-users
  • org.freedesktop.consolekit.system.stop
  • org.freedesktop.consolekit.system.stop-multiple-users

Dúfam, že budete so mnou súhlasiť, že ich identifikácia podľa mena akcie nebola veľmi zložitá. Ostáva nájsť v ktorom súbore sú tieto akcie definované. Keďže sú však všetky akcie v jednom adresári, ani to nie je problém a pomôže mi grep :

grep "org.freedesktop.consolekit.system" * | cut -d: -f1 | sort -u
org.freedesktop.consolekit.policy

Ako vidno, všetky tieto akcie sú definované v jednom súbore org.freedesktop.consolekit.policy, ktorý je súčasťou balíka consolekit. Keď sa pozriete do tohoto súboru, zistíte, že politiky akcií sú definované vcelku prehľadne vo formáte XML. Aby som vec zjednodušil, zameriam sa na akciu org.freedesktop.consolekit.system.stop-multiple-users, ktorá má vlastne na svedomí ten odporný potvrdzovací dialóg. Definícia tejto akcie vyzerá takto:

<action id="org.freedesktop.consolekit.system.stop-multiple-users">
    <description>Stop the system when multiple users are logged in</description>
    <message>System policy prevents stopping the system when other users are logged in</message>
    <defaults>
        <allow_inactive>no</allow_inactive>
        <allow_active>auth_admin_keep</allow_active>
    </defaults>
</action>

Celá definícia politiky akcie takto vlastne pozostáva z definície mena akcie (action id), popisu a správy, ktoré teraz nie sú dôležité, ale iste pomôžu pri identifikácii určenia akcia, a hlavne definície predvolených práv. Predvolené práva sú dve:

  • allow_inactive – definuje právo vykonania programom, ktoré nie sú v aktívnej relácii
  • allow_active – definuje právo vykonania programom, ktoré sú súčasťou aktívnej relácie

Aktívna relácia (session) je tá, s ktorou sa práve pracuje, a hlavne je registrovaná pomocou consolekit, ale o toto sa stará systém na pozadí. Reda presnejšie program, ktorý sa stará o prihlásenie sa o to má postarať (to platí pre login, GDM, KDM, ale napríklad neplatí pre SLIM). Ďalej budem predpokladať, že používate tekého správcu prihlásenia, ktorý používa PolicyKit, a teda bude ma zaujímať právo aktívnej relácie, ale možnosti ich nastavenia sú rovnaké.

Možné hodnoty predvoleného práva sú:

  • no – prístup odmietnutý;
  • yes – prístup povolený;
  • auth_self – prístup povolený po zadaní svojho hesla;
  • auth_self_keep – prístup povolený po zadaní svojho hesla a toto povolenie je uchované do konca aktuálnej relácie;
  • auth_admin – prístup povolený po zadaní administrátorského hesla
  • auth_admin_keep – prístup povolený po zadaní administrátorského hesla a toto povolenie je uchované do konca aktuálnej relácie

Keď sa pozriete na definíciu akcie, tak už možno tušíte príčinu otravného dialógu áno, právo je udelené až po overení heslom administrátora. Ako to, že mi stačí zadať vlastné heslo?

Definícia administrátora

V tejto časti sa pokúsim dať odpoveď na otázku, prečo spomínaný dialóg vyžaduje na vypnutie moje heslo a nie heslo používateľa root. Najprv základná otázka existencie, ľudstva a vôbec… Teda, kto je to administrátor? Väčšinu používateľov Linuxu napadne používateľ root. V Debiane to problém nie je, ale napríklad také Ubuntu prichádza v predvolenej inštalácii s používateľom root, ktorý je zablokovaný, a tak by celé policykit bolo nepoužiteľné, pretože nemôžete zadať heslo, ktoré nie je nastavené.

Nenastavené heslo tu myslím vo význame zablokovaný používateľ, nie prázdne heslo.

PolicyKit prichádza s definíciou tzv. identít administrátorov (AdminIdentities), ktoré sú definované pomocou tzv. lokálnej autority (local authority). Ako ukážem neskôr, definícia lokálnej autority slúži aj na iné účely, zatiaľ však ostanem pri definícii administrátorov.

Konfigurácia lokálnej autority je definovaná v súboroch v adresára /etc/polkit-1/localauthority.conf.d/. Kompletný popis určenia jednotlivých podadresárov lokálnej autority nájdete v manuálovej stránke pklocalauthority(8). Spomínaný adresár v Debiane vo východzom stave obsahuje dva súbory balíka policykit-1.

Prvý zo súborov, 50-localauthority.conf, obsahuje (okrem poznámky aby ste he nemenili, lebo bude pri aktualizácii prepísaný):

[Configuration]
AdminIdentities=unix-user:0

A druhý, 51-debian-sudo.conf, obsahuje (už bez poznámky o aktualizácii):

[Configuration]
AdminIdentities=unix-group:sudo

Prvý súbor definuje ako administrátora používateľa s UID 0, teda používateľa root. Druhý súbor prepisuje toto nastavenie na členov skupiny sudo. Takže aby používateľ mohol vypnúť stroj, na ktorom sú prihlásení aj iní používatelia, musí byť členom skupiny sudo a na overenie musí zadať svoje heslo.

Ak chcete použiť inú skupinu, tak prepíšte jej meno v tomto súbore alebo pridajte nový súbor, ktorého meno bude začínať dvojciferným číslom väčším ako 51 (aby bol spracovaný až po týchto dvoch) a končiť príponou .conf. Samozrejme, môžete ako identity administrátora použiť kombináciu používateľov a skupín. Ak napríkald vytvoríte súbor /etc/polkit-1/localauthority.conf.d/60-local.conf s obsahom:

[Configuration]
AdminIdentities=unix-user:slavko;unix-user:janko;unix-group:staff

Budú za administrátorov považovaní používatelia slavko, janko a všetci členovia skupiny staff. Aby sa zmeny prejavili netreba nič reštartovať stačí uložiť súbor…

Kontrola nastavení

Keď už viete kto je to administrátor, respektíve ako nastaviť administrátorov pre PolicyKit, je ten správny čas pozrieť sa na to, ako sa dajú nastavenia akcií PolicyKit prezerať a kontrolovať, čo je veľmi dôležité, keď v nich robíte zmeny. K dispozícii sú dva programy: pkaction a pkcheck.

pkaction

Nástroj pkaction slúži na zobrazenie východzích hodnôt registrovanej (definovanej) akcie. Ako som už spomenul vyššie, keď ho spustíte bez volieb, vypíše všetky registrované akcie. Ak použijete len voľbu –verbose, vypíše ku každej akcii aj jej nastavenia. Mňa však teraz zaujíma konkrétna akcia, ktorú možno definovať pomocou voľby –action-id:

pkaction --verbose --action-id org.freedesktop.consolekit.system.stop-multiple-users
org.freedesktop.consolekit.system.stop-multiple-users:
    description: Stop the system when multiple users are logged in
    message: System policy prevents stopping the system when other users are logged in
    vendor:
    vendor_url:
    icon:
    implicit any: no
    implicit inactive: no
    implicit active: auth_admin_keep

pkcheck

Narozdiel od predchádzajúceho príkazu, nástroj pkcheck kontroluje, či má daný proces právo vykonať zadanú akciu. Príkazu je treba zadať minimálne dva parametre, a to –process s číslom procesu, ktorý vykonáva akciu a –action-id s identifikátorom akcie, ktorá má byť vykonávaná. Výsledkom je potom návratová hodnota, ktorá je:

  • 0, ak je proces oprávnený akciu vykonať,
  • iné, ak ju vykonať oprávnený nie je.

Takže príkladom otestovania práv na vypnutie systému, keď sú prihlásení viacerí používatelia bude ($$ je špeciálna premenná shellu, ktorá obsahuje PID aktuálneho shellu):

pkcheck --process $$ \
        --action-id org.freedesktop.consolekit.system.stop-multiple-users
polkit\56retains_authorization_after_challenge=1
Authorization requires authentication and -u wasn't passed.

echo $?
2

Vo výpise vidíte poznámku, že autorizácia vyžaduje overenie (tj. zadanie hesla), a keďže som overenie neurobil, návratová hodnota nie je 0, čiže oprávnenie nebolo udelené. Aby som mohol zadať heslo, musím pridať ďalší parameter, a to –allow-user-interaction:

pkcheck --process $$ \
        --action-id org.freedesktop.consolekit.system.stop-multiple-users \
        --allow-user-interaction
polkit\56dismissed=true
polkit\56retains_authorization_after_challenge=true
Authentication request was dismissed.
Overenie totožnosti PolicyKit

Overenie totožnosti PolicyKit

Spustenie príkazu otvorí dialógové okno, podobné tomu na obrázku (obrázok je konkrétne na reštart), ktoré poskytuje možnosť zadania hesla. Ak sú za administrátorov považovaní viacerí používatelia, je tu aj možnosť výberu príslušného administrátora z rozbaľovacieho zoznamu.

Tento výpis ukazuje výsledok, keď som autentifikačný dialóg zrušil, v prípade, že zadáte správne heslo, bude výstup programu vyzerať takto:

polkit\56retains_authorization_after_challenge=true
polkit\56temporary_authorization_id=tmpauthz1

Zaujímavý je druhý riadok výpisu, kde PolicyKit informuje, že bol vytvorený dočasný overovací token, takže nasledujúce spustenie rovnakého príkazu už nebude vyžadovať zadanie hesla (podrobnosti neskôr).

Pomocou príkazu pkcheck si môžete vypísať zoznam dočasný overovacích tokenov:

pkcheck --list-temp
authorization id: tmpauthz1
action:           org.freedesktop.consolekit.system.stop-multiple-users
subject:          unix-process:3318:35032 (/bin/bash)
obtained:         3 min 35 sec ago (Fri Aug 26 14:09:32 2011)
expires:          1 min 24 sec from now (Fri Aug 26 14:14:31 2011)

Alebo ich môžete (všetky) vymazať, takže pri ďalšom použití bude treba znova zadať heslo:

pkcheck --revoke-temp

Vlastné politiky

Keď už teraz viete, kde sú definované politiky a ako si ich zobraziť a vyskúšať, môžete sa pustiť do prispôsobovania politík. Prispôsobím si tu politiku vypínania systému, keď sú prihlásení viacerí používatelia tak, aby nevyžadovala heslo.

Aj toto prispôsobovanie sa robí v adresári lokálnej autority, ale tentokrát v adresári /etc/polkit-1/localauthority/50-local.d a súbor musí mať príponu .pkla. Podrobnosti o význame jednotlivých aresárov lokálnej autority nájdete v manuálovej stránke pklocalauthority(8). Meno súboru lokálnej politiky musí rešpektovať mennú schému tak, aby bola zaistená jednoznačnosť názvu súboru, čo však v prípade lokálnej politky nie je až také dôležité, ale je dobré to rešpektovať. Schéma mena vraví o použití opačného zápisu DNS a prípony .pkla, takže lokálny politika sa môže volať localhost.pkla.

Formát súboru je prostý súbor INI, teda obsahuje mená sekcií v lomených zátvorkách, nasledované dvojicami kľúč=hodnota. Meno sekcie je v podstate ľubovoľné, len musí byť v danom súbore jedinečné a je dobré ho voliť popisné, aby bolo jasné, čo sekcia obsahuje.

V sekcii sú platné nasledujúce kľúče:

  • Identity – bodkočiarkou oddelený zoznam identít, ktoré začínajú unix-user: alebo unix-group:;
  • Action – bodkočiarkou oddelený zoznam akcií;
  • ResultActive – vrátený výsledok overenia pre procesy aktívnej relácie;
  • ResultInactive – vrátený výsledok overenia pre procesy, ktoré nie sú súčasťou aktívnej relácie;
  • ResultAny – vrátený výsledok overenia pre všetky procesy, teda ako v aktívnej, tak i v neaktívnej relácii.

Každá sekcia pritom musí mať definované kľúče Identity a Action a aspoň jeden z kľúčov Result. Kľúče Result môžu nadobúdať rovnaké hodnoty ako predvolené akcie (no, yes, auth_self, auth_self_keep, auth_admin, auth_admin_keep).

Pamätáte si ešte ako je nastavená akcia org.freedesktop.consolekit.system.stop-multiple-users? Východzia politika jej nastavuje no pre neaktívne relácie a auth_admin_keep pre aktívne relácie. Práve nastavenie auth_admin_keep má za následok nutnosť prvý krát sa overiť pomocou hesla. Výsledok overenia je potom uložený až do ukončenia relácie v spomenutom dočasnom overovacom tokene. Aby som teda doma nemusel zadávať heslo, vytvorím si súbor .pkla s obsahom:

[Slavko vypne bez hesla]
Action=org.freedesktop.consolekit.system.stop-multiple-users;org.freedesktop.consolekit.system.restart-multiple-users
Identity=unix-user:slavko
ResultActive=yes

V príklade vidíte, že som nastavil právo pre dve akcie naraz (aj vypnutie aj reštart), len pre používateľa slavko (unix-user:slavko). Právo samotné je nastavené pre aktívnu reláciu (ResultActive) a implicitne povoľuje vykonanie akcie (yes). Ak teraz skúsite príkaz na overenie akcie:

pkcheck --process $$ \
        --action-id org.freedesktop.consolekit.system.stop-multiple-users \
        --allow-user-interaction

Zistíte, že príkaz nič nevypíše a jeho návratová hodnota je 0, teda, že máte na vykonanie akcie mám právo bez ďalších obmedzení. Ostatní používatelia budú naďalej spracovaní predvolenou politikou, teda budú musieť zadať heslo niektorého z administrátorov.

Záver

PolicyKit (spolu s ConsoleKit) je mocný nástroj správy systémových práv, ktorý je ľahko a účinne prispôsobiteľný vlastným potrebám. Stačí len vedieť ako, a ja dúfam, že tento článok pomôže aspoň trochu poodhaliť jeho tajomstvá.