Kodėl OpenVPN kablys neranda failo šalia savo scenarijaus
Santykiniai keliai kabliuke sprendžiami proceso, o ne scenarijaus atžvilgiu. Pritvirtinkite juos __file__, tada prieš teises patikrinkite vardų erdvę ir tapatybę.
Kabliukai, kurie veikia be klaidų ir vis tiek praneša apie trūkstamą failą, paprastai žiūri ne į tą vietą, o ne nepavyksta atlikti savo darbo. Santykiniai keliai scenarijuje sprendžiami proceso darbinio katalogo atžvilgiu, o tarnyba paleidžiama su darbiniu katalogu, kurio jūs nepasirinkote. Failas šalia scenarijaus ir failas, kurį atidaro procesas, yra tas pats dalykas tik tada, kai kažkas juos pritvirtina. Šis skirtumas paaiškina didelę dalį kabliukų gedimų, kurie klaidingai perskaitomi kaip teisių problemos.
Patikrinkite kelią prieš teises, nes teisių klaida netinkamame faile vis tiek yra netinkamas failas.
Santykinis kelias sprendžiamas proceso, o ne failo atžvilgiu
Kai scenarijus iškviečia open("policy.json"), branduolys išsprendžia vardą proceso dabartinio darbinio katalogo atžvilgiu. Niekas iš paties scenarijaus vietos tame ieškime nedalyvauja. OpenVPN pradeda kabliukus iš katalogo, kurį pasirenka pats, ir parinktis cd gali jį pakeisti, todėl scenarijus, išbandytas rankiniu būdu iš savo aplanko, elgiasi kitaip, kai jį paleidžia tarnyba. Rankinis bandymas praeina, tarnybos paleidimas nepavyksta, o žurnalo eilutė mini tik trūkstamą vardą.
Python atskleidžia scenarijaus vietą kaip __file__, ir būtent tai leidžia pritvirtinti. Path(__file__).resolve().parent / "policy.json" stato kelią iš failo, o ne iš proceso. Ši viena eilutė pašalina priklausomybę nuo darbinio katalogo nieko nekeisdama teisėse.
Sąmoningai pritvirtinkite kelią, tada patikrinkite, ką daro resolve
resolve() seka simbolines nuorodas, todėl įdiegimas, kuris kabliuką susieja vietoje, pritvirtinamas prie nuorodos tikslo, o ne prie katalogo, kuriame yra nuoroda. Paprastai to norima versijuotame diegime, ir tai neteisinga išdėstymui, kuris tikisi duomenų šalia simbolinės nuorodos. Nuspręskite, ką diegimas turi omenyje, ir rašykite kodą pagal tai, o ne atraskite skirtumą produkcijoje. Path(__file__).parent be resolve() išlaiko pačios nuorodos katalogą.
Jei duomenys priklauso egzemplioriui, o ne programai, imkite absoliutų kelią iš konfigūracijos. Kietas vietos kodavimas pririša kabliuką prie vieno prieglobos išdėstymo.
Praeikite keturias ribas iš eilės
Pradėkite nuo darbinio katalogo: palyginkite įrenginio WorkingDirectory, OpenVPN parinktį cd ir bet kokį apvalkalą, kuris prieš exec pakeičia katalogą. Tada patvirtinkite išspręstą vietą, nes panašaus pavadinimo failas kitame diegime gali atsakyti į paiešką ir paslėpti klaidą. Toliau ateina failų sistemos vaizdas: chroot arba tarnybos mount vardų erdvė gali absoliutų prieglobos kelią tiesiog padaryti nesamą. Galiausiai prieigos tapatybė, kuri yra atskiras klausimas nuo matomumo.
ProtectHome ir PrivateTmp slepia skirtingas vietas, ir nė viena neparodoma katalogo sąraše, paimtame iš prieglobos. Kelias, kuris egzistuoja root vartotojui apvalkale, gali būti nematomas įrenginio vardų erdvėje, ir todėl tos pačios komandos bandymas už tarnybos ribų taip mažai įrodo.
Pataisykite paiešką neplėsdami tarnybos
Kelio pritvirtinimas išsprendžia tik pirmą ribą. Jis neatskleidžia katalogo, kurį tarnyba slepia, ir nesuteikia neprivilegijuotai paskyrai prieigos prie failo, skirto tik root. script-security padidinimas pakeičia, kuriuos scenarijus OpenVPN paleis; tai neturi jokios įtakos tam, kur išsprendžiamas santykinis vardas. Visos tarnybos darbinio katalogo keitimas yra platesnis už problemą, nes kiekvienas kitas santykinis sertifikato, žurnalo ar pagalbininko kelias juda kartu.
Rinkitės siaurą pataisą: deterministinis kelias scenarijuje, aiški konfigūracijos reikšmė egzemplioriaus duomenims ir failų nuosavybė, atitinkanti paskyrą, kuria kabliukas iš tikrųjų veikia.
Užfiksuokite įrodymus, įvardijančius ribą
Naudinga gedimo ataskaita turi tris dalykus: tikslų kelią, kurį kabliukas bandė, aplinką, kuri jį sukūrė, ir kuri riba atsisakė. Išspausdinkite išspręstą kelią ir išimtį neišpildami failo turinio. Šis trejetas atskiria neteisingą pritvirtinimą nuo paslėpto mount ir nuo teisių atsisakymo, o tai trys skirtingos pataisos.
Tvirtinimas, kad root gali perskaityti failą iš terminalo, atsako į vieną iš tų klausimų ir nė į vieną kitą. Vietoj to bandykite iš pačios tarnybos konteksto.