Zwei zusammengeklebte Rezepte mit minimalen Rechten ergeben keine strengere Bereitstellung. Das eine Modell lässt den Daemon mit Rechten starten und nach der Initialisierung auf ein unprivilegiertes Konto wechseln; das andere lässt den Dienstmanager ihn von der ersten Anweisung an unter einer eingeschränkten Identität starten. Beide funktionieren für sich, und die Kombination ergibt oft einen Dienst, der keine der beiden Aufgaben sauber erfüllen kann. Der Rest geht die Entscheidung der Reihe nach durch.

Zwei Modelle, ein Eigentümer des Wechsels

Das erste Modell gehört dem Daemon. Die Community-Version von OpenVPN hat die Optionen user und group, die die Identität wechseln, nachdem Tunnel und Schlüssel eingerichtet sind, und persist-key zusammen mit persist-tun halten diese Ressourcen danach nutzbar.

Das zweite Modell gehört dem Dienstmanager. Eine systemd-Einstellung User= oder Group= bestimmt die Identität, unter der der Prozess startet, und Capability-Direktiven bestimmen, was er halten darf. Die Wahl zwischen den Modellen ist eine Paketierungsfrage, bevor sie eine Sicherheitsfrage ist, und der Paketbetreuer hat sie bereits beantwortet. Ihre Aufgabe ist es, diese Antwort zu finden, statt eine dritte Möglichkeit zu erfinden.

Beide sind legitim. Der Fehler ist, sie als Schichten eines Designs zu behandeln, denn das zweite Modell kann den Identitätswechsel des ersten zu einer Operation machen, die der Prozess nicht mehr ausführen darf.

Entscheiden Sie, wo die Identität wechselt

Startet die Unit bereits als eigenes Konto, verlangt eine Daemon-Anweisung, ein anderes Konto zu werden, einen setuid-Übergang, den ein gehärteter Dienst nie machen sollte. Der Fehler erscheint als Berechtigungsfehler beim Start statt als klare Richtlinienmeldung. Es liest sich wie eine fehlende Capability, was Leute zu einem breiteren Bounding-Set schickt statt zur Identitätsfrage.

Lesen Sie, was das installierte Paket tatsächlich mitbringt, bevor Sie etwas bearbeiten, einschließlich seines drop-in-Verzeichnisses. Manche Units lassen den eigenen Wechsel des Daemons bewusst weg, weil der Manager ihn bereits übernimmt, und manche verlassen sich für den Wechsel nach der Initialisierung auf diese Optionen. Eines von beiden zu entfernen, ohne zu wissen, welches Modell Sie geerbt haben, ist der Weg, auf dem ein funktionierender Dienst nicht mehr startet.

Schreiben Sie das gewählte Modell in eine Zeile: manager-eigen oder daemon-eigen. Jede spätere Direktive muss zu diesem Satz passen, und eine gemischte Unit sollte als Fehler und nicht als Kompromiss behandelt werden.

Capabilities sind Grenzen, keine Gewährungen

Ein Capability-Bounding-Set sagt, was ein Prozess höchstens halten darf. Es ist eine Obergrenze, und eine Capability dort aufzuführen gewährt für sich genommen nichts, weshalb eine Unit mit großzügigem Bounding-Set trotzdem keinen Tunnel aufbauen kann.

Was eine Capability tatsächlich in das Ambient-Set eines Dienstes setzt, ist AmbientCapabilities=. Die systemd-Ausführungsreferenz dokumentiert die beiden Direktiven getrennt, und dieser Unterschied erklärt den größten Teil der verwirrenden Capability-Ratschläge im Netz.

Fügen Sie eine Capability erst hinzu, nachdem die fehlschlagende Operation sie identifiziert hat. Ein breiteres Bounding-Set verdeckt die eigentliche Ursache und lässt den Dienst privilegierter als vom Design beabsichtigt. Es macht die Unit auch schwerer zu prüfen, weil die Obergrenze die Aufgabe nicht mehr beschreibt. Entfernen Sie die zusätzliche Capability, sobald der echte Fehler behoben ist.

Befugnisse über den Lebenszyklus abbilden

Listen Sie auf, was der Prozess in jeder Phase tun muss: Start, Dauerbetrieb, erneute Authentifizierung und Abbau. Schnittstellenerstellung, Routenänderungen, das Lesen eines geschützten Schlüssels und der Aufruf eines Helfers geschehen nicht alle im selben Moment oder unter denselben Anforderungen. Sortieren Sie die Liste nach Phase, bevor Sie sie nach Capability sortieren.

Persistenzoptionen bewahren Ressourcen über Neuverhandlungen hinweg und gewähren keine Berechtigungen, die nie gehalten wurden. Ein Schlüssel, den der Prozess beim Start nicht lesen kann, bleibt auch später unlesbar, was die Persistenz-Flags auch sagen. Die Flags bewahren, was bereits funktioniert hat.

Verwenden Sie ein eigenes Konto statt eines geteilten. Die OpenVPN-Entwickler warnen vor der Angewohnheit, nobody als allgemeines Beispiel zu verwenden, weil andere Dienste auf dem Host bereits unter diesem Konto laufen könnten und die Isolation, die Sie zu haben glauben, nicht vorhanden ist.

Funktionen, die die lokale Last ändern, etwa Datenkanal-Offload oder ein anders gelinkter Build, können verschieben, welche Operationen nötig sind. Überprüfen Sie die Abbildung, wenn sich das Paket ändert, nicht nur wenn etwas kaputtgeht.

Schreiben Sie den Plan auf und behalten Sie Wiederherstellungszugang

Ein Bereitstellungsprotokoll sollte den Manager, die Startidentität, die beabsichtigte Daueridentität und jede Gewährung mit der Operation nennen, die sie erfordert. Dieses Protokoll macht die nächste Änderung überprüfbar statt experimentell.

Halten Sie den Konsolenzugang offen, während Sie bearbeiten, denn eine Unit, die beim Start scheitert, ist aus der Ferne schwer zu reparieren. Testen Sie einen Neustart und einen vollständigen Reboot, bevor Sie die Änderung als abgeschlossen bezeichnen. Eine Unit, die einen Neustart übersteht, kann trotzdem scheitern, bevor das Netzwerk steht.

Erfolg ist ein verstandener Lebenszyklus mit minimalen Befugnissen, kein Prozess, der zufällig unter einem Nicht-root-Namen läuft.

Ähnliche Artikel