Was persist-tun und persist-key in OpenVPN tatsächlich überleben
Beide Optionen decken einen sanften Neustart innerhalb eines laufenden Prozesses ab. Sie behalten die Schnittstelle nach einem Stopp nicht bei und sind keine Richtlinie zum Blockieren von Verkehr.
Das Stoppen des Dienstes entfernt die Schnittstelle selbst mit gesetztem persist-tun. Das ist die Option, die wie dokumentiert funktioniert, kein Fehler. Die Option beschreibt einen Neustartpfad innerhalb eines laufenden Prozesses, und systemctl stop ist nicht dieser Pfad.
Liest man die beiden Namen zusammen, wird das Design klar. Einer behält einen Deskriptor, der andere behält Schlüsselmaterial, und beide existieren wegen dessen, was nach dem Ablegen der Privilegien geschieht.
Die zwei Ressourcen und der Neustart, zu dem sie gehören
OpenVPN signalisiert seinen eigenen Neustart in zwei gewöhnlichen Situationen. Ein ausdrückliches SIGUSR1 tut das, und ein ping-restart, das ein toter Peer auslöst, tut dasselbe. Beide lassen den Prozess am Leben und führen die Verbindungseinrichtung erneut aus, und dort verdienen die Optionen ihren Platz.
| Event | TUN/TAP device | Key and auth files | Addresses and routes | up/down hooks |
|---|---|---|---|---|
Soft reset, from SIGUSR1 or from a ping-restart the daemon sends itself | survives only with persist-tun | survive only with persist-key | survive with the device, otherwise rebuilt | run again only when restart hooks are enabled |
Configuration reload, SIGHUP | recreated | re-read from disk | rebuilt once the device returns | run again |
| Service stop | lost | re-read at the next start | removed | run at the next start |
Nur die Zeile des sanften Neustarts ist das, was diese beiden Optionen ändern, und die Arbeit, die sie überspringen, ist der teure Teil auf einer ausgelasteten Strecke. Das erneute Öffnen eines Geräts reißt die daran hängenden Adressen und Routen ab, und ihr Wiederaufbau kann Pakete verlieren, die beim Beginn des Neustarts unterwegs waren. Ein Stopp zerstört dieselben Objekte ohne jede Option, sie zu erhalten.
Warum es diese Optionen überhaupt gibt
Ein gehärteter OpenVPN-Server startet normalerweise als root, öffnet seine Schlüssel und sein Gerät und wechselt dann zu einem unprivilegierten Benutzer. Nach diesem Wechsel sind einige Vorgänge einfach weg. Das Lesen einer Schlüsseldatei mit Modus 0600, das Anlegen einer Netzschnittstelle oder das Ändern von Routen kann allesamt verweigert werden.
Ohne die persist-Optionen würde ein Peer, der lange genug schweigt, um ping-restart auszulösen, genau diese Vorgänge erzwingen. Die Wiederverbindung würde fehlschlagen, obwohl sich an der Konfiguration nichts geändert hatte. Der Prozess würde scheinbar ohne Grund sterben, und das Protokoll würde einen Berechtigungsfehler statt eines Netzwerkfehlers zeigen.
Mit ihnen verwendet der sanfte Neustart wieder, was die privilegierte Phase bereits erhalten hat. Es ist keine Magie im Spiel, und der Prozess überlebt nichts. Der Erwerb von Ressourcen wird lediglich aufgeschoben.
Lesen Sie den ersten Fehler, nicht den letzten
Wenn ein Neustart fehlschlägt, lesen Sie den ersten Fehler statt den letzten. Ein geschützter Schlüssel, eine auth-Datei, ein Schnittstellen-ioctl und ein externer Hook sind vier verschiedene Ressourcen. Eine zu behalten sagt nichts über den Zugriff auf die anderen. Ein Hook, der ein Firewall-Werkzeug aufruft, braucht weiterhin die Privilegien, die dieses Werkzeug verlangt.
Hooks haben ihren eigenen Schalter. Das OpenVPN-Handbuch paart die persist-Optionen mit up-restart, das entscheidet, ob die up- und down-Skripte nach einem Neustart erneut laufen. Eine Schnittstelle, die oben blieb, sagt Ihnen daher nichts darüber, ob Ihre Resolver-Integration aktualisiert wurde.
# which restart path just happened?
journalctl -u openvpn-client@office --since '10 min ago' | grep -E 'SIGUSR1|ping-restart|Restart pause|NOTE:'
# did the interface survive, and do its routes still exist?
ip -brief link show tun0
ip route show dev tun0
Dieses Befehlspaar trennt die beiden Fehlerarten in Sekunden. Eine vorhandene Schnittstelle mit fehlenden Routen ist ein Hook- oder Routenproblem. Eine verschwundene Schnittstelle bedeutet, dass der Prozess tatsächlich geendet hat.
Eine beibehaltene Schnittstelle ist kein Kill-Switch
Wenn die Anforderung lautet, dass Verkehr den Tunnel nie verlassen darf, liefert ein beibehaltenes Gerät das nicht. Routen für die andere Adressfamilie, eine zweite Standardroute und der Fall, dass der Prozess vollständig endet, bleiben alle außerhalb des Geltungsbereichs der Option.
Behandeln Sie die beiden Anforderungen getrennt. Das Tunnelobjekt über Wiederverbindungen hinweg zu behalten, ist eine Bequemlichkeit für den Daemon. Das Blockieren des Ausgangs bei ausgefallenem Tunnel ist eine Firewall-Richtlinie mit eigenen Regeln und eigenem Test. Beides zu vermengen erzeugt eine Konfiguration, die defensiv aussieht und sich wie eine Wiederverbindung nach bestem Bemühen verhält.
Benennen Sie das Ereignis, bevor Sie es diagnostizieren. Ein sanfter Neustart, ein fehlgeschlagener Verbindungsversuch und ein Dienststopp sind drei Ereignisse mit drei Verhaltensweisen, und nur das erste ist das, was diese Optionen beschreiben.