Hookovi veze na VPN daemonu rade kao daemon, a to obično znači da rade kao root. U trenutku kada jedan od tih hookova zapiše u nečiji početni direktorij ili ponovno pokrene pomoćnika radne površine, dali ste mrežnom događaju mogućnost da djeluje kao bilo koji lokalni korisnik. Uobičajeni prečac, pročitati korisničko ime iz varijable okoline i proslijediti ga, to ne ispravlja. On samo preimenuje radnju bez promjene računa koji je izvodi. Ono što funkcionira je trodijelna predaja u kojoj privilegirani korak kaže što se dogodilo, a zasebna jedinica izvodi radnju pod ispravnim identitetom.

Korisničko ime u okolini nije prekidač identiteta

Unix odlučuje čega se proces smije dotaknuti prema svom efektivnom korisničkom ID-u, a ne prema nizovima u svojoj okolini. Postavljanje USER=alice ili izvoz LOGNAME mijenja što nemarna programska oprema ispisuje u svoj izlaz; ne mijenja ništa u provjerama vlasništva datoteka. Hook koji radi kao root s tom varijablom i dalje otvara Alicine datoteke kao root.

Ni imena nisu isto ime. Prijava za daljinski pristup, lokalni Unix račun i uobičajeno ime certifikata tri su identifikatora koji se često podudaraju, a ponekad ne. Korisnik koji se autentificira kao a.smith možda nema nikakav lokalni račun ili se preslikava na asmith putem usluge imenika. Svaki dizajn koji pretpostavlja da jedan niz služi sve tri uloge slomit će se već na prvom izvođaču.

Dakle prvo pitanje nije „koji je korisnik povezan“ nego „kojem lokalnom računu je dopušteno izvesti ovu radnju“. Odgovorite na to iz vlastite baze podataka o računima, a ne iz onoga što je klijent poslao:

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ća naredba je ona koju ljudi preskaču. Ako je ciljna datoteka u vlasništvu roota jer ju je stvorio prethodni hook, ispravno konfigurirana korisnička radnja neće uspjeti s pogreškom dopuštenja koja izgleda kao problem sustava systemd i nije.

Daemon ostaje tamo gdje jest

Promijeniti vlastiti User= VPN usluge u Alice pogrešna je poluga. To mijenja kako daemon veže sučelja, čita ključeve, zapisuje svoju datoteku stanja i upravlja rutama, i premješta sav taj rizik u jedinicu koja je radila. Daemon treba svoje privilegije; naknadna radnja ne.

Pogledajte što jedinica zapravo radi prije nego je dotaknete. Dvije naredbe govore identitet izvođenja i točne naredbene retke na snazi, uključujući sve što je dodalo nadjačavanje:

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

Pri zadanom instaliranju paketa daemon je root i skripta --up to nasljeđuje. Potvrdite to umjesto da pretpostavljate, jer očvrsnuta distribucija mogla ga je premjestiti na namjenski račun, a rukom napisan drop-in može pokretati hook kroz omotač s drukčijim pravilima.

Tri imenovana dijela, jedan uzak okidač

Raspored koji preživljava održavanje ima događaj, okidač i radnju. Daemon izvješćuje da se imenovana sesija podigla. Okidač prihvaća tu malu činjenicu i traži jednu fiksnu radnju. Radnja radi pod lokalnim računom koji posjeduje datoteke koje dotiče. Ništa u lancu ne prihvaća proizvoljnu putanju naredbe.

Sama radnja obična je servisna jedinica, a identitet je jedna direktiva unutar nje:

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

Imajte na umu da User=alice vrijedi za cijelu jedinicu, a systemd dokumentira jedno izuzeće koje vrijedi znati: naredba s prefiksom + radi s punim privilegijama bez obzira na to. Taj je prefiks legitiman alat za jedan privilegirani korak i prikladan način da poništite razdvajanje koje ste upravo izgradili, zato svaki + u toj jedinici tretirajte kao nešto što treba opravdati u pregledu.

Držite ulaz okidača minimalnim i bez tajni. Identifikator sesije, preslikani račun i vremenska oznaka obično su sve što je potrebno. Nikada ne prenosite preko granice fragment ljuske, putanju izvršne datoteke ni blok okoline koji je dostavio klijent, jer strana koja prima nema načina razlikovati legitiman podatak od ubrizganoga.

Provjerite identitet koji je doista radio

Pregled konfiguracije nije dokaz. Nakon odobrene testne veze potvrdite UID koji je dotaknuo datoteku i UID koji daemon još koristi:

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

Prvi redak trebao bi pokazati Alice i vremensku oznaku unutar vašeg testnog prozora. Drugi bi trebao i dalje pokazivati root ili servisni račun paketa, što dokazuje da se daemon nije pomaknuo. Treći je najjeftiniji način provjere dopuštenja radnje bez čekanja na stvarno ponovno povezivanje.

Ako je vlasnik datoteke Alice, ali su se njezina grupa ili način promijenili između pokretanja, tražite UMask= ili razliku u dopuštenjima direktorija umjesto logičke pogreške. Ako se vremenska oznaka uopće nije pomaknula, okidač nikada nije opalio, a koristan sljedeći korak je journalctl -u za jedinicu radnje umjesto još jednog ponovnog povezivanja klijenta.

Što događaj veze još uvijek ne dokazuje

Uspostavljen tunel jedna je činjenica. To ne znači da je sesija radne površine otključana, da je sabirnica sesije dostupna ili da je privatni resurs koji radnja želi već dostupan. oneshot jedinica pod Alicinim UID-om ima njezin identitet i ništa od njezine sesije, pa sve što zahtijeva grafičku sabirnicu mora ići kroz podržani mehanizam korisničke sesije i definirati što se događa kad je odjavljena.

Ponovna povezivanja se također ponavljaju. Prijenosno računalo koje spava u vlaku može proizvesti desetak događaja veze u jednom satu, a hook koji svaki put doda redak pretvara datoteku stanja u zapisnik koji nitko ne može čitati. Učinite radnju idempotentnom ili joj dopustite da zamijeni jedan zapis s ključem po sesiji.

Naposljetku, ograničite radijus štete u samoj jedinici: prikaz datotečnog sustava samo za čitanje izvan direktorija stanja, bez novih privilegija i s izričitim vremenskim ograničenjem. Razdvajanje daemona i korisničke radnje vrijedno je samo po sebi, ali vrijedi mnogo više kada radnja ne može učiniti ništa osim one jedne stvari koju ste odobrili.

Povezani članci