Bakit hindi mahanap ng hook ng OpenVPN ang file sa tabi ng script nito
Ang mga relatibong landas sa isang hook ay nireresolba laban sa proseso, hindi sa script. I-angkla ang mga ito gamit ang __file__, pagkatapos suriin ang namespace at pagkakakilanlan bago ang mga pahintulot.
Ang mga hook na tumatakbo nang walang error at nag-uulat pa rin ng nawawalang file ay karaniwang tumitingin sa maling lugar, hindi nabibigo sa kanilang gawain. Ang mga relatibong landas sa isang script ay nireresolba laban sa working directory ng proseso, at ang isang serbisyo ay nagsisimula sa working directory na hindi mo pinili. Ang file sa tabi ng script at ang file na binubuksan ng proseso ay pareho lamang kapag may nag-angkla sa kanila. Ang agwat na iyon ang nagpapaliwanag sa malaking bahagi ng mga pagkabigo ng hook na maling binabasa bilang problema sa pahintulot.
Suriin ang landas bago ang mga pahintulot, dahil ang error sa pahintulot sa maling file ay maling file pa rin.
Ang relatibong landas ay nireresolba laban sa proseso, hindi sa file
Kapag tumawag ang isang script sa open("policy.json"), nireresolba ng kernel ang pangalan laban sa kasalukuyang working directory ng proseso. Wala sa lokasyon ng script mismo ang sumasali sa paghahanap na iyon. OpenVPN nagsisimula ng mga hook mula sa directory na pinipili nito mismo, at ang opsyon na cd ay maaaring magbago nito, kaya ang script na sinubukan sa kamay mula sa sariling folder ay kumikilos nang iba kapag pinapatakbo ito ng daemon. Pumasa ang manu-manong pagsubok, nabigo ang pagpapatakbo ng serbisyo, at ang linya ng log ay binabanggit lamang ang nawawalang pangalan.
Inilalantad ng Python ang lokasyon ng script bilang __file__, at iyon ang nagpapangyari sa angkla. Path(__file__).resolve().parent / "policy.json" bumubuo ng landas mula sa file sa halip na mula sa proseso. Ang nag-iisang linyang iyon ay nag-aalis ng dependency sa working directory nang walang binabago sa mga pribilehiyo.
Sadyang i-angkla ang landas, pagkatapos suriin kung ano ang ginagawa ng resolve
resolve() sinusundan ang mga symbolic link, kaya ang isang instalasyong nagli-link sa hook sa lugar nito ay nag-angkla sa target ng link, hindi sa directory na may hawak ng link. Karaniwan itong gustong mangyari para sa bersyonadong deployment, at mali ito para sa layout na umaasa ng data sa tabi ng symbolic link. Magpasya kung alin ang ibig sabihin ng deployment, at isulat ang code ayon doon sa halip na tuklasin ang pagkakaiba sa production. Path(__file__).parent nang walang resolve() pinapanatili ang sariling directory ng link.
Kung ang data ay pag-aari ng instance at hindi ng program, kumuha ng absolute path mula sa configuration. Ang pag-hardcode ng lokasyon ay nagtatali sa hook sa isang layout ng host.
Daanan ang apat na hangganan nang sunod-sunod
Magsimula sa working directory: ihambing ang WorkingDirectory, ang opsyong cd ng OpenVPN at anumang wrapper na nagpapalit ng directory bago ang exec. Pagkatapos kumpirmahin ang naresolbang lokasyon, dahil ang file na may katulad na pangalan sa ibang deployment ay maaaring sumagot sa paghahanap at itago ang pagkakamali. Susunod ang pananaw ng filesystem: ang chroot o mount namespace ng serbisyo ay maaaring gawing wala na lamang ang isang absolute path ng host. Sa huli ang identidad ng pag-access, na isang tanong na hiwalay sa visibility.
ProtectHome at PrivateTmp nagtatago ng magkaibang lokasyon, at wala sa dalawa ang lumalabas sa isang listahan ng directory na kinuha mula sa host. Ang landas na umiiral para sa root sa isang shell ay maaaring hindi makita sa loob ng namespace ng unit, at iyon ang dahilan kung bakit napakaliit ng napatutunayan ng pagsubok sa parehong utos sa labas ng serbisyo.
Ayusin ang paghahanap nang hindi pinalalawak ang serbisyo
Ang pag-angkla ng landas ay nireresolba lamang ang unang hangganan. Hindi nito inilalantad ang directory na itinatago ng serbisyo, at hindi ito nagbibigay sa account na walang pribilehiyo ng access sa file na para lamang sa root. Ang pagtaas ng script-security nagbabago kung aling mga script ang patatakbuhin ng OpenVPN; wala itong epekto sa kung saan nireresolba ang relatibong pangalan. Ang pagpapalit ng working directory para sa buong serbisyo ay mas malawak kaysa sa problema, dahil bawat iba pang relatibong landas ng certificate, log o helper ay gumagalaw kasama nito.
Piliin ang makitid na pagwawasto: isang deterministikong landas sa script, isang tahasang halaga ng configuration para sa data ng instance, at pagmamay-ari ng file na tumutugma sa account na aktwal na pinapatakbuhan ng hook.
Itala ang ebidensiyang nagpapangalan sa hangganan
Ang kapaki-pakinabang na ulat ng pagkabigo ay naglalaman ng tatlong bagay: ang eksaktong landas na sinubukan ng hook, ang environment na gumawa nito, at kung aling hangganan ang tumanggi. I-print ang naresolbang landas at ang exception nang hindi nagbubuhos ng nilalaman ng file. Ang triplet na iyon ay naghihiwalay ng maling angkla mula sa nakatagong mount at mula sa pagtanggi ng pahintulot, na tatlong magkaibang pagwawasto.
Ang pag-aangkin na kayang basahin ng root ang file mula sa terminal ay sumasagot sa isa sa mga tanong na iyon at wala sa iba. Subukan sa halip mula sa konteksto ng serbisyo mismo.