V tomto článku popíši, jak spouštět grafické aplikace pod jiným uživatelským účtem, avšak zobrazit je ve vašem aktuálním sezení (tzn. bez použití rychlého přepínání uživatelů). Článek zahrnuje rozličné úpravy nastavení systému, a tudíž není určený pro běžné uživatele bez pokročilých systémových znalostí. Instrukce jsou sepsány pro Fedoru 18.

Na vše, co je zde zmíněno, jsem přišel metodou pokus a omyl; v této oblasti nemám žádné hluboké znalosti. Některá doporučení nemusí být proto zcela správná. Bavil jsem se s pár kvalifikovanějšími lidmi a bylo mi řečeno, že Linux obecně požadovanou funkcionalitu plně nepodporuje a některé aplikace mohou vykazovat chyby nebo zcela nefungovat. Proto to považujte za částečné řešení v rámci možností – pro některé aplikace může fungovat perfektně, ale nelze předpokládat, že bude fungovat vždy.

Pozadí problému

Na svém počítači mám běžného uživatele kparal a druhého uživatele gamer, kterého používám pro několik případů:

  • Hraní her. V GNOME používám náhradní režim („Fallback mode“) abych získal trochu více grafického výkonu (mám hodně pomalou grafickou kartu a rozdíl je dost poznat).
  • Spouštění neznámých a „ne tak důvěryhodných“ nástrojů a skriptů, většinou stažených někde z internetu (tzn. ne zabalíčkovaných ve Fedoře). V těchto nástrojích neočekávám přímo škodlivý software, ale spíše závažné chyby. Mám mnohem lepší pocit, když vím, že daný neznámý skript mi nemůže omylem smazat žádná osobní data.

Bohužel používání druhého uživatelského účtu je často nepohodlné:

  • Pokud potřebuji přenést nějaký text (např. webový odkaz) z jednoho účtu do druhého, musím jej uložit do souboru, zkopírovat jej a nastavit oprávnění. Těžkopádné.
  • Pokud jsem zrovna přepnutý do sezení uživatele gamer, nevidím žádná upozornění od svých chatovacích klientů, emailových klientů, atp. běžících pod mým uživatelem kparal. Musím se pořád přepínat z jednoho účtu do druhého, abych si přečetl zprávy a odpověděl.
  • Pokud jsem zrovna přepnutý do sezení uživatele gamer, nemohu jednoduše přistoupit k souborům v domovském adresáři uživatele kparal. Můžete si říct, že o to přece jde, ale občas mi to hodně překáží, např. pokud bych si chtěl pustit na pozadí nějakou vlastní hudbu. Opět je nutné manipulovat se soubory, nastavovat oprávnění, atd. Otrava.

Přes víkend jsem si nainstaloval Steam. Samozřejmě jej pouštím pod uživatelem gamer. Ne jenom kvůli výkonu, ale také protože moje důvěra ve Steam není zdaleka stoprocentní. Steam stahuje a spouští spoustu externích binárních souborů. Věřím, že si Valve dává pozor, aby neměli žádný bezpečnostní incident (např. škodlivý software v některé z herních aktualizací), určitě mají vnitřní bezpečnostní kontroly a politiky, ale jak moc jsou důvěryhodné? Spouští Steam všechno v nějakém typu sandboxu? Nevím, a upřímně, spouštění Steamu (a desítek externích binárek, které spouští on) pod odděleným uživatelským účtem zní jako rozumný kompromis.

Když jsem chtěl ve Steamu koupit novou hru, potřeboval jsem se přihlásit do Moneybookers. Moje hesla do platebních portálů ale většinou obsahují cca 20 náhodných znaků a mám je bezpečně uložené ve správci hesel pod uživatelem kparal. V té chvíli jsem se rozzlobil. Heslo je příliš dlouhé, abych si ho zapamatoval. Nápad opsat si jej na papír mě urazil (k čemu tedy máme ty technologie?) a nechtěl jsem podstupovat obvyklou proceduru ukládání souboru s textem na disk. Asi to byl takový vrtoch. Jak tedy to heslo přenést? Proč si proboha nemohu spustit Steam běžící pod uživatelem gamer, ale zobrazený v mém obvyklém prostředí uživatele kparal, a prostě to vložit přes schránku? Windows to umí!

Jak se ukázalo, tak v Linuxu to více méně jde zprovoznit také, ale vyžaduje to pár úprav. Poté můžete spouštět aplikace pod jiným uživatelským účtem a zobrazovat si je ve svém sezení. Pojďme se podívat, jak na to.

Základní zobrazení aplikace

Pokud se přihlásíte s použitím su a spustíte ukázkovou grafickou aplikaci (v tomto případě kalkulačku), vše by mělo fungovat automaticky:

kparal@kraken ~ $ su - gamer -c gcalctool
Heslo: 

** (gcalctool:3969): WARNING **: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.

** (gcalctool:3969): CRITICAL **: unable to create directory '/run/user/1000/dconf': Operace zamítnuta.  dconf will not work properly.
(opakováno mnohokrát)

Je tam varování ohledně sběrnice pro přístupnost, ale ještě jsem neviděl, že by to mělo nějaké negativní následky, takže to pokládám za poměrně neškodné. Ty hlášky týkající se dconf jsou zřejmě chyba a může to způsobit nekorektní chování aplikace – nastavení aplikace nemusí jít načíst nebo uložit. Pokud tyto hlášky vidíte, měli byste nejprve zrušit proměnnou XDG_RUNTIME_DIR:

kparal@kraken ~ $ su - gamer
Heslo:
gamer@kraken ~ $ unset XDG_RUNTIME_DIR
gamer@kraken ~ $ gcalctool

 ** (gcalctool:3969): WARNING **: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.

V tomto bodě by měla většina vašich grafických aplikací fungovat správně (jediný problém, který jsem našel, je, že globální nabídka GNOME u nich nefunguje). Některá funkcionalita ovšem být ztracena může, zvláště pokud se váš program pokouší komunikovat s jinými procesy přes D-Bus. Dle informací, které jsem posbíral, by v některých případech mohlo pomoct spustit aplikaci přes dbus-launch:

gamer@kraken ~ $ dbus-launch vaše-aplikace

Ještě jsem neviděl žádnou aplikaci, která by to vyžadovala, takže nemohu poskytnout více podrobností. Obecně, pokud vidíte jakékoliv chyby týkající se D-Busu. očekávejte, že ne vše musí fungovat správně. Ale často vám to nemusí vadit, záleží na úkonech, které potřebujete s danou aplikací provést.

Použití sudo místo su

Já osobně raději používám sudo místo su, protože si jistou dobu pamatuje vaše heslo, a dá se i nastavit na přihlášení bez hesla. Tento přístup ale není tak přímočarý a jednoduchý jako ten předchozí a vyžaduje některé úpravy. Touto sekcí se řiďte, pouze pokud vám nevyhovuje přihlášení pomocí su.

Ve výchozím stavu uvidíte následující výstup při použití příkazu sudo (a aplikace se nespustí):

kparal@kraken ~ $ sudo -i -u gamer gcalctool
No protocol specified

** (gcalctool:5113): WARNING **: Could not open X display
No protocol specified

(gcalctool:5113): Gtk-WARNING **: cannot open display: :0

To je způsobeno tím, že oprávnění vašeho X serveru nedovolují připojit se nikomu dalšímu (pokud tomu správně rozumím):

kparal@kraken ~ $ xhost
access control enabled, only authorized clients can connect
SI:localuser:kparal

Pokud chcete použít sudo místo su, musíte povolit uživateli gamer, aby mohl zobrazit okno aplikace ve vašem sezení. Nějak takto:

kparal@kraken ~ $ xhost +si:localuser:gamer
localuser:gamer being added to access control list

kparal@kraken ~ $ xhost
access control enabled, only authorized clients can connect
SI:localuser:gamer
SI:localuser:kparal

Nyní to zkuste znovu:

kparal@kraken ~ $ sudo -i -u gamer gcalctool

Kalkulačka by se měla nyní v pořádku zobrazit. Příkaz xhost se musí spouštět po každém spuštění vašeho sezení, tak jsem jej chtěl původně přidat do ~kparal/.xprofile, až na to, že Fedora tento soubor nespouští. Takže nakonec jsem jej přidal do ~kparal/.profile takto:

# povolit uživateli gamer zobrazovat aplikace na tomto X serveru
# (ale vynechat místní připojení bez X a vzdálená připojení)
if [ -n "$DISPLAY" -a -z "$SSH_CLIENT" ]; then
    xhost +si:localuser:gamer
fi

Nyní jsem použil výše uvedený příkaz na spuštění Steamu ve svém sezení a pohodlně jsem vložil své heslo pro Moneybookers. Úspěch!

Zvuk

Poměrně rychle jsem zjistil, že pro takto přesměrované aplikace nefunguje přehrávání zvuku. Je škoda, že nemáme vyřešené, aby to fungovalo automaticky, ale naštěstí se to dá velmi jednoduše spravit.

Nejprve si nainstalujte a spusťte paprefs a zaškrtněte Povolit přístup ze sítě na místní zvuková zařízení. Netuším, jaké konfigurační soubory to upravuje, protože se nic nezměnilo ani v ~/.pulse ani v /etc/pulse. Ale lze nyní vidět server PulseAudio, jak poslouchá přes TCP/IP na příchozí síťová spojení. Měl by vyžadovat autorizaci, takže se nemusí bát, že by vás někdo odposlouchával.

Nyní zkuste přehrát nějaký zvuk:

kparal@kraken ~ $ su - gamer -c paplay /usr/share/sounds/alsa/Front_Center.wav

(nebo prostě spusťte Totem/Firefox/atd)

Pokud máte štěstí (na rozdíl ode mne), váš zvuk bude nyní fungovat perfektně. Ale pokud je démon PulseAudio z nějakého důvodu restartován (spadne nebo jej zabijete a spustíte znovu), tak přehrávání nadále nefunguje a musíte se znovu přihlásit do svého sezení. To je pravděpodobně chyba. Já jsem to nevěděl, takže jsem strávil hodiny čtením dokumentace k PulseAudiu. Není to úplně povznášející zážitek.

Pokud vám automatické směrování zvuku nefunguje, nebo potřebujete přehrávat zvuk i poté, co restartujete PulseAudio, toto je postup, který jsem nedobrovolně objevil:

  1. Můžete zkopírovat ~kparal/.pulse-cookie do ~gamer/.pulse-cookie (a opravit vlastnictví souboru). To vám zajistí autentizaci.
  2. Poté můžete přesměrovat zvuk tak, že se přes sudo přihlásíte jako gamer, nastavíte proměnnou PULSE_SERVER=localhost a spustíte aplikaci, kterou potřebujete.

(Také by mělo být nějak možné přesměrovat zvuk pomocí unix soketů místo TCP/IP soketů, ale ta prokletá dokumentace mi v tomto úkolu vůbec nepomohla.)

Grafická akcelerace

Najděte dva rozdíly:

kparal@kraken ~ $ glxinfo | grep render
direct rendering: Yes
OpenGL renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset

a

kparal@kraken ~ $ su - gamer -c glxinfo | grep render
Heslo:
libGL error: failed to load driver: i965
libGL error: Try again with LIBGL_DEBUG=verbose for more details.
direct rendering: Yes
OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 0x301)

Ano, vaše přesměrovaná aplikace nemají přístup k 3D akceleraci. Tady je podrobnější chybová zpráva:

kparal@kraken ~ $ su - gamer
Heslo:
gamer@kraken ~ $ LIBGL_DEBUG=verbose glxinfo | grep render
libGL: OpenDriver: trying /usr/lib64/dri/i965_dri.so
libGL error: failed to open drm device: Permission denied
libGL error: failed to load driver: i965
libGL: OpenDriver: trying /usr/lib64/dri/swrast_dri.so
libGL: Can't open configuration file /home/gamer/.drirc: No such file or directory.
direct rendering: Yes
OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 0x301)

Zkusil jsem spustit chromium-bsu a extremetuxracer, obojí běželo okolo 30 FPS za použití softwarového vykreslování. S tím se hrát nedá.

Naštěstí jsem objevil příčinu. Jedná se o přístupová práva k souboru /dev/dri/card0, který představuje vaši grafickou kartu. Pokud se přihlásíte do standardního grafického sezení, některý z démonů (pravděpodobně logind) vám udělí dočasná rw práva k tomuto souboru pomocí ACL:

kparal@kraken ~ $ getfacl /dev/dri/card0 
getfacl: Removing leading '/' from absolute path names
# file: dev/dri/card0
# owner: root
# group: video
user::rw-
user:kparal:rw-
group::rw-
mask::rw-
other::---

Ale pokud se přihlásíte pomocí su nebo sudo, tak daná práva neobdržíte. Našel jsem dvě možná řešení. Prvním je přidat ACL práva pro uživatele gamer ručně po každém startu počítače:

kparal@kraken ~ $ sudo setfacl -m user:gamer:rw /dev/dri/card0

Toto můžete přidat například do /etc/rc.d/rc.local, aby se to automaticky spouštělo při startu. Druhou možností je přidat uživatele gamer do skupiny video, která vlastní tento soubor. V tomto případě nic nemusíte spouštět při startu, změna je trvalá.

Nyní by vaše 3D aplikace měly fungovat správně:

kparal@kraken ~ $ su - gamer -c glxinfo | grep render
Heslo:
direct rendering: Yes
OpenGL renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset

Těch pár jednoduchých her, co jsem vyzkoušel, nyní běží plnou rychlostí.

Chci ovšem upozornit, že pokud takto trvale zvýšíte práva uživatele gamer, tak to přináší jisté bezpečnostní implikace. Pokud bude tento účet kompromitován, tak vám útočník může přistupovat k vaší grafické kartě nebo i videokameře (pouze pokud jste uživatele přidali do skupiny video, protože tato skupina zároveň kontroluje přístup k videokameře), to vše na dálku. Z tohoto důvodu mi první přístup přijde o něco bezpečnější (omezuje množství přístupných zařízení) a určitě byste měli uživateli gamer zakázat jakékoliv vzdálené přihlášení (např. zakázat tento účet v nastavení vašeho serveru SSH).

Závěr

Nyní konečně mohu zobrazovat grafické aplikace (dokonce i hry) z jiného uživatelského účtu ve svém aktuálním sezení. Zabralo mi nějaký čas na dané postupy přijít. Je velmi pravděpodobné, že jsem spoustu problémů vyřešil špatným (nebo neoptimálním) způsobem. Znáte nějaký nástroj, který by dokázal všechno toto nastavování vyřešit sám za uživatele? Nebo znáte funkční nástroj na sandboxing aplikací, který by pro tyto účely fungoval? Podělte se v diskuzi s vašimi nápady a zlepšeními. Díky.

Zdroj: blog autora.