Hooks melden Erfolg, und derselbe Pfad sieht aus einer Shell weiterhin leer aus. Beide Aussagen können gleichzeitig wahr sein, weil ein systemd-Dienst in seinem eigenen Mount-Namensraum mit einem privaten temporären Verzeichnis leben kann. Ist das einmal verstanden, lautet die interessante Frage, ob der Schreibvorgang überhaupt erfolgreich war.

Zwei temporäre Verzeichnisse, ein Pfad

Die Isolierungseinstellung gibt der Unit eine private Sicht auf die temporären Verzeichnisse, statt sie schreibgeschützt zu machen. Prozesse außerhalb der Unit können nicht sehen, was sie dort schreibt, und alles, was sie hinterlässt, wird verworfen, wenn die Unit stoppt. Ein vom Hook ausgegebener Pfad und ein aus einer Shell geprüfter Pfad können daher auf verschiedene Objekte mit demselben Namen verweisen.

Das ist ein Sichtbarkeitsproblem, und es sieht wie ein Datenverlustproblem aus. Nichts wurde gelöscht, weil die Datei einfach in einem Namensraum liegt, dem die Shell nicht angehört. Derselbe Befehl verhält sich anders, wenn er innerhalb der Unit ausgeführt wird, und genau diese Beobachtung entscheidet den Streit meistens. Lies die Einstellungen der Unit, bevor du irgendetwas über den Schreibvorgang schließt.

Trenne unsichtbar von unbeschreibbar

Ein erfolgreicher Schreibvorgang und ein fehlgeschlagenes Öffnen liefern unterschiedliche Beweise, und dieser Unterschied entscheidet die Reparatur. Wenn der Hook sagt, die Datei sei angelegt, ein externer Leser sie aber nicht findet, hast du eine Namensraumfrage. Wenn der Hook einen Berechtigungsfehler oder ein fehlgeschlagenes Öffnen meldet, wurde die Datei nie geschrieben, und keine Änderung des Namensraums hilft.

systemctl show [email protected] -p PrivateTmp -p User -p Group -p RuntimeDirectory
systemctl show [email protected] -p MainPID --value
sudo ls -l /proc/PID/root/tmp/client-state

Der Pfad über die Prozesswurzel zeigt die eigene Dateisystemsicht des Dienstes, abhängig von Berechtigungsprüfungen auf diesen Prozess, solange er noch läuft. Lies das Journal der Unit in derselben Sitzung, denn ein Schreibfehler und eine fehlende Datei lassen sich leicht verwechseln, wenn jemand die Ursache schon entschieden hat.

Gib gemeinsamen Daten einen ausdrücklichen Ort

Daten, die nur der Dienst braucht, gehören in sein privates temporäres Verzeichnis. Daten, die ein anderer Prozess lesen muss, brauchen einen für beide definierten Pfad mit angegebenem Eigentümer, Modus und Ablauf. Entscheide vor dem Bearbeiten der Unit, welchen der beiden Fälle du hast. Die meisten dieser Vorfälle entstehen daraus, dass eine private Datei als gemeinsame behandelt wird.

[Service]
RuntimeDirectory=openvpn-hook-office
RuntimeDirectoryMode=0750

Ein Runtime-Verzeichnis legt den Ordner unter dem System-Runtime-Bereich an, erstellt es für den konfigurierten Benutzer und die Gruppe der Unit und entfernt es, wenn die Unit stoppt. Füge es über ein Drop-in hinzu, damit die Unit des Pakets unverändert bleibt, lade dann den Manager neu und starte die Instanz neu, wobei du akzeptierst, dass sich ihre Clients erneut verbinden.

Behalte jedes Runtime-Verzeichnis, das die installierte Unit bereits benötigt. Die Liste zu ersetzen, statt sie zu ergänzen, ist ein verbreiteter Weg, eine unabhängige Funktion zu beschädigen, die niemand mit der Änderung verbindet.

Zwei Privilegienschichten können widersprechen

Der Dienstmanager legt das Verzeichnis für den konfigurierten Benutzer der Unit an, während der VPN-Daemon vor dem Ausführen eines Verbindungs-Hooks gesondert auf sein eigenes Konto wechseln kann. Das sind verschiedene Schichten, und sie können unterschiedliche Identitäten benennen.

Ein root-eigenes Verzeichnis mit restriktivem Modus ist für einen Daemon, der bereits Privilegien abgegeben hat, vollkommen sichtbar und für ihn dennoch unbeschreibbar. Der Fehler liest sich dann als Berechtigungsproblem, obwohl der Pfad genau dort existiert, wo du ihn erwartet hast. Vergleiche den Eigentümer des Verzeichnisses mit der Identität, die der Hook meldet. Wenn sie sich unterscheiden, war der Modus nie die Frage.

Prüfe die Identität, unter der der Hook wirklich läuft, bevor du den Eigentümer änderst. Den Ausführungsbenutzer des Dienstes zu ändern, um ein Verzeichnis zu reparieren, kann Gerätezugriff und Netzwerkprivilegien anderswo verändern, was ein hoher Preis für ein kleines Problem ist.

Prüfe die gesamte Übergabe

Bestätige vier Dinge auf einmal: Der Hook schreibt unter seiner echten Identität, der vorgesehene Leser kann die Datei nutzen, unbeteiligte Benutzer können es nicht, und das Stoppen der Unit räumt wie vorgesehen auf. Dass eine Datei im gemeinsamen temporären Verzeichnis des Hosts auftaucht, ist keine Anforderung, und es ist meist ein Zeichen dafür, dass der Austausch nie einen eigenen Pfad bekommen hat. Teste den Leser nach einem Neustart, nicht nur beim ersten Lauf. Aufräumverhalten ist Teil des Entwurfs, also beobachte es, statt es anzunehmen.

Dauerhafter Zustand gehört an einen Ort mit passender Lebensdauer, denn ein Runtime-Verzeichnis soll verschwinden. Wähle den Ort nach der Lebensdauer, nicht nach der Bequemlichkeit. Diese Gewohnheit verhindert die nächste Auflage derselben Untersuchung.

Ähnliche Artikel