Das Plugin wird in Threads, die älter als die aktuellen Builds sind, noch immer empfohlen, und auf einem gestern kompilierten Server scheitert es beim Laden. Das ist kein Konfigurationsfehler, den Sie mit einem Pfad beheben können. Plugin und Skript-Hook lösen dasselbe Problem auf verschiedenen Ebenen, und der Wechsel von einem zum anderen ändert, was installiert werden muss, was mit Serverrechten läuft und was ein fehlgeschlagener Login Ihnen tatsächlich sagt.

Der Mythos: das Plugin ist der unterstützte Weg

Ein Plugin ist ein Shared Object, das in den OpenVPN-Prozess geladen wird, also muss es zur Schnittstelle passen, die dieser Prozess bereitstellt. Builds ändern sich, Paketierung ändert sich, und eine Bibliothek, die für eine ältere Schnittstelle kompiliert wurde, verweigert schlicht das Laden. Nichts in der Serverkonfiguration kann diese Lücke überbrücken, deshalb endet der Rat, „einfach radiusplugin zu installieren“, mit einem Server, der nicht startet.

Der Skript-Hook steht stattdessen außerhalb des Prozesses. OpenVPN führt ein Programm aus, übergibt ihm die Zugangsdaten und liest ein Urteil zurück. Diese Entkopplung lässt ihn Upgrades überleben, und sie macht ihn zugleich zu Ihrer Verantwortung, wie es das Plugin nie war.

Keiner der beiden Ansätze ist von der Konstruktion her sicherer. Der eine führt fremden Code im Daemon aus; der andere führt Ihren Code daneben aus, mit den Zugangsdaten in der Hand. Die richtige Frage ist, welches dieser beiden Risiken Sie tatsächlich betreiben können.

Was das Plugin zusammengebunden hat

Das Plugin brachte seine eigene Konfigurationsdatei mit RADIUS-Host, gemeinsamem Geheimnis, Wiederholungszahl und Timeout mit, und die Serverkonfiguration verwies mit einer einzigen Zeile darauf. Die Behandlung der Zugangsdaten blieb im Serverprozess, sodass das Passwort nie eine Prozessgrenze überquerte, die der Administrator hätte sichern müssen.

Der Preis war die Kopplung. Jedes OpenVPN-Upgrade riskierte eine inkompatible Schnittstelle, und jede Distribution, die das Paket neu baute, riskierte eine Bibliothek, die nicht mehr passte. Wenn das passiert, ist der Fehler laut und sofort, und das ist die einzige Gnade des Entwurfs.

Wenn ein solches Plugin auf Ihrem Build noch lädt, kann es die kleinere Betriebsfläche sein. Bestätigen Sie die Schnittstelle, gegen die es gebaut wurde, halten Sie es an den getesteten Build gebunden, und behandeln Sie jedes Upgrade als Änderung, die einen vollständigen Login-Test erfordert, nicht als routinemäßiges Paketupdate.

Worauf der Skript-Hook wirklich vertraut

Der Hook wird mit auth-user-pass-verify und einem Übergabemechanismus konfiguriert: Umgebungsvariablen oder eine temporäre Datei. Bei der Umgebungsform verlangt OpenVPN script-security 3, die dokumentierte Stufe, die die Passwortfreigabe an Skripte erlaubt. Diese Stufe ist eine bewusste Schwächung der Voreinstellung und sollte als Berechtigung mit beigefügter Begründung behandelt werden.

Alles, was das Skript berührt, erbt dieses Vertrauen. Es muss root gehören, nicht für Gruppe oder Andere beschreibbar sein, über einen absoluten Pfad referenziert werden und frei von jeder Stelle sein, an der ein nicht vertrauenswürdiger Wert eine Shell erreicht. Setzen Sie jede Variable in Anführungszeichen, weisen Sie unerwartete Zeichen zurück und bauen Sie niemals einen Befehl aus dem gelieferten Benutzernamen. Ein Skript, das bei jedem Login-Versuch als root läuft, ist es wert, einmal genau auf diese vier Eigenschaften geprüft zu werden.

ls -l /usr/local/sbin/radius-auth.sh
stat -c '%U %a' /usr/local/sbin/radius-auth.sh

Die Dateiübergabe vermeidet das Problem der Umgebungsvererbung und übergibt die Zugangsdaten über eine temporäre Datei mit eingeschränkten Rechten an das Skript. Wenn Ihr Client das unterstützt, ist das meist die bessere Voreinstellung, auch wenn bei einem Fehler ein weiteres Objekt aufzuräumen ist.

Exit-Codes entscheiden, ob Sie offen scheitern

Der Exit-Status des Skripts ist das Urteil: null akzeptiert, ungleich null weist zurück. Das Muster, das Ärger macht, ist ein Shell-Skript, das nur akzeptiert, wenn die RADIUS-Antwort ein bestimmtes Akzeptanz-Token enthält, und für alles andere einen Fehler zurückgibt, weil es damit drei verschiedene Ereignisse in eine Antwort zusammenfasst. Ein falsches Passwort, ein unerreichbarer Server und eine fehlerhafte Antwort werden alle zur selben Ablehnung.

Trennen Sie diese Fälle im Skript, auch wenn der Hook nur akzeptieren oder ablehnen kann. Protokollieren Sie das Backend-Ergebnis getrennt, alarmieren Sie bei Timeouts und Transportfehlern und machen Sie im Monitoring sichtbar, wenn die Authentifizierung ausfällt, weil der Dienst nicht erreichbar ist, und nicht, weil Benutzer sich vertippen.

Zwei Gewohnheiten halten den Rest vernünftig. Wenn RADIUS die Autorität ist, sollte es der einzige Ort sein, an dem ein Passwort geprüft wird, denn eine Schattentabelle erzeugt zwei Antworten auf dieselbe Frage, und die zweite ist eine Angriffsfläche, die niemand beobachtet. Und denken Sie daran, dass der Hook bei jedem erneuten Versuch wieder aufgerufen wird, sodass ein langsames Skript mit einem ungeduldigen Client zum Verstärker für Passwortraten wird, es sei denn, Sie fügen eine Verzögerung oder eine Richtlinie auf der RADIUS-Seite hinzu.

Was Sie aufgeben, wenn das Zertifikat wegfällt

Viele Bereitstellungen dieser Form schalten die Client-Zertifikatsprüfung ganz ab und lassen einen Benutzernamen und ein Passwort als den gesamten Anspruch des Clients. Was mit dieser Einstellung verschwindet, ist zertifikatsbasierte Identität. Der Kanal bleibt verschlüsselt, aber das Einzige, was den Client benennt, ist das RADIUS-Urteil. Alles nachgelagert, was sich früher auf ein Zertifikatssubjekt stützte, muss sich nun auf den Benutzernamen stützen.

Behalten Sie den Schutz des Kontrollkanals bei, damit ein nicht authentifizierter Peer den Handshake nicht prüfen oder überfluten kann, und verwenden Sie username-as-common-name, wenn die Konfiguration pro Benutzer vom Common Name abhängt. Verwaltete Gateways lösen das oft anders, indem sie die Zertifikatsauthentifizierung an einem Gateway beenden, das EAP-TLS mit RADIUS spricht; dann gilt keine dieser Serverdirektiven. Kopieren Sie das Modell, das Ihre eigene Plattform dokumentiert, nicht das eines Nachbarprodukts. Die entscheidenden Direktiven unterscheiden sich so stark, dass ihre Vermischung eine Konfiguration ergibt, die parst und danach niemanden authentifiziert.

Ähnliche Artikel