Kāpēc OpenVPN āķis neatrod failu blakus savam skriptam
Relatīvie ceļi āķī tiek atrisināti pret procesu, nevis pret skriptu. Noenkurojiet tos ar __file__, pēc tam pirms atļaujām pārbaudiet vārdu telpu un identitāti.
Āķi, kas darbojas bez kļūdām un tomēr ziņo par trūkstošu failu, parasti skatās nepareizajā vietā, nevis cieš neveiksmi savā darbā. Relatīvie ceļi skriptā tiek atrisināti pret procesa darba direktoriju, un pakalpojums sākas ar darba direktoriju, kuru jūs neizvēlējāties. Fails blakus skriptam un fails, kuru atver process, ir viens un tas pats tikai tad, kad kaut kas tos noenkuro. Šī plaisa izskaidro lielu daļu āķu kļūmju, kuras maldīgi nolasa kā atļauju problēmas.
Pārbaudiet ceļu pirms atļaujām, jo atļauju kļūda nepareizajā failā joprojām ir nepareizais fails.
Relatīvais ceļš tiek atrisināts pret procesu, nevis pret failu
Kad skripts izsauc open("policy.json"), kodols atrisina vārdu pret procesa pašreizējo darba direktoriju. Nekas no paša skripta atrašanās vietas šajā meklēšanā nepiedalās. OpenVPN sāk āķus no direktorijas, kuru tas pats izvēlas, un opcija cd to var mainīt, tāpēc skripts, kas pārbaudīts ar roku no savas mapes, uzvedas citādi, kad to palaiž dēmons. Manuālā pārbaude iztur, pakalpojuma palaišana neizdodas, un žurnāla rinda piemin tikai trūkstošo vārdu.
Python atklāj skripta atrašanās vietu kā __file__, un tieši tas padara noenkurošanu iespējamu. Path(__file__).resolve().parent / "policy.json" veido ceļu no faila, nevis no procesa. Šī viena rinda novērš atkarību no darba direktorijas, neko nemainot privilēģijās.
Apzināti noenkurojiet ceļu, tad pārbaudiet, ko dara resolve
resolve() seko simboliskajām saitēm, tāpēc instalācija, kas āķi piesaista vietā, noenkurojas saites mērķī, nevis direktorijā, kas satur saiti. Versijotā izvietošanā parasti tas ir vēlamais, un tas ir nepareizi izkārtojumam, kas gaida datus blakus simboliskajai saitei. Izlemiet, ko izvietošana domā, un rakstiet kodu atbilstoši, nevis atklājiet atšķirību produkcijā. Path(__file__).parent bez resolve() saglabā pašas saites direktoriju.
Ja dati pieder instancē, nevis programmai, ņemiet absolūtu ceļu no konfigurācijas. Cietā atrašanās vietas kodēšana piesaista āķi vienam resursdatora izkārtojumam.
Izejiet četras robežas pēc kārtas
Sāciet ar darba direktoriju: salīdziniet vienības WorkingDirectory, OpenVPN opciju cd un jebkuru apvalku, kas pirms exec nomaina direktoriju. Pēc tam apstipriniet atrisināto atrašanās vietu, jo faila ar līdzīgu nosaukumu citā izvietošanā var atbildēt uz meklēšanu un paslēpt kļūdu. Tālāk nāk failu sistēmas skats: chroot vai pakalpojuma mount vārdu telpa var absolūtu resursdatora ceļu vienkārši padarīt neesošu. Visbeidzot piekļuves identitāte, kas ir jautājums atsevišķi no redzamības.
ProtectHome un PrivateTmp slēpj dažādas atrašanās vietas, un neviens no tiem neparādās direktorija sarakstā, kas ņemts no resursdatora. Ceļš, kas pastāv root čaulā, var būt neredzams vienības vārdu telpā, un tāpēc tās pašas komandas pārbaude ārpus pakalpojuma pierāda tik maz.
Izlabojiet meklēšanu, nepaplašinot pakalpojumu
Ceļa noenkurošana atrisina tikai pirmo robežu. Tā neatklāj direktoriju, ko pakalpojums slēpj, un nedod nepiederošam kontam piekļuvi failam, kas paredzēts tikai root. script-security paaugstināšana maina, kādus skriptus OpenVPN palaidīs; tam nav nekādas ietekmes uz to, kur tiek atrisināts relatīvais vārds. Visam pakalpojumam darba direktorijas maiņa ir plašāka par problēmu, jo katrs cits relatīvais sertifikāta, žurnāla vai palīga ceļš pārvietojas līdzi.
Dodiet priekšroku šauram labojumam: deterministisks ceļš skriptā, skaidra konfigurācijas vērtība instances datiem un failu īpašumtiesības, kas atbilst kontam, ar kuru āķis faktiski darbojas.
Reģistrējiet pierādījumus, kas nosauc robežu
Noderīgs atteices ziņojums satur trīs lietas: precīzo ceļu, ko āķis mēģināja, vidi, kas to radīja, un kura robeža atteicās. Izdrukājiet atrisināto ceļu un izņēmumu, neizberžot faila saturu. Šis trijnieks atdala nepareizu noenkurojumu no paslēpta mount un no atļaujas atteikuma, un tie ir trīs dažādi labojumi.
Apgalvojums, ka root var nolasīt failu no termināļa, atbild uz vienu no šiem jautājumiem un ne uz vienu citu. Tā vietā pārbaudiet no paša pakalpojuma konteksta.