Spúšťajte akciu po pripojení VPN ako používateľ, nie ako démon
Premenná prostredia s USER=alice nemení, pod ktorým účtom hook beží. Oddeľte udalosť, spúšťač a akciu a potom dokážte UID.
Hooky pripojenia v démonovi VPN bežia ako démon, a to zvyčajne znamená, že bežia ako root. V okamihu, keď jeden z týchto hookov zapíše do niekoho domovského adresára alebo reštartuje pomocníka pracovnej plochy, dali ste sieťovej udalosti schopnosť konať ako ľubovoľný lokálny používateľ. Zvyčajná skratka, teda prečítať používateľské meno z premennej prostredia a odovzdať ho ďalej, to neopravuje. Len premenuje akciu bez toho, aby zmenila, ktorý účet ju vykonáva. Funguje trojdielne odovzdanie, v ktorom privilegovaný krok povie, čo sa stalo, a samostatná jednotka vykoná akciu pod správnou identitou.
Používateľské meno v prostredí nie je prepínač identity
Unix rozhoduje, na čo proces smie siahnuť, podľa svojho efektívneho používateľského ID, nie podľa reťazcov vo svojom prostredí. Nastavenie USER=alice alebo export LOGNAME mení, čo neopatrný softvér vypíše do svojho výstupu; na kontroly vlastníctva súborov to nemení nič. Hook bežiaci ako root s nastavenou premennou stále otvára Alicine súbory ako root.
Ani mená nie sú to isté meno. Prihlásenie vzdialeného prístupu, lokálny unixový účet a všeobecný názov certifikátu sú tri identifikátory, ktoré sa často zhodujú a občas nie. Používateľ, ktorý sa autentifikuje ako a.smith, nemusí mať vôbec žiadny lokálny účet, alebo sa môže cez adresárovú službu mapovať na asmith. Akýkoľvek návrh, ktorý predpokladá, že jeden reťazec slúži všetkým trom rolám, sa zlomí na prvom dodávateľovi.
Prvá otázka teda nie je „ktorý používateľ je pripojený“, ale „ktorý lokálny účet smie túto akciu vykonať“. Odpovedzte na ňu z vlastnej databázy účtov, nie z toho, čo poslal klient:
id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json
Tretí príkaz je ten, ktorý ľudia preskakujú. Ak cieľový súbor vlastní root, pretože ho vytvoril predchádzajúci hook, správne nastavená používateľská akcia zlyhá s chybou oprávnenia, ktorá vyzerá ako problém systemd a nie je.
Démon zostáva tam, kde je
Zmeniť vlastný User= služby VPN na Alicu je nesprávna páka. Mení, ako démon viaže rozhrania, číta kľúče, zapisuje svoj stavový súbor a spravuje trasy, a presúva celé toto riziko do jednotky, ktorá fungovala. Démon potrebuje svoje oprávnenia; následná akcia nie.
Pozrite sa, čo jednotka skutočne robí, skôr než sa jej dotknete. Dva príkazy vám povedia identitu vykonávania a presné platné príkazové riadky vrátane všetkého, čo pridal súbor s prepisom:
systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server
Pri predvolenej inštalácii z balíka je démon root a skript --up to dedí. Potvrďte to namiesto predpokladu, pretože spevnená distribúcia ho mohla presunúť na vyhradený účet a ručne napísaný drop-in môže spúšťať hook cez obal s inými pravidlami.
Tri pomenované časti, jeden úzky spúšťač
Usporiadanie, ktoré prežije údržbu, má udalosť, spúšťač a akciu. Démon hlási, že pomenovaná relácia nabehla. Spúšťač prijme tento malý fakt a požiada o jednu pevnú akciu. Akcia beží pod lokálnym účtom, ktorý vlastní súbory, ktorých sa dotýka. Nič v reťazi neprijíma ľubovoľnú cestu príkazu.
Akcia samotná je obyčajná jednotka služby a identita je jedna direktíva v nej:
[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i
Všimnite si, že User=alice platí pre celú jednotku a systemd dokumentuje jednu výnimku, ktorú sa oplatí poznať: príkaz s predponou + beží s plnými oprávneniami bez ohľadu na to. Táto predpona je legitímny nástroj na jeden privilegovaný krok a pohodlný spôsob, ako zrušiť oddelenie, ktoré ste práve postavili, preto každý + v tejto jednotke berte ako niečo, čo treba v recenzii odôvodniť.
Udržujte vstup spúšťača minimálny a nie tajný. Identifikátor relácie, mapovaný účet a časová značka sú zvyčajne všetko, čo treba. Nikdy neposielajte cez hranicu fragment shellu, cestu k spustiteľnému súboru ani blok prostredia od klienta, pretože prijímajúca strana nemá ako rozlíšiť legitímnu hodnotu od vloženej.
Overte identitu, ktorá skutočne bežala
Kontrola konfigurácie nie je dôkaz. Po schválenom testovacom pripojení potvrďte UID, ktoré sa dotklo súboru, a UID, ktoré démon stále používa:
stat -c '%U %G %y %n' /home/alice/.local/state/vpn-status.json
ps -o user=,pid=,cmd= -p "$(pgrep -o -f 'openvpn --daemon')"
systemd-run --uid=alice --pipe /usr/local/bin/refresh-vpn-status --dry-run
Prvý riadok by mal ukázať Alicu a časovú značku v rámci vášho testovacieho okna. Druhý by mal stále ukazovať root alebo balíčkový servisný účet, čo dokazuje, že sa démon nepohol. Tretí je najlacnejší spôsob, ako otestovať oprávnenia akcie bez čakania na skutočné opätovné pripojenie.
Ak je vlastníkom súboru Alica, ale jeho skupina alebo režim sa medzi spusteniami zmenili, hľadajte UMask= alebo rozdiel v oprávneniach adresára, nie logickú chybu. Ak sa časová značka vôbec nepohla, spúšťač sa nikdy nespustil, a užitočným ďalším krokom je journalctl -u pre jednotku akcie, nie ďalšie opätovné pripojenie klienta.
Čo udalosť pripojenia stále nedokazuje
Nadviazaný tunel je jeden fakt. Neznamená, že je relácia pracovnej plochy odomknutá, že je dostupná zbernica relácie alebo že súkromný zdroj, ktorý akcia chce, je už dostupný. Jednotka oneshot pod Aliciným UID má jej identitu a nič z jej relácie, takže čokoľvek, čo vyžaduje grafickú zbernicu, musí ísť cez podporovaný mechanizmus používateľskej relácie a definovať, čo sa stane, keď sa odhlási.
Opätovné pripojenia sa tiež opakujú. Notebook, ktorý spí vo vlaku, môže za hodinu vygenerovať tucet udalostí pripojenia, a hook, ktorý zakaždým pridá riadok, premení stavový súbor na log, ktorý nikto neprečíta. Urobte akciu idempotentnou alebo jej dovoľte nahradiť jediný záznam kľúčovaný reláciou.
Nakoniec obmedzte polomer škôd v samotnej jednotke: pohľad na súborový systém len na čítanie mimo stavového adresára, žiadne nové oprávnenia a výslovný časový limit. Oddelenie démona a používateľskej akcie má cenu samo o sebe, ale má oveľa väčšiu cenu, keď akcia nemôže urobiť nič iné ako tú jedinú vec, ktorú ste schválili.