OpenVPN liest das Passwort vom Terminal, nicht von stdin
Wo OpenVPN ein Passwort tatsächlich liest, warum eine Datei auf stdin scheitert und die drei unterstützten Wege für skriptgesteuerte Anmeldung unter Linux und macOS.
OpenVPN fragt auf dem steuernden Terminal nach Benutzername und Passwort, und eine in die Standardeingabe umgeleitete Datei ist nicht dieses Terminal. Genau dieser eine Umstand erklärt das Skript, das hängt, obwohl das Passwort direkt in der Pipe liegt. Die Eingabeaufforderung zeichnet der Client, und gelesen wird vom Terminalgerät, daher ändert eine Umleitung von stdin nichts. Wenn du den Client über einen seiner dokumentierten Eingänge speist, verbindet dasselbe Skript beim ersten Versuch.
Drei Eingänge decken fast jeden Fall ab, und jeder scheitert auf seine eigene Weise. Entscheide nach der Eingabeaufforderung, die der Client tatsächlich zeigt, nicht nach der Option, die am leichtesten zu skripten ist.
Die Eingabeaufforderung kommt nicht von stdin
Wenn OpenVPN Zugangsdaten braucht, öffnet es das steuernde Terminal und liest dort. Deshalb sieht ein interaktiver Test gut aus, während derselbe Befehl unter cron oder einer Unit-Datei untätig steht und die Eingabeaufforderung in ein Protokoll schreibt, das niemand ansieht. Manche Builds fallen auf die Standardeingabe zurück, wenn kein Terminal existiert, und diese Inkonsistenz ist schlimmer als ein harter Fehler, weil sie das Problem bis zum Einsatz verbirgt.
Prüfe die Umgebung, bevor du Code schreibst: starte den Client unter demselben Benutzer, mit derselben stdin, wie es der Scheduler oder Dienstmanager tun wird. Erscheint die Eingabeaufforderung nie im Protokoll und macht der Prozess keine Fortschritte, wartet etwas auf ein Terminal, das nicht existiert.
Eingang eins: eine Datei mit zwei Zeilen
Die Authentifizierungsoption nimmt einen Pfad, und die Datei enthält genau zwei Zeilen, zuerst den Benutzernamen, dann das Passwort, sonst nichts. Gib den Pfad ausdrücklich an, statt dich auf einen Standarddateinamen zu verlassen, denn eine verirrte Datei mit Zugangsdaten im Arbeitsverzeichnis ist der Weg, auf dem das falsche Konto zum Einsatz kommt. Setze den Modus auf 0600 und übertrage den Besitz an das Konto, das den Client ausführt.
Der Client liest die Datei einmal beim Start, eine Passwortrotation bedeutet also einen Neustart des Prozesses. Das ist meist genau das gewünschte Verhalten, und es gehört ins Runbook neben das Rotationsverfahren.
Eingang zwei: askpass für die Schlüsselpassphrase
Ein passphrasengeschützter privater Schlüssel löst eine zweite, andere Aufforderung aus, und sie hat ihre eigene dateigestützte Antwort: Die Option askpass liest die Passphrase aus der ersten Zeile einer Datei. Für SSH-basierte Tunnel ist das Gegenstück ein askpass-Programm, das der Client ausführt und dessen Standardausgabe zum Geheimnis wird.
Keine der beiden Formen legt das Geheimnis in die Argumentliste, und beide lassen es als Datei oder als ausführbares Programm bestehen, das es ausgibt. Der Schutz sind Dateirechte und Prozessbesitz, nicht Unklarheit. Ein Helfer, der eine fest kodierte Zeichenkette ausgibt, ist ein Geheimnis mit zusätzlichen Schritten.
Eingang drei: die eigene CLI des Portalclients
Unternehmensclients liefern meist einen Kommandozeilen-Einstiegspunkt, der sich ohne Fenster mit einem benannten Portal verbindet, und das ist der unterstützte Weg. Unter Linux bietet der GlobalProtect-Client Verbindungs- und Zertifikatsimportvorgänge über seine CLI an, und Portale mit Zertifikatsauthentifizierung brauchen den Importschritt, bevor eine automatisierte Verbindung funktionieren kann. Ziehe ihn synthetischen Tastendrücken vor: Du bekommst einen echten Exit-Status, keine Abhängigkeit vom Fensterfokus, und er übersteht einen gesperrten Bildschirm.
Braucht die erste Verbindung noch einen Menschen, der ein Zertifikat annimmt, ist die Automatisierung nicht fertig. Erledige den Import beim Einrichten und halte ihn als Voraussetzung fest.
Wenn der Ablauf ein Pseudo-Terminal braucht
Eine Folge, die nach einem Passwort und dann nach einem Einmalcode fragt, hat keine einzelne Datei zum Lesen. Ein Terminaltreiber wie Expect ist das richtige Werkzeug, weil er der Reihe nach auf jedes Muster wartet, und er braucht den gestarteten Prozess, bevor er überhaupt etwas abgleichen kann.
Zwei Fehler dominieren. Ein Skript, das ohne Start des Clients auf eine Aufforderung wartet, wartet ewig, und Tcl ist keine Shell, also wird Shell-Arithmetik in einem expect-Block nicht so ausgewertet, wie sie gelesen wird. Lass das Debug-Flag an, während du die Muster baust, und schalte es danach ab.
Geheimnisse, die austreten, und wo sie sich verstecken
Alles, was als Argument übergeben wird, ist in der Prozessliste sichtbar, deshalb gehören Zugangsdaten in eine Datei oder hinter einen Helfer, nie auf die Kommandozeile. Einmalcodes werden konstruktionsbedingt verbraucht und müssen für jeden Versuch erzeugt werden. Fehlerprotokolle tragen oft den Benutzernamen und manchmal mehr, also redigiere sie, bevor du sie irgendwohin schickst, und halte das Geheimnis aus dem Profil selbst heraus, denn eine Konfigurationsdatei mit eingebettetem Passwort wird in Tickets und Repositories geklebt. Eine Kontenrotation bedeutet dann, jede Kopie zu jagen, und genau diese Kosten vermeidet diese Anordnung.
Prüfe die gewählten Eingänge und verkabele sie dann in der Unit-Datei oder dem Scheduler, der den Client tatsächlich startet. Der Tunnel lebt genau so lange wie dieser Prozess.