Prečo háčik OpenVPN nenájde súbor vedľa svojho skriptu
Relatívne cesty v háčiku sa riešia voči procesu, nie voči skriptu. Ukotvite ich pomocou __file__, potom pred právami skontrolujte menný priestor a identitu.
Háčiky, ktoré bežia bez chyby a napriek tomu hlásia chýbajúci súbor, zvyčajne pozerajú na nesprávne miesto, nie že by zlyhávali vo svojej práci. Relatívne cesty v skripte sa riešia voči pracovnému adresáru procesu a služba štartuje s pracovným adresárom, ktorý ste si nevybrali. Súbor vedľa skriptu a súbor, ktorý proces otvorí, sú to isté len vtedy, keď ich niečo ukotví. Ten rozdiel vysvetľuje veľkú časť zlyhaní háčikov, ktoré sa nesprávne čítajú ako problémy s právami.
Skontrolujte cestu pred právami, pretože chyba práv na nesprávnom súbore je stále nesprávny súbor.
Relatívna cesta sa rieši voči procesu, nie voči súboru
Keď skript zavolá open("policy.json"), jadro vyrieši názov voči aktuálnemu pracovnému adresáru procesu. Na umiestnení samotného skriptu v tomto hľadaní nič nezávisí. OpenVPN spúšťa háčiky z adresára, ktorý si samo vyberie, a voľba cd ho môže zmeniť, takže skript testovaný ručne z vlastného priečinka sa správa inak, keď ho spustí démon. Ručný test prejde, spustenie služby zlyhá a riadok v logu spomenie iba chýbajúci názov.
Python sprístupňuje umiestnenie skriptu ako __file__, a práve to umožňuje ukotvenie. Path(__file__).resolve().parent / "policy.json" zostaví cestu zo súboru, nie z procesu. Ten jediný riadok odstráni závislosť od pracovného adresára bez toho, aby zmenil čokoľvek na právach.
Ukotvite cestu zámerne a potom skontrolujte, čo robí resolve
resolve() sleduje symbolické odkazy, takže inštalácia, ktorá háčik prepojí na miesto, sa ukotví na cieľ odkazu, nie na adresár, ktorý odkaz drží. To je pri verzovanom nasadení zvyčajne to, čo chcete, a je to nesprávne pre usporiadanie, ktoré očakáva dáta vedľa symbolického odkazu. Rozhodnite, čo nasadenie znamená, a napíšte kód podľa toho, namiesto toho, aby ste rozdiel objavili v produkcii. Path(__file__).parent bez resolve() zachová vlastný adresár odkazu.
Ak dáta patria inštancii a nie programu, vezmite absolútnu cestu z konfigurácie. Natvrdo zapísané umiestnenie viaže háčik na jedno usporiadanie hostiteľa.
Prejdite štyri hranice po poradí
Začnite pracovným adresárom: porovnajte WorkingDirectory, voľbu cd OpenVPN a akýkoľvek obal, ktorý mení adresár pred exec. Potom potvrďte vyriešené umiestnenie, pretože súbor podobného názvu v inom nasadení môže hľadaniu odpovedať a chybu skryť. Nasleduje pohľad na súborový systém: chroot alebo mount menný priestor služby môžu absolútnu cestu hostiteľa jednoducho urobiť neprítomnou. Nakoniec identita prístupu, čo je otázka oddelená od viditeľnosti.
ProtectHome a PrivateTmp skrývajú rôzne umiestnenia a ani jedno sa neobjaví vo výpise adresára prevzatého z hostiteľa. Cesta, ktorá pre root v shelli existuje, môže byť vnútri menného priestoru jednotky neviditeľná, a preto testovanie toho istého príkazu mimo služby dokazuje tak málo.
Opravte hľadanie bez rozšírenia služby
Ukotvenie cesty rieši iba prvú hranicu. Neodhalí adresár, ktorý služba skrýva, a nedá neprivilegovanému účtu prístup k súboru len pre root. Zvýšenie script-security mení, ktoré skripty OpenVPN spustí; na to, kde sa rieši relatívny názov, nemá vplyv. Zmena pracovného adresára pre celú službu je širšia než problém, pretože každá ďalšia relatívna cesta certifikátu, logu alebo pomocníka sa posúva s ňou.
Uprednostnite úzku opravu: deterministická cesta v skripte, explicitná konfiguračná hodnota pre dáta inštancie a vlastníctvo súborov zodpovedajúce účtu, pod ktorým háčik skutočne beží.
Zaznamenajte dôkazy, ktoré pomenujú hranicu
Užitočná správa o zlyhaní obsahuje tri veci: presnú cestu, ktorú háčik skúsil, prostredie, ktoré ju vytvorilo, a ktorá hranica odmietla. Vypíšte vyriešenú cestu a výnimku bez vylievania obsahu súboru. Tá trojica oddeľuje nesprávne ukotvenie od skrytého mountu a od odmietnutia práv, čo sú tri rôzne opravy.
Tvrdenie, že root môže súbor prečítať z terminálu, odpovedá na jednu z tých otázok a na žiadnu inú. Testujte namiesto toho z vlastného kontextu služby.