Krokar som körs utan fel och ändå rapporterar en saknad fil tittar vanligtvis på fel ställe, inte att de misslyckas i sitt arbete. Relativa sökvägar i ett skript löses mot processens arbetskatalog, och en tjänst startar med en arbetskatalog som du inte har valt. Filen bredvid skriptet och filen som processen öppnar är bara samma sak när något förankrar dem. Den klyftan förklarar en stor del av krokfelen som felaktigt läses som behörighetsproblem.

Kontrollera sökvägen före behörigheterna, eftersom ett behörighetsfel på fel fil fortfarande är fel fil.

En relativ sökväg löses mot processen, inte mot filen

När ett skript anropar open("policy.json"), löser kärnan namnet mot processens aktuella arbetskatalog. Ingenting i skriptets egen placering deltar i den sökningen. OpenVPN startar krokar från en katalog som den väljer själv, och alternativet cd kan ändra den, så ett skript som testats för hand från sin egen mapp beter sig annorlunda när daemonen kör det. Handtestet går igenom, tjänstekörningen misslyckas, och loggraden nämner bara det saknade namnet.

Python exponerar skriptets placering som __file__, och det är det som gör förankring möjlig. Path(__file__).resolve().parent / "policy.json" bygger en sökväg från filen i stället för från processen. Den enda raden tar bort beroendet av arbetskatalogen utan att ändra något i behörigheterna.

Förankra sökvägen med avsikt och kontrollera sedan vad resolve gör

resolve() följer symboliska länkar, så en installation som länkar kroken på plats förankras vid länkens mål, inte vid katalogen som håller länken. Det är vanligtvis det du vill ha för en versionerad utrullning, och det är fel för en layout som förväntar sig data bredvid den symboliska länken. Bestäm vad utrullningen menar och skriv koden därefter i stället för att upptäcka skillnaden i produktion. Path(__file__).parent utan resolve() behåller länkens egen katalog.

Om data tillhör instansen och inte programmet, ta en absolut sökväg från konfigurationen. Hårdkodning av en plats binder kroken till en enda värdlayout.

Gå igenom fyra gränser i ordning

Börja med arbetskatalogen: jämför enhetens WorkingDirectory, alternativet cd i OpenVPN och varje omslag som byter katalog före exec. Bekräfta sedan den lösta platsen, eftersom en fil med liknande namn i en annan utrullning kan svara på sökningen och dölja felet. Därefter kommer filsystemsvyn: en chroot eller tjänstens mount-namnutrymme kan helt enkelt göra en absolut värdssökväg frånvarande. Sist är åtkomstidentiteten, som är en fråga skild från synlighet.

ProtectHome och PrivateTmp döljer olika platser, och ingen av dem syns i en kataloglista tagen från värden. En sökväg som finns för root i ett skal kan vara osynlig inuti enhetens namnutrymme, och därför bevisar testning av samma kommando utanför tjänsten så lite.

Rätta sökningen utan att vidga tjänsten

Förankring av sökvägen löser bara den första gränsen. Den avslöjar inte en katalog som tjänsten döljer och ger inte ett oprivilegierat konto åtkomst till en fil som bara är för root. Att höja script-security ändrar vilka skript OpenVPN kommer att köra; det har ingen effekt på var ett relativt namn löses. Att ändra arbetskatalogen för hela tjänsten är bredare än problemet, eftersom varje annan relativ certifikat-, logg- eller hjälpsökväg flyttar med.

Föredra den smala rättelsen: en deterministisk sökväg i skriptet, ett explicit konfigurationsvärde för instansdata och filägande som matchar kontot kroken faktiskt körs som.

Registrera bevis som namnger gränsen

En användbar felrapport innehåller tre saker: den exakta sökväg kroken försökte, miljön som frambringade den och vilken gräns som nekade. Skriv ut den lösta sökvägen och undantaget utan att dumpa filens innehåll. Den treheten skiljer en felaktig förankring från en dold mount och från en nekad behörighet, som är tre olika rättelser.

Påståendet att root kan läsa filen från en terminal besvarar en av de frågorna och ingen av de andra. Testa i stället från tjänstens eget sammanhang.

Relaterade artiklar