Ein VPN-Client skripten: die Ebene vor dem Passwort wählen
Hersteller-CLI, rasdial, ein App-Intent oder UI-Automatisierung scheitern jeweils anders. Wählen Sie die Ebene, halten Sie das Geheimnis aus argv, und warten Sie auf Zustand, nicht auf Exit-Codes.
Skripte starten VPN-Clients auf der Ebene, die der Autor gewählt hat, und diese Ebene ist selten die, die die Aufgabe brauchte. Die Kommandozeile des Herstellers, die Wählhilfe des Betriebssystems und ein Intent einer mobilen App kehren alle an unterschiedlichen Punkten im Leben der Verbindung zurück. Sie behandeln auch das Geheimnis unterschiedlich, und dieser Unterschied entscheidet, ob das Passwort für jeden Benutzer auf dem Rechner sichtbar ist. Wählen Sie die Ebene, bevor Sie die erste Zeile des Skripts schreiben.
Ebene 1: die Kommandozeile des Herstellers
Die meisten Desktop-Clients liefern eine Kommandozeile, die einen Profilnamen und, allzu oft, ein Passwort annimmt. Ciscos alter Client akzeptierte ein connect-Verb mit Benutzer- und Passwortargumenten; macOS stellt den eingebauten Dienst über networksetup bereit; NetworkManager antwortet auf nmcli. Diese Aufrufe kehren zurück, wenn der Befehl fertig ist, was nicht derselbe Moment ist, in dem der Tunnel nutzbar wird. Lesen Sie die eigene Dokumentation des Herstellers für die Version, die Sie einsetzen, denn diese Schnittstellen ändern sich und einige werden ganz entfernt.
nmcli connection up "Work VPN"
networksetup -connectpppoeservice "Work VPN"
Der Vorteil ist, dass der Hersteller seinen eigenen Profilspeicher kennt, sodass der Aufruf dieselbe Konfiguration nutzt wie die GUI. Der Nachteil ist, dass jeder Hersteller eigene Verben erfindet, und ein Skript für einen Client lässt sich nicht auf einen anderen übertragen. Betrachten Sie diese Ebene als den kürzesten Weg, wenn der Client festgelegt und die Version festgeschrieben ist.
Ebene 2: der eigene Dienst des Betriebssystems
Unter Windows ist die Wählhilfe Teil des Betriebssystems, und sie arbeitet gegen einen Telefonbucheintrag statt gegen den Profilspeicher des Herstellers. Das macht sie portabler über Clients hinweg und leichter von einem Dienstkonto aus zu skripten. Es bedeutet auch, dass die Verbindung an einer Stelle existieren kann und an der anderen nicht, was Leute verwirrt, die in der falschen Liste nachsehen.
rasdial "Work VPN" user pass
Get-VpnConnection -Name "Work VPN" | Select-Object ConnectionStatus
Nutzen Sie die PowerShell-Oberfläche, wenn Sie den Eintrag erstellen oder entfernen müssen, statt ihn zu wählen. Die WMI- und Cmdlet-Ebenen legen dieselben Objekte unter verschiedenen Namen offen, und Entfernen ist eine andere Operation als Trennen. Ein Skript, das nur wählt, lässt nach einer Migration veraltete Einträge zurück. Prüfen Sie, in welchen Speicher Ihre Automatisierung schreibt, bevor Sie versprechen, dass die Bereinigung geschieht.
Remove-VpnConnection -Name "Old VPN" -Force
Get-VpnConnection
Unter macOS ist das Gegenstück die Liste der Netzwerkdienste, in der ein vorhandener Dienst über den Namen verbunden wird, statt spontan erstellt zu werden.
Zugangsdaten lecken auf jeder Ebene, also wählen Sie den Kanal
Alles, was Sie auf der Kommandozeile übergeben, erscheint in der Prozesstabelle für jeden lokalen Benutzer, und es überlebt meist auch in der Shell-Historie. Die unterstützte Alternative von OpenVPN ist, das Geheimnis aus einer Datei zu lesen mit --askpass, und die Datei selbst braucht Berechtigungen, die dem Vertrauen entsprechen, das Sie in sie setzen. Eine benannte Pipe vermeidet es, das Geheimnis auf die Platte zu schreiben, lässt aber jeden Prozess, der sie öffnen kann, dort schreiben. Speichern Sie das Geheimnis unter Windows im Anmeldeinformationsmanager oder in einer Datei, die nur das Dienstkonto lesen kann, und niemals als Literal in einer Batchdatei.
openvpn --config /etc/openvpn/work.conf --askpass /etc/openvpn/work.secret --auth-nocache --daemon
ls -l /etc/openvpn/work.secret
Dieselbe Regel gilt für Token und Einmalcodes: wenn die Automatisierung sie braucht, braucht die Automatisierung einen Kanal, der kein Kommandozeilenargument ist. Wechseln Sie das Geheimnis, wenn Sie den Mechanismus ändern, denn der alte Wert hat irgendwo in einem Protokoll gelegen. Ein Skript, das funktioniert und leckt, ist kein funktionierendes Skript.
Auf Zustand warten, dann einen Eigentümer beaufsichtigen
Jeder dieser Aufrufe kehrt zurück, bevor der Tunnel bereit ist, also pollen Sie den Zustand, den der Client offenlegt, oder prüfen Sie ein Ziel darin mit einem Zeitlimit. Dateien zu kopieren oder eine Datenbankverbindung direkt nach dem Verbindungsaufruf zu öffnen, ist ein Wettlauf, und er scheitert sporadisch auf eine Weise, die wie ein Netzwerkfehler aussieht.
ip link show tun0
nmcli -t -f GENERAL.STATE connection show "Work VPN"
curl -sS --max-time 5 https://app.internal.example/health -o /dev/null
Das Trennen hat dasselbe Problem in umgekehrter Richtung: Der Prozess kann beenden, bevor die Routen weg sind. Nutzen Sie die Hooks des Clients, wo es sie gibt, etwa die Up- und Down-Skripte von OpenVPN oder ein ExecStartPost einer systemd-Unit, weil diese an dem Punkt laufen, der Sie wirklich interessiert. Hooks laufen mit den Rechten dessen, was sie aufgerufen hat, also braucht ein Hook, der das Netzwerk neu startet, eine ausdrückliche Regel statt einer Annahme. Halten Sie genau einen Eigentümer für die Lebensdauer der Verbindung.
Wenn zwei Aufseher dasselbe Profil starten und stoppen, ist das Ergebnis eine Wiederverbindungsschleife, die sich wie ein Anbieterausfall liest. Das Runbook endet, wenn die Ebene dokumentiert ist, das Geheimnis einen Kanal hat, der nicht argv ist, die Wartebedingung eine Zustandsprüfung mit Zeitlimit ist und ein Prozess den Lebenszyklus besitzt.