Der Authenticator zeigt einen frischen sechsstelligen Code, das VPN weist ihn zurück, und derselbe Code verifiziert sich einwandfrei, wenn Sie ihn aus Ihrer eigenen Shell testen. Diese Lücke ist die ganze Geschichte. Ein PAM-Modul, das das Registrierungsgeheimnis nicht öffnen kann, gibt einen Fehler zurück, der identisch mit einem falschen Code aussieht, und die Dienstumgebung, die Home-Verzeichnisse verbirgt, ist ein häufiger Grund dafür. Bevor Sie irgendeine Berechtigung lockern, entscheiden Sie, in welcher von drei Situationen Sie sich befinden.

Welcher der drei Fehler ist es?

Der erste ist ein Geheimnis, das das Modul überhaupt nicht lesen kann. Der zweite ist ein Geheimnis, das es lesen, aber nicht aktualisieren kann. Der dritte ist ein Code, der wirklich falsch ist, meist wegen Uhrzeitdrift oder eines wiederverwendeten Werts.

Trennen Sie sie, indem Sie das Dienstjournal und das System-Authentifizierungsprotokoll für einen fehlgeschlagenen Versuch lesen, und bestätigen Sie dann, welchen PAM-Dienst das Plugin lädt und welche Modulzeile dieser Dienst verwendet. Eine allgemeine Authentifizierungsfehlermeldung unterscheidet sie nicht, und ein erfolgreicher manueller Test auch nicht, denn Ihre Shell ist nicht die Umgebung des Dienstes.

Die Dateisystemsicht der Unit ist der übliche Übeltäter, wenn nur der Dienst scheitert.

systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20

Option A: das Geheimnis aus dem Home-Verzeichnis holen

Wenn der Dienst /home verbirgt und Sie diesen Schutz lieber behalten, speichern Sie das Geheimnis dort, wo er es sehen kann. Das Modul akzeptiert einen secret=-Pfad und ein user=-Konto, das die Dateioperationen ausführt, wodurch ein zentraler Speicher viele Identitäten bedienen kann.

Dies ist die saubere Option, und sie braucht die meiste Sorgfalt, weil ein gemeinsamer Speicher ein einziges Verzeichnis zur Sicherheitsgrenze für jedes Konto macht.

auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otp

Prüfen Sie drei Dinge, bevor Sie ihr trauen: Das Konto existiert, der Modul-Arbeitsprozess kann zu ihm wechseln, und die Dateien gehören ihm mit restriktiven Modi. Verwenden Sie ~ oder einen Pfad mit Home-Variable nicht zusammen mit user=, und deaktivieren Sie nicht die Eigentumsprüfungen des Moduls, um einen Pfad zum Laufen zu bringen. Halten Sie die Passwortstufe und den Rest des Stacks intakt.

Option B: die Datei lassen und einen Pfad öffnen

Wenn das Geheimnis im Home des Benutzers bleiben muss, braucht die Unit eine Sicht, die genau dieses Verzeichnis einschließt, ohne alle Homes auf dem Host offenzulegen. Ein Drop-in kann einen eng begrenzten Bind-Mount unter einem sandboxed Home hinzufügen.

Das behält den Eigentum pro Benutzer als Modell bei, auf Kosten einer Unit-Änderung, die bei jeder Änderung der Sandbox geprüft werden muss.

Zwei Grenzen werden leicht übersehen. Ein schreibgeschützter Pfad, der unter einem von der Sandbox verborgenen Verzeichnis hinzugefügt wird, legt es nicht offen, weil das übergeordnete Verzeichnis einfach nicht da ist. Und der Mount muss beschreibbar sein, wenn das Modul den Zustand aktualisieren muss, was die nächste Option ins Spiel bringt. Schreiben Sie das Drop-in als separate Datei, statt die paketierte Unit unter /usr/lib zu bearbeiten, damit ein Paket-Upgrade es nicht stillschweigend rückgängig macht.

Option C: die Sandbox behalten und Zustandsschreibvorgänge reparieren

Das Geheimnis zu lesen ist nur die Hälfte der Authentifizierung. Das Modul kann Zeitverschiebungsinformationen, Replay-Schutz oder einen Zähler neu schreiben, und eine Datei, die die Leseprüfung besteht, kann trotzdem am Schreiben scheitern.

Dieser Fehler sieht beim nächsten Versuch wie ein schlechter Code aus und nicht bei diesem, weshalb er mit Uhrzeitdrift verwechselt wird.

Geben Sie ihm ein eigenes beschreibbares Verzeichnis und richten Sie den Geheimpfad dorthin, statt das ganze Home beschreibbar zu machen. Bestätigen Sie den Eigentümer des Verzeichnisses, den freien Speicher des Dateisystems und ob die Unit Schreibvorgänge anderswo einschränkt. Testen Sie dann zwei aufeinanderfolgende Anmeldungen, denn die zweite beweist den Schreibpfad und die erste nur das Lesen.

Prüfen Sie als der Dienst, nicht als Sie selbst

Jede wichtige Prüfung muss innerhalb der Sandbox der Unit mit der Identität der Unit laufen.

Ein Befehl, der als root gelingt, sagt Ihnen, dass die Datei existiert, und sonst nichts. Eine Anmeldung über den tatsächlichen Dienst sagt Ihnen, ob das Modul das Geheimnis lesen, nutzen und zurückschreiben kann, was es braucht.

Schließlich halten Sie die Anforderung intakt. Eine Nullpasswort-Option hinzuzufügen, Lesefehler zu akzeptieren oder die Sandbox zu entfernen, würde das Symptom jeweils beseitigen, indem die Richtlinie geändert wird. Ein Benutzer, der einen Code vorlegen muss, sollte weiterhin abgelehnt werden, wenn das Geheimnis nicht erreichbar ist.

Ähnliche Artikel