Absicherung von Diensten mit systemd
Version vom 10. Januar 2023, 14:46 Uhr von Thomas.will (Diskussion | Beiträge)
Sicherung Ihrer Dienste
- Eines der Kernmerkmale von Unix-Systemen ist die Idee der Privilegientrennung zwischen den verschiedenen Komponenten des Betriebssystems.
- Viele Systemdienste werden unter ihren eigenen Benutzer-IDs ausgeführt, was ihre Möglichkeiten und damit die Auswirkungen auf das Betriebssystem einschränkt, falls sie ausgenutzt werden.
- Diese Art der Privilegientrennung bietet jedoch nur einen sehr grundlegenden Schutz, da auf diese Weise ausgeführte Systemdienste im Allgemeinen immer noch mindestens so viel tun können wie ein normaler lokaler Benutzer, wenn auch nicht so viel wie root.
- Aus Sicherheitsgründen ist es jedoch sehr interessant, die Möglichkeiten von Diensten noch weiter einzuschränken und einige Dinge abzuschalten, die normale Benutzer tun dürfen.
- Eine gute Möglichkeit, die Auswirkungen von Diensten zu begrenzen, ist der Einsatz von MAC-Technologien wie SELinux.
- Wenn Sie daran interessiert sind, Ihren Server abzusichern, ist die Ausführung von SELinux eine sehr gute Idee. systemd ermöglicht es Entwicklern und Administratoren, unabhängig von einem MAC zusätzliche Einschränkungen auf lokale Dienste anzuwenden.
- Unabhängig davon, ob Sie SELinux nutzen können, können Sie daher immer noch bestimmte Sicherheitsbeschränkungen für Ihre Dienste durchsetzen.
Systemd absichern
- Diese systemd-Funktionen wurden so konzipiert, dass sie so einfach wie möglich zu verwenden sind, um sie für Administratoren und Upstream-Entwickler attraktiv zu machen:
- Isolieren von Diensten vom Netzwerk
- Service-private /tmp
- Verzeichnisse als schreibgeschützt oder für Dienste unzugänglich erscheinen lassen
- Funktionen von Diensten wegnehmen
- Verbieten von Forking, Einschränkung der Dateierstellung für Dienste
- Steuern des Geräteknotenzugriffs auf Dienste
- Alle hier beschriebenen Optionen sind in den Manpages von systemd dokumentiert, insbesondere in systemd.exec(5)
- Alle diese Optionen sind auf allen systemd-Systemen verfügbar, unabhängig davon, ob SELinux oder ein anderer MAC aktiviert ist oder nicht.
- Alle diese Optionen sind relativ günstig, also nutze sie im Zweifelsfall.
- Auch wenn Sie denken, dass Ihr Dienst nicht in /tmp schreibt und daher die Aktivierung von PrivateTmp=yes (wie unten beschrieben) möglicherweise nicht erforderlich ist, ist es aufgrund der heutigen komplexen Software immer noch vorteilhaft, diese Funktion zu aktivieren, einfach weil Sie auf Bibliotheken verlinken (und Plug-Ins für diese Bibliotheken), die Sie nicht kontrollieren, benötigen möglicherweise doch temporäre Dateien. Beispiel: Sie wissen nie, welche Art von NSS-Modul Ihre lokale Installation aktiviert hat und was dieses NSS-Modul mit /tmp macht.
- Diese Optionen sind hoffentlich sowohl für Administratoren interessant, um ihre lokalen Systeme zu sichern, als auch für Upstream-Entwickler, um ihre Dienste standardmäßig sicher bereitzustellen. Wir empfehlen Upstream-Entwicklern dringend, diese Optionen standardmäßig in ihren Upstream-Serviceeinheiten zu verwenden.
- Sie sind sehr einfach zu bedienen und bieten große Vorteile für die Sicherheit.
Möglichkeiten
- systemd Isolieren von Diensten vom Netzwerk
- systemd Dienst-Privat /tmp=
- Ein weiterer sehr einfacher, aber leistungsfähiger Konfigurationsschalter ist PrivateTmp=:
... [Service] ExecStart=... PrivateTmp=yes*Im obigen Beispiel werden nur die CAP_CHOWN- und CAP_KILL-Fähigkeiten vom Dienst beibehalten, und der Dienst und alle Prozesse, die er möglicherweise erstellt, haben keine Chance, jemals wiederIsolieren von Diensten vom Netzwerk
...
- Wenn diese Option aktiviert ist, stellt sie sicher, dass das /tmp-Verzeichnis, das der Dienst sieht, privat und vom /tmp des Hostsystems isoliert ist.
- /tmp war traditionell ein gemeinsam genutzter Bereich für alle lokalen Dienste und Benutzer.
- Im Laufe der Jahre war es eine Hauptquelle von Sicherheitsproblemen für eine Vielzahl von Diensten.
- Symlink-Angriffe und DoS-Schwachstellen aufgrund erratbarer temporärer /tmp-Dateien sind häufig.
- Indem das /tmp des Dienstes vom Rest des Hosts isoliert wird, werden solche Schwachstellen hinfällig.
- Achtung: Einige Dienste missbrauchen /tmp tatsächlich als Speicherort für IPC-Sockets und andere Kommunikationsprimitive, obwohl dies fast immer eine Schwachstelle ist und /run ist der viel sicherere Ersatz dafür, Eeinfach weil es kein Ort ist, auf den nichtprivilegierte Prozesse schreiben können.
- Zum Beispiel platziert X11 seine Kommunikations-Sockets unterhalb von /tmp (was eigentlich sicher ist – wenn auch immer noch nicht ideal – in dieser Ausnahme, da es dies in einem sicheren Unterverzeichnis tut, das beim frühen Booten erstellt wird).
- Dienste, die über solche kommunizieren müssen Kommunikationsprimitive in /tmp sind keine Kandidaten für PrivateTmp=.
- Glücklicherweise sind heutzutage nur noch sehr wenige Dienste übrig, die /tmp so missbrauchen.
- Intern nutzt diese Funktion Dateisystem-Namensräume des Kernels. Wenn aktiviert, wird ein neuer Dateisystem-Namensraum geöffnet, der den größten Teil der Hosthierarchie mit Ausnahme von /tmp erbt.
- systemd Verzeichnisse als schreibgeschützt oder für Dienste nicht zugänglich machen
- Mit den Optionen ReadOnlyDirectories= und InaccessibleDirectories= ist es möglich, die angegebenen Verzeichnisse zum Schreiben bzw.
- Schreiben unzugänglich zu machen. sowohl Lesen als auch Schreiben an den Dienst:
... [Service] ExecStart=... InaccessibleDirectories=/home ReadOnlyDirectories=/var ...
- Mit diesen beiden Konfigurationszeilen wird der gesamte Baum unterhalb von /home für den Dienst unzugänglich (d. h. das Verzeichnis erscheint leer und im Zugriffsmodus 000), und der Baum unterhalb von /var wird schreibgeschützt.
- Vorbehalt: Beachten Sie, dass ReadOnlyDirectories= derzeit nicht rekursiv auf Submounts der angegebenen Verzeichnisse angewendet wird
- (d. h. Mounts unter /var im obigen Beispiel bleiben beschreibbar).
- Dies wird wahrscheinlich bald behoben.
- Intern wird dies ebenfalls auf Basis von Dateisystem-Namensräumen implementiert.
- systemd Fähigkeiten von Diensten wegnehmen
- Eine weitere sehr mächtige Sicherheitsoption in systemd ist CapabilityBoundingSet=, die es ermöglicht, auf relativ feinkörnige Weise einzuschränken, welche Kernel-Fähigkeiten ein gestarteter Dienst behält:
... [Service] ExecStart=... CapabilityBoundingSet=CAP_CHOWN CAP_KILL ...
- Im obigen Beispiel werden nur die CAP_CHOWN- und CAP_KILL-Fähigkeiten vom Dienst beibehalten, und der Dienst und alle Prozesse, die er möglicherweise erstellt, haben keine Chance,
zu erwerben, nicht einmal über setuid-Binärdateien.
- Die Liste der aktuell definierten Capabilities ist in Capabilities(7) verfügbar.
- Leider sind einige der definierten Capabilities zu generisch (zB CAP_SYS_ADMIN), dennoch sind sie dennoch ein sehr nützliches Tool, insbesondere für Dienste, die ansonsten mit vollen Root-Rechten laufen.
- Es ist nicht immer einfach, genau zu ermitteln, welche Fähigkeiten erforderlich sind, damit ein Dienst sauber läuft, und erfordert ein wenig Testen.
- Um diesen Prozess ein wenig zu vereinfachen, ist es möglich, bestimmte Fähigkeiten, die definitiv nicht benötigt werden, auf die Blacklist zu setzen, anstatt alle, die möglicherweise benötigt werden, auf die Whitelist zu setzen.
- Beispiel: CAP_SYS_PTRACE ist eine besonders leistungsfähige und sicherheitsrelevante Fähigkeit, die für die Implementierung von Debuggern benötigt wird, da sie die Introspektion und Manipulation jedes lokalen Prozesses auf dem System ermöglicht.
- Ein Dienst wie Apache hat offensichtlich nichts damit zu tun, ein Debugger für andere Prozesse zu sein, daher ist es sicher, die Fähigkeit daraus zu entfernen:
... [Service] ExecStart=... CapabilityBoundingSet=~CAP_SYS_PTRACE ...
- Das Zeichen ~, das der Wertzuweisung hier vorangestellt ist, kehrt die Bedeutung der Option um: Anstatt alle Fähigkeiten aufzulisten, die der Dienst behält, können Sie diejenigen auflisten, die er nicht behält.
- Achtung: Einige Dienste reagieren möglicherweise verwirrt, wenn bestimmte Funktionen für sie nicht verfügbar sind.
- Wenn Sie also die richtigen Fähigkeiten bestimmen, die Sie behalten möchten, müssen Sie dies sorgfältig tun, und es könnte eine gute Idee sein, mit den Upstream-Betreuern zu sprechen, da sie am besten wissen sollten, welche Operationen ein Dienst möglicherweise erfolgreich ausführen muss.
- Vorbehalt 2: Fähigkeiten sind kein Zauberstab. Sie möchten sie wahrscheinlich kombinieren und in Verbindung mit anderen Sicherheitsoptionen verwenden, um sie wirklich nützlich zu machen.
- Um einfach zu überprüfen, welche Prozesse auf Ihrem System welche Fähigkeiten behalten, verwenden Sie das Tool pscap aus dem Paket libcap-ng-utils.
Die Verwendung der CapabilityBoundingSet=-Option von systemd ist oft ein einfacher, auffindbarer und kostengünstiger Ersatz für das individuelle Patchen aller System-Daemons, um das Capability Bounding Set selbst zu steuern.
- systemd Verbieten von Forking, Einschränkung der Dateierstellung für Dienste
- Ressourcenlimits können verwendet werden, um bestimmte Sicherheitslimits auf ausgeführte Dienste anzuwenden.
- In erster Linie sind Ressourcengrenzen für die Ressourcenkontrolle (wie der Name schon sagt ...) und nicht so sehr für die Zugriffskontrolle nützlich.
- Zwei davon können jedoch nützlich sein, um bestimmte Betriebssystemfunktionen zu deaktivieren:
- RLIMIT_NPROC und RLIMIT_FSIZE können verwendet werden, um das Forking zu deaktivieren und das Schreiben von Dateien mit einer Größe > 0 zu deaktivieren:
... [Service] ExecStart=... LimitNPROC=1 LimitFSIZE=0 ...
- Beachten Sie, dass dies nur funktioniert, wennb der fragliche Dienst Privilegien aufgibt und unter einer eigenen (Nicht-Root-) Benutzer-ID läuft oder die CAP_SYS_RESOURCE-Fähigkeit aufgibt, zum Beispiel über CapabilityBoundingSet=, wie oben beschrieben.
- Ohne dies könnte ein Prozess einfach das Ressourcenlimit wieder erhöhen und somit jegliche Wirkung zunichte machen.
- Vorbehalt: LimitFSIZE= ist ziemlich brutal. Wenn der Dienst versucht, eine Datei mit einer Größe > 0 zu schreiben, wird er sofort mit dem SIGXFSZ beendet, der den Prozess beendet, wenn er nicht gefangen wird. Außerdem ist das Erstellen von Dateien mit der Größe 0 weiterhin erlaubt, auch wenn diese Option verwendet wird.
- systemd Steuern des Geräteknotenzugriffs auf Dienste
- Geräteknoten sind eine wichtige Schnittstelle zum Kernel und seinen Treibern. Da Treiber in der Regel viel weniger Tests und Sicherheitsüberprüfungen unterzogen werden als der Kernel, sind sie oft ein wichtiger Einstiegspunkt für Sicherheitshacks.
- Mit systemd können Sie den Zugriff auf Geräte für jeden Dienst einzeln steuern:
... [Service] ExecStart=... DeviceAllow=/dev/null rw ...
- Dadurch wird der Zugriff auf /dev/null und nur auf diesen Geräteknoten beschränkt und der Zugriff auf alle anderen Geräteknoten gesperrt.
- Die Funktion wird auf dem cgroup-Controller des Geräts implementiert.
- systemd Andere Optionen
- Neben den oben genannten benutzerfreundlichen Optionen stehen eine Reihe weiterer sicherheitsrelevanter Optionen zur Verfügung.
- Sie erfordern jedoch normalerweise ein wenig Vorbereitung im Dienst selbst und sind daher wahrscheinlich in erster Linie für Upstream-Entwickler nützlich.
- Diese Optionen sind RootDirectory= (um chroot()-Umgebungen für einen Dienst einzurichten) sAchtung:
- Einige Dienste reagieren möglicherweise verwirrt, wenn bestimmte Funktionen für sie nicht verfügbar sind.
- Wenn Sie also die richtigen Fähigkeiten bestimmen, die Sie behalten möchten, müssen Sie dies sorgfältig tun, und es könnte eine gute Idee sein, mit den Upstream-Betreuern zu sprechen, da sie am besten wissen sollten, welche Operationen ein Dienst möglicherweise erfolgreich ausführen muss.