VPN demono prisijungimo hook'ai veikia kaip demonas, ir tai paprastai reiškia, kad jie veikia kaip root. Tą akimirką, kai vienas iš šių hook'ų įrašo į kieno nors namų katalogą arba iš naujo paleidžia darbalaukio pagalbininką, jūs davėte tinklo įvykiui galimybę veikti kaip bet kuriam vietiniam naudotojui. Įprastas trumpasis kelias, nuskaityti naudotojo vardą iš aplinkos kintamojo ir jį perduoti, to neišsprendžia. Jis tik peržymi veiksmą, nepakeisdamas, kuri paskyra jį atlieka. Kas veikia, yra trijų dalių perdavimas, kuriame privilegijuotas žingsnis pasako, kas įvyko, o atskiras vienetas atlieka veiksmą su teisinga tapatybe.

Naudotojo vardas aplinkoje nėra tapatybės jungiklis

Unix sprendžia, ką procesas gali liesti, pagal savo efektyvų naudotojo ID, o ne pagal savo aplinkos eilutes. USER=alice nustatymas arba LOGNAME eksportavimas keičia, ką neatsargi programinė įranga atspausdina savo išvestyje; failų nuosavybės patikrose jis nieko nekeičia. Hook'as, veikiantis kaip root su šiuo kintamuoju, vis tiek atidaro Alice failus kaip root.

Vardai taip pat nėra tas pats vardas. Nuotolinės prieigos prisijungimas, vietinė Unix paskyra ir bendrasis sertifikato vardas yra trys identifikatoriai, kurie dažnai sutampa ir kartais ne. Naudotojas, kuris autentifikuojasi kaip a.smith, gali iš viso neturėti vietinės paskyros arba būti susiejamas su asmith per katalogų tarnybą. Bet kokia konstrukcija, kuri daro prielaidą, kad viena eilutė atlieka visus tris vaidmenis, suges prie pirmojo rangovo.

Taigi pirmas klausimas yra ne „kuris naudotojas prisijungęs“, o „kuri vietinė paskyra turi teisę atlikti šį veiksmą“. Atsakykite į tai iš savo paskyrų duomenų bazės, o ne iš to, ką atsiuntė klientas:

id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json

Trečioji komanda yra ta, kurią žmonės praleidžia. Jei tikslinis failas priklauso root, nes jį sukūrė ankstesnis hook'as, teisingai sukonfigūruotas naudotojo veiksmas nepavyks su leidimų klaida, kuri atrodo kaip systemd problema ir ja nėra.

Demonas lieka ten, kur yra

Pakeisti paties VPN tarnybos User= į Alice yra netinkama svirtis. Tai keičia, kaip demonas susieja sąsajas, skaito raktus, rašo savo būsenos failą ir valdo maršrutus, ir perkelia visą šią riziką į vienetą, kuris veikė. Demonui reikia jo privilegijų; tolesniam veiksmui ne.

Pažiūrėkite, ką vienetas iš tikrųjų daro, prieš jį liesdami. Dvi komandos pasako vykdymo tapatybę ir galiojančias tikslias komandų eilutes, įskaitant viską, ką pridėjo perrašymas:

systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server

Numatytame paketo diegime demonas yra root, o --up scenarijus tai paveldi. Patvirtinkite tai, o ne darykite prielaidą, nes sukietinta distribucija galėjo jį perkelti į atskirą paskyrą, o ranka rašytas drop-in gali paleisti hook'ą per apvalkalą su kitokiomis taisyklėmis.

Trys įvardytos dalys, vienas siauras trigeris

Išdėstymas, kuris išgyvena priežiūrą, turi įvykį, trigerį ir veiksmą. Demonas praneša, kad įvardyta sesija pakilo. Trigeris priima tą mažą faktą ir prašo vieno fiksuoto veiksmo. Veiksmas veikia pagal tą vietinę paskyrą, kuriai priklauso liečiami failai. Niekas grandinėje nepriima savavališko komandos kelio.

Pats veiksmas yra įprastas tarnybos vienetas, o tapatybė yra viena direktyva jo viduje:

[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i

Atkreipkite dėmesį, kad User=alice galioja visam vienetui, ir systemd dokumentuoja vieną išimtį, kurią verta žinoti: komanda su priešdėliu + vis tiek veikia su visomis privilegijomis. Tas priešdėlis yra teisėtas įrankis vienam privilegijuotam žingsniui ir patogus būdas panaikinti ką tik sukurtą atskyrimą, todėl bet kurį + tame vienete traktuokite kaip tai, ką reikia pagrįsti peržiūroje.

Laikykite trigerio įvestį minimalią ir ne slaptą. Sesijos identifikatorius, susieta paskyra ir laiko žyma paprastai yra viskas, ko reikia. Niekada neperduokite per ribą shell fragmento, vykdomojo failo kelio ar kliento pateikto aplinkos bloko, nes priimanti pusė neturi būdo atskirti teisėtos reikšmės nuo įterptos.

Patikrinkite, kuri tapatybė iš tikrųjų veikė

Konfigūracijos peržiūra nėra įrodymas. Po patvirtinto bandomojo prisijungimo patvirtinkite UID, kuris palietė failą, ir UID, kurį demonas vis dar naudoja:

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

Pirmoje eilutėje turėtų būti Alice ir laiko žyma jūsų bandymo lange. Antroje vis dar turėtų būti root arba paketo tarnybos paskyra, kas įrodo, kad demonas nepasistūmė. Trečioji yra pigiausias būdas išbandyti veiksmo leidimus nelaukiant tikro pakartotinio prisijungimo.

Jei failo savininkas yra Alice, bet jo grupė ar režimas pasikeitė tarp paleidimų, ieškokite UMask= arba katalogo leidimų skirtumo, o ne logikos klaidos. Jei laiko žyma visai nepasistūmėjo, trigeris niekada nesuveikė, ir naudingas kitas žingsnis yra journalctl -u veiksmo vienetui, o ne dar vienas kliento pakartotinis prisijungimas.

Ko prisijungimo įvykis vis dar neįrodo

Nustatytas tunelis yra vienas faktas. Tai nereiškia, kad darbalaukio sesija atrakinta, sesijos magistralė pasiekiama arba kad privatus išteklius, kurio nori veiksmas, jau prieinamas. oneshot vienetas pagal Alice UID turi jos tapatybę ir nieko iš jos sesijos, todėl viskas, kam reikia grafinės magistralės, turi eiti per palaikomą naudotojo sesijos mechanizmą ir apibrėžti, kas vyksta, kai ji atsijungia.

Pakartotiniai prisijungimai taip pat kartojasi. Nešiojamasis kompiuteris, kuris miega traukinyje, per valandą gali sukelti tuziną prisijungimo įvykių, o hook'as, kuris kiekvieną kartą prideda eilutę, būsenos failą paverčia žurnalu, kurio niekas negali perskaityti. Padarykite veiksmą idempotentišką arba leiskite jam pakeisti vieną įrašą, raktuotu pagal sesiją.

Galiausiai apribokite žalos spindulį pačiame vienete: tik skaitomas failų sistemos vaizdas už būsenos katalogo ribų, jokių naujų privilegijų ir aiškus laiko limitas. Demono ir naudotojo veiksmo atskyrimas vertas pats savaime, bet jis vertas daug daugiau, kai veiksmas negali padaryti nieko kito, išskyrus tą vieną dalyką, kurį patvirtinote.

Susiję straipsniai