client-config-dir wird ignoriert, seit OpenVPN ein Dienst wurde
Ein relatives client-config-dir wird gegen das Arbeitsverzeichnis des Daemons aufgelöst. Lies die Unit, prüfe die Pfadrechte und bestätige dann den Lookup im Log.
Dein Tunnel kommt hoch und der Client verbindet, aber die feste Adresse und die gepushten Routen, die du für diesen einen Benutzer definiert hast, fehlen. Im Log steht nichts von “file not found”, und genau das schickt Leute los, Zertifikate neu zu erzeugen. In den meisten dieser Fälle läuft der Daemon aus einem anderen Verzeichnis als der Shell, in der du getestet hast, und client-config-dir wurde nie so aufgelöst, wie du angenommen hast. Die Lösung ist eine Pfadkorrektur, kein Zurücksetzen von Anmeldedaten.
Lies die Unit, bevor du die Konfiguration anfasst
Beginne beim tatsächlich laufenden Prozess, nicht bei der Datei, die du bearbeitet hast. Frage systemd nach der Exec-Zeile, dem Arbeitsverzeichnis und dem Konto, auf das es wechselt. Diese drei Antworten erklären die meisten Fehler dieser Art:
systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectoryEin leeres WorkingDirectory bedeutet, dass die Unit in / startet, also wird ein relatives client-config-dir ccd unter /ccd gesucht. Dieses Verzeichnis existiert fast nie, und der Daemon behandelt sein Fehlen nicht als fatal.
Vergleiche das mit dem interaktiven Start, den du beim Testen benutzt hast, wo das aktuelle Verzeichnis deiner Shell wahrscheinlich das Konfigurationsverzeichnis war. Dieselbe Datei, dieselben Schlüsselwörter, zwei verschiedene Ergebnisse.
Wogegen ein relativer Pfad aufgelöst wird
Das Schlüsselwort wird gegen das Arbeitsverzeichnis des Prozesses zu dem Zeitpunkt aufgelöst, an dem die Option benutzt wird. Es bedeutet nicht „neben der Konfigurationsdatei, die ich mit --config übergeben habe“. OpenVPN liest eine Konfiguration bereitwillig aus einem absoluten Pfad und löst relative Werte trotzdem woanders auf, und genau das ist die Falle hier. Das OpenVPN 2.6-Handbuch nennt die Regel unter --client-config-dir und noch einmal unter --cd.
Das Schlüsselwort cd ändert diesen Kontext, bevor andere Dateien gelesen werden, sodass eine Unit, die cd /etc/openvpn/server und dann client-config-dir ccd setzt, zu /etc/openvpn/server/ccd auflöst. Wenn du cd hinzufügst, prüfe die Reihenfolge der Direktiven und bedenke, dass sie jede andere relative Referenz in derselben Datei beeinflusst.
Gehe den Pfad als Konto des Daemons ab
Ein Pfad kann korrekt und trotzdem unlesbar sein. Nach dem Privilegienabfall ist der Daemon nicht mehr root, also braucht jedes übergeordnete Verzeichnis Suchrecht für dieses Konto, und die Client-Datei selbst braucht Leserecht. Ein fehlendes Ausführungsbit auf einem übergeordneten Verzeichnis genügt, um die Datei zu verstecken, und der Fehler zeigt sich nur als Client, der still den Standard-Pool bekommt.
namei gibt die Rechte jeder Komponente der Reihe nach aus, was schneller ist, als die Verzeichnisse einzeln zu prüfen:
namei -l /etc/openvpn/server/ccd/client1Teste dann das Lesen als Dienstkonto statt als du selbst:
runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readableWenn die Unit chroot verwendet, muss das Verzeichnis innerhalb des Gefängnisses existieren, und der Pfad in der Konfiguration wird erst nach dem chroot interpretiert. Eine Datei, die auf dem Host außerhalb des Gefängnisses liegt, ist von innen unsichtbar.
Bestätige den Lookup, statt zu raten
Erhöhe das Log-Level für einen Neustart und lies, was der Server über client-spezifische Optionen sagt. Bei verb 4 meldet der Daemon die importierte Konfiguration pro Client, eine fehlende Zeile ist also ein direkter Beweis, dass für diese Verbindung keine Datei gelesen wurde.
openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccdStarte das im Vordergrund auf einem freien Port und verbinde einen Client. Das nimmt systemd völlig aus dem Bild: erscheinen die Overrides hier und nicht unter dem Dienst, liegt der Unterschied im Kontext der Unit, nicht in der Datei.
Entscheide, was passieren soll, wenn keine Datei passt. Ohne ccd-exclusive wird der Client nur mit den globalen Pool-Einstellungen zugelassen, und das ist der stille Fehler von oben. Mit ihr wird eine fehlende Datei zu einer abgelehnten Verbindung, und diese Ablehnung ist leichter zu bemerken, aber unter Last schwerer zu debuggen.
Korrigieren, neu starten, prüfen
Mache das Verzeichnis in der Konfiguration absolut und lass es so. Relative Pfade sind nur sicher, wenn die Unit das Arbeitsverzeichnis festnagelt, und das Festnageln ist ein zusätzliches bewegliches Teil, das jemand später entfernt.
client-config-dir /etc/openvpn/server/ccd
ccd-exclusiveStarte die Instanz neu, verbinde einen bekannten Client erneut und lies die Adresse, die er bekommen hat, zusammen mit den zu ihm gepushten Routen. Wenn die Adresse mit der Zeile ifconfig-push in der Datei dieses Clients übereinstimmt, hat der Lookup funktioniert. Landet der Client weiterhin im allgemeinen Pool, geh zurück zur Zahl der Logzeilen: null Importe bedeuten, dass der Pfad oder die Identität falsch ist, ein Import mit falschem Inhalt bedeutet, dass du eine andere Datei bearbeitest als die, die der Daemon liest.
Rolle zurück, indem du die vorherige Unit und Konfiguration zusammen wiederherstellst und dann neu startest. Zertifikate müssen dafür nicht neu ausgestellt werden, und ein Verzeichnisproblem als Anmeldedatenproblem zu behandeln ist der Weg, auf dem aus einer Fünf-Minuten-Korrektur ein Wartungsfenster wird.