Warum ein OpenVPN-Hook die Datei neben seinem Skript nicht findet
Relative Pfade in einem Hook werden gegen den Prozess aufgelöst, nicht gegen das Skript. Verankern Sie sie mit __file__ und prüfen Sie dann Namensraum und Identität vor den Berechtigungen.
Hooks, die fehlerfrei laufen und trotzdem eine fehlende Datei melden, schauen meist am falschen Ort, nicht bei ihrer Aufgabe zu scheitern. Relative Pfade in einem Skript werden gegen das Arbeitsverzeichnis des Prozesses aufgelöst, und ein Dienst startet mit einem Arbeitsverzeichnis, das Sie nicht gewählt haben. Die Datei neben dem Skript und die Datei, die der Prozess öffnet, sind nur dann dasselbe, wenn etwas sie verankert. Diese Lücke erklärt einen großen Teil der Hook-Fehler, die fälschlich als Berechtigungsprobleme gelesen werden.
Prüfen Sie den Pfad vor den Berechtigungen, denn ein Berechtigungsfehler an der falschen Datei ist immer noch die falsche Datei.
Ein relativer Pfad wird gegen den Prozess aufgelöst, nicht gegen die Datei
Wenn ein Skript open("policy.json") aufruft, löst der Kernel den Namen gegen das aktuelle Arbeitsverzeichnis des Prozesses auf. Nichts am eigenen Ort des Skripts ist an dieser Suche beteiligt. OpenVPN startet Hooks aus einem Verzeichnis, das er selbst wählt, und die Option cd kann es ändern, sodass ein von Hand im eigenen Ordner getestetes Skript sich anders verhält, sobald der Daemon es ausführt. Der manuelle Test besteht, der Dienstlauf scheitert, und die Logzeile nennt nur den fehlenden Namen.
Python legt den Ort des Skripts als __file__ offen, und genau das macht eine Verankerung möglich. Path(__file__).resolve().parent / "policy.json" baut einen Pfad aus der Datei statt aus dem Prozess. Diese eine Zeile entfernt die Abhängigkeit vom Arbeitsverzeichnis, ohne etwas an den Rechten zu ändern.
Verankern Sie den Pfad bewusst und prüfen Sie dann, was resolve tut
resolve() folgt symbolischen Links, daher verankert eine Installation, die den Hook an seinen Platz verlinkt, am Linkziel und nicht am Verzeichnis, das den Link enthält. Das ist für ein versioniertes Deployment meist gewünscht und für ein Layout falsch, das Daten neben dem Symlink erwartet. Entscheiden Sie, welches das Deployment meint, und schreiben Sie den Code entsprechend, statt die Differenz in der Produktion zu entdecken. Path(__file__).parent ohne resolve() behält das eigene Verzeichnis des Links.
Wenn die Daten zur Instanz und nicht zum Programm gehören, nehmen Sie einen absoluten Pfad aus der Konfiguration. Ein fest kodierter Ort koppelt den Hook an ein Host-Layout.
Gehen Sie vier Grenzen der Reihe nach durch
Beginnen Sie beim Arbeitsverzeichnis: Vergleichen Sie WorkingDirectory, die Option cd von OpenVPN und jeden Wrapper, der vor exec das Verzeichnis wechselt. Bestätigen Sie dann den aufgelösten Ort, denn eine gleichnamige Datei in einem anderen Deployment kann die Suche beantworten und den Fehler verbergen. Als Nächstes kommt die Dateisystemsicht: Ein chroot oder ein Mount-Namensraum des Dienstes kann einen absoluten Hostpfad schlicht abwesend machen. Zuletzt die Zugriffsidentität, die eine von der Sichtbarkeit getrennte Frage ist.
ProtectHome und PrivateTmp verbergen verschiedene Orte, und keiner davon erscheint in einer vom Host erstellten Verzeichnisliste. Ein Pfad, der für root in einer Shell existiert, kann innerhalb des Namensraums der Unit unsichtbar sein, weshalb das Testen desselben Befehls außerhalb des Dienstes so wenig beweist.
Beheben Sie die Suche, ohne den Dienst zu erweitern
Die Verankerung des Pfades löst nur die erste Grenze. Sie legt kein Verzeichnis offen, das der Dienst verbirgt, und sie gewährt keinem unprivilegierten Konto Zugriff auf eine reine root-Datei. Das Erhöhen von script-security ändert, welche Skripte OpenVPN ausführt; es hat keinen Einfluss darauf, wo ein relativer Name aufgelöst wird. Das Arbeitsverzeichnis für den gesamten Dienst zu ändern ist breiter als das Problem, weil jeder andere relative Zertifikats-, Log- oder Hilfspfad mitwandert.
Bevorzugen Sie die enge Korrektur: ein deterministischer Pfad im Skript, ein expliziter Konfigurationswert für Instanzdaten und Dateieigentum, das zu dem Konto passt, unter dem der Hook tatsächlich läuft.
Erfassen Sie Belege, die die Grenze benennen
Ein brauchbarer Fehlerbericht enthält drei Dinge: den genauen Pfad, den der Hook versucht hat, die Umgebung, die ihn erzeugt hat, und welche Grenze abgelehnt hat. Geben Sie den aufgelösten Pfad und die Ausnahme aus, ohne den Dateiinhalt zu schütten. Diese Dreiergruppe trennt eine falsche Verankerung von einem verborgenen Mount und von einer Berechtigungsverweigerung, die drei verschiedene Korrekturen sind.
Die Behauptung, root könne die Datei von einem Terminal lesen, beantwortet eine dieser Fragen und keine der anderen. Testen Sie stattdessen aus dem Kontext des Dienstes selbst.