Dienste mithilfe von Systemd absichern

Aus LinuxUser 12/2021

Dienste mithilfe von Systemd absichern

© Andrii Yurlov / 123RF.com

Abhärtung

Mit Systemd-analyze Dienste Schritt für Schritt quantifizierbar absichern

Eines der wichtigen Ziele bei der Systemd-Entwicklung ist ein sicheres Linux. Nun kann man nur verbessern, was sich messen lässt, weshalb schon der alte Grieche Archimedes von Syrakus riet: “Miss alles, was sich messen lässt, und mach alles messbar, was sich nicht messen lässt.” Dieser Maxime folgend macht Systemd nun die Systemsicherheit unter Linux mess- und verbesserbar.

Konkret bewerkstelligt das das Kommando systemd-analyze [1] mit dem Parameter security. Führt man es aus, liefert es eine Tabelle wie in Abbildung 1: Sie führt jeden von Systemd verwalteten Service auf (UNIT) und liefert dazu einen Zahlenwert für den Schutzgrad (EXPOSURE, wobei 10 der höchste und zugleich schlechteste Wert ist), eine verbale Übersetzung dieses Werts (PREDICATE) und schließlich noch eine dritte Darstellung der Bewertung in Form eines Emojis.

Abbildung 1: Eine tabellarische Bewertung aller Services nach Sicherheitsgesichtspunkten.

Abbildung 1: Eine tabellarische Bewertung aller Services nach Sicherheitsgesichtspunkten.

Zusätzlich kann Systemd-analyze erläutern, wie es zu seiner Einschätzung kommt: Dafür starten Sie es mit dem Namen einer konkreten Service-Unit. Nun listet es wie in Abbildung 2 alle überprüften Faktoren nebst Markierung für die Erfüllung (Haken) oder Nichterfüllung (Kreuz).

Abbildung 2: Die Detaildarstellung aller Faktoren, die in die Bewertung eingingen.

Abbildung 2: Die Detaildarstellung aller Faktoren, die in die Bewertung eingingen.

Härtefall

Danach kennen Sie also die Meinung von Systemd zur Sicherheitslage der geprüften Dienste – aber was lässt sich tun, um sie zu verbessern? Um das herauszufinden, basteln Sie sich einen minimalen Service, dessen Sicherheit Sie dann Schritt für Schritt anheben. Dazu legen Sie zunächst in einem leeren Verzeichnis (im Beispiel /home/$USER/Python/sectest/, das später als Document Root eines kleinen Webservers dienen soll, eine minimalistische HTML-Seite an (Listing 1).

Listing 1

Minimale HTML-Seite

<!doctype html>
<html lang=en>
  <head>
    <meta charset=utf-8>
    <title>Hello World</title>
  </head>
  <body>
    <p><h1>HELLO WORLD!</h1></p>
  </body>
</html>

Den Webserver selbst borgen Sie sich am einfachsten bei Python aus, denn das bringt bereits ein schlichtes Exemplar mit, das sich so gut wie ohne Konfiguration verwenden lässt. Den Server-Start verpacken Sie in ein Systemd-Unit-File, das wiederum so einfach wie möglich ausfällt (Listing 2). Das Unit-File [2] landet als helloworld.service im Verzeichnis /lib/systemd/system/, die HTML-Seite als index.html in besagtem Document-Root-Verzeichnis. Nach einem systemctl start helloworld.service sollte die Eingabe von localhost:8080 in der Adresszeile eines Webbrowsers die schlichte Hello-World-Seite auf den Bildschirm bringen.

Listing 2

Unit-File

[Unit]
Description=Simple Http Server
Documentation=https://docs.python.org/3/library/http.server.html
[Service]
Type=simple
WorkingDirectory=/home/<I>Benutzer<I>/Python/sectest
ExecStart=/usr/bin/python3 -m http.server 8080
ExecStop=/bin/kill -9 $MAINPID
[Install]
WantedBy=multi-user.target

In diesem Zustand, ohne irgendwelche Vorkehrungen, ist der Service noch vollkommen ungeschützt. In der Ausgabe von systemd-analyze security erscheint er mit der hohen Punktzahl 9,6 als UNSAFE mit entsetztem Emoji (Abbildung 3).

Abbildung 3: Ausgangspunkt: Der neue Service ist noch vollkommen unsicher.

Abbildung 3: Ausgangspunkt: Der neue Service ist noch vollkommen unsicher.

Grundlegendes

Im ersten Schritt ergänzen Sie im Service-Abschnitt des Unit-Files die Zeile NoNewPrivileges=true. Das verhindert, dass der Prozess später mehr Privilegien erlangen kann, als ihm ursprünglich zugewiesen wurden, zum Beispiel mithilfe von setuid– oder setgid-Bits. Danach (wie auch bei allen folgenden Ergänzungen des Unit-Files) fällt ein systemctl daemon-reload an, gefolgt von einem systemctl restart helloworld.service. Betrachten Sie jetzt die Ausgabe von systemd-analyze security, ist der Exposure-Wert von helloworld.service schon leicht gesunken, von 9,6 auf 9,4. Als UNSAFE gilt der Dienst freilich immer noch.

Also weiter im Text: Eine ganze Klasse von Angriffen lässt sich unmöglich machen, indem Sie nun im Unit-File PrivateTmp=yes ergänzen. Das bewirkt, dass Systemd für den Prozess einen neuen, exklusiven Filesystem-Namensraum erzeugt und /tmp sowie /var/tmp/ dorthin mountet. So werden temporäre Files nicht mehr öffentlich geteilt und nach dem Ende des Prozesses sofort gelöscht. Angriffe, die auf dem Austausch oder der Manipulation temporärer Dateien beruhen, laufen so ins Leere. Der Exposure-Wert sinkt auf 9.0, die Bewertung bleibt aber auf UNSAFE.

Es gibt also noch einiges zu tun. Im nächsten Schritt ergänzen Sie das Unit-File mit dem Eintrag RestrictNamespaces=uts ipc pid user cgroup. Das unterbindet für den Prozess den Zugriff auf die aufgeführten Namespaces. Die Aufzählung lässt unter anderem den Namespace net aus, den der Webserver naturgemäß verwenden muss. Mit dieser Maßnahme sinkt der Exposure-Wert erstmals unter 9 (auf 8,8), und die Bewertung lautet nicht mehr UNSAFE, sondern nur noch EXPOSED. Das Emoji wechselt von einem entsetzten zu einem nur noch unzufriedenen Ausdruck.

Kernel und Control Groups

Im nächsten Schritt stellen Sie im Unit-File die zusätzlichen Schutzmechanismen ProtectKernelTunables=yes, ProtectKernelModules=yes und ProtectControlGroups=yes ein. Das macht die Kernel-Variablen, auf die der Anwender via /proc/sys/, /sys, /proc/sysrq-trigger/, /proc/latency_stats/, /proc/acpi/, /proc/timer_stats/, /proc/fs/ und /proc/irq/ zugreifen kann, für den Prozess read-only und damit nicht mehr veränderbar. Ohnehin sollte das System auf diese Variablen nur während des Bootens schreibend zugreifen, Sie büßen dadurch also keine Funktionalität ein. Da unser Webserver keine speziellen Kernel-Module benötigt, haben Sie ihm auch das Laden und Entladen solcher Module für den Webserver-Prozess verboten. Genauso untersagt ist ihm ab sofort der Zugriff auf die Control Groups, den höchstens Container-Verwaltungssoftware benötigt, nicht aber ein Webserver. Das drückt den Exposure-Wert auf jetzt 8,1.

Schließlich können Sie noch ProtectSystem=strict einstellen. Das mountet /usr sowie die Bootloader-Verzeichnisse /boot und /efi für alle Prozesse, die diese Unit startet, im Read-only-Modus. Zusätzlich legen Sie PrivateUsers=strict fest. Diese Einstellung konfiguriert für den Prozess ein User-Group-Mapping, das Root und den User, der den Hauptprozess der Unit startet, auf sich selbst abbildet, aber alle anderen Benutzer oder Gruppen auf nobody mappt. Die User- und Gruppen-Datenbank des Systems wird so vom Prozess entkoppelt, der in seiner eigenen Sandbox läuft. Der Exposure-Wert sinkt damit unter 8 (genauer: auf 7,8).

Capabilities

Zum Schluss beschränken Sie noch die Capabilities [3], die dem Prozess zur Verfügung stehen sollen. Dabei handelt es sich um Rechte, die man unprivilegierten Prozessen quasi häppchenweise zugestehen kann. Das macht es überflüssig, einem Prozess die vollkommen unbeschränkten Superuser-Berechtigungen übertragen zu müssen, nur weil er ein einzelnes Sonderrecht benötigt.

Wir gehen hier recht restriktiv vor und definieren CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH. Das schließt beispielsweise die Zuweisung von CAP_SYS_ADMIN, CAP_DAC_OVERRIDE oder CAP_SYS_PTRACE an den Prozess aus und bringt viele Punkte. Der Exposure-Wert fällt damit auf 5,7. Die Bewertung bescheinigt uns nun ein mittleres Sicherheitsniveau, und das Emoji schaut zum ersten Mal neutral und nicht mehr grimmig in die Welt (Abbildung 4).

Abbildung 4: Zum ersten Mal ist das Emoji nicht unzufrieden: Sie haben ein mittleres Sicherheitsniveau erreicht.

Abbildung 4: Zum ersten Mal ist das Emoji nicht unzufrieden: Sie haben ein mittleres Sicherheitsniveau erreicht.

Fazit

Es bleiben noch etliche Möglichkeiten, um für zusätzliche Sicherheit zu sorgen. Eine gute Zusammenstellung aller Systemd-Optionen, die sich für das Härten von Diensten eignen, liefert beispielsweise eine Beschreibung auf Github [4]. Die dort beschriebenen Möglichkeiten eröffnen ein weites Feld für weitere Optimierungen. Mit Systemd-analyze als Messinstrument können Sie Ihre Fortschritte dabei jeweils mitverfolgen. (jlu)

Infos

  1. Manpage zu Systemd-analyze: https://www.freedesktop.org/software/systemd/man/systemd-analyze.html

  2. Workshop Systemd-Units: Ferdinand Thommes, “Handarbeit”, LU 07/2018, S. 30, https://www.linux-community.de/41286

  3. Posix File Capabilities: Marcel Hilzinger, “Grenzen setzen”, LU 06/2009, S. 36, https://www.linux-community.de/18253

  4. Hardening-Optionen: https://gist.github.com/ageis/f5595e59b1cddb1513d1b425a323db04

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 12/2021 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben