Systemd Hardening Workshop: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(54 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 7: Zeile 7:
 
*Er weist jeder einen numerischen „Exposure Level“-Wert zu, je nachdem, wie wichtig die Einstellung ist.  
 
*Er weist jeder einen numerischen „Exposure Level“-Wert zu, je nachdem, wie wichtig die Einstellung ist.  
 
*Anschließend berechnet es ein Gesamtexpositionsniveau für die gesamte Einheit durch eine Schätzung
 
*Anschließend berechnet es ein Gesamtexpositionsniveau für die gesamte Einheit durch eine Schätzung
*Diese lieht im Bereich von 0,0 bis 10,0, die uns sagt, wie exponiert ein Dienst sicherheitstechnisch ist.
+
*Diese lieht im Bereich von 0.0 bis 10.0, die uns sagt, wie exponiert ein Dienst sicherheitstechnisch ist.
 +
*systemd-analyze security
 +
<pre>
 +
UNIT                                EXPOSURE PREDICATE HAPPY
 +
cron.service                              9.6 UNSAFE    😨
 +
dbus.service                              9.6 UNSAFE    😨
 +
emergency.service                        9.5 UNSAFE    😨
 +
getty@tty1.service                        9.6 UNSAFE    😨
 +
rc-local.service                          9.6 UNSAFE    😨
 +
rescue.service                            9.5 UNSAFE    😨
 +
rsyslog.service                          9.6 UNSAFE    😨
 +
ssh.service                              9.6 UNSAFE    😨
 +
strongswan-starter.service                9.6 UNSAFE    😨
 +
systemd-ask-password-console.service      9.4 UNSAFE    😨
 +
systemd-ask-password-wall.service        9.4 UNSAFE    😨
 +
systemd-fsckd.service                    9.5 UNSAFE    😨
 +
systemd-initctl.service                  9.4 UNSAFE    😨
 +
systemd-journald.service                  4.3 OK        🙂
 +
systemd-logind.service                    2.6 OK        🙂
 +
systemd-networkd.service                  2.9 OK        🙂
 +
systemd-timesyncd.service                2.1 OK        🙂
 +
systemd-udevd.service                    8.0 EXPOSED  🙁
 +
user@0.service                            9.8 UNSAFE    😨
 +
user@1000.service                        9.4 UNSAFE    😨
 +
webserver.service                        9.6 UNSAFE    😨
 +
</pre>
  
 +
=Vorgehensweise=
 +
*Wir können nun Schritt für Schritt die Verbesserungen überprüfen, die an unserem systemd-Dienst vorgenommen wurden.
 +
*Wie Sie sehen können, sind jetzt mehrere Dienste als UNSAFE gekennzeichnet, was wahrscheinlich daran liegt, dass nicht alle Anwendungen die von systemd bereitgestellten Funktionen anwenden.
 +
 +
=Einstieg=
 +
*Beginnen wir mit einem einfachen Beispiel.
 +
*Wir wollen eine systemd-Unit erstellen, um den Befehl python3 -m http.server als Dienst zu starten:
 +
<pre>
 +
[Unit]
 +
Description=Simple Http Server
 +
Documentation=https://docs.python.org/3/library/http.server.html
 +
 +
[Service]
 +
Type=simple
 +
ExecStart=/usr/bin/python3 -m http.server
 +
ExecStop=/bin/kill -9 $MAINPID
 +
 +
[Install]
 +
WantedBy=multi-user.target
 +
</pre>
 +
 +
*Wir speichern diese Datei unter /etc/systemd/system/simplehttp.service ab
 +
=Wir starten den Dienst=
 +
*systemctl start simplehttp.service
 +
 +
=Überprüfung=
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        9.6 UNSAFE    😨
 +
=PrivateTmp=
 +
*Es erstellt einen Dateisystem-Namensraum unter /tmp/systemd-private-*-[Unit-Name]-*/tmp
 +
*Dies wird  anstelle eines gemeinsam genutzten /tmp oder /var/tmp benutzt.
 +
*Viele der mit Red Hat Enterprise Linux veröffentlichten Unit-Dateien enthalten diese Einstellung.
 +
*Dies entfernt die eine ganze Klasse von Schwachstellen im Zusammenhang mit der Vorhersage und Ersetzung von Dateien entfernt, die in /tmp verwendet werden.
 +
=Die Änderung=
 +
[Unit]
 +
Description=Simple Http Server
 +
Documentation=https://docs.python.org/3/library/http.server.html
 +
 +
[Service]
 +
Type=simple
 +
ExecStart=/usr/bin/python3 -m http.server
 +
ExecStop=/bin/kill -9 $MAINPID
 +
 +
'''#Secure Features'''
 +
'''PrivateTmp=yes'''
 +
 +
[Install]
 +
WantedBy=multi-user.target
 +
 +
=Neu einlesen und restart=
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
=Neue Untersuchung=
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        9.2 UNSAFE    😨
 +
;Der Wert hat sich von 9.6 auf 9.2 verbessert
 +
=NoNewPrivileges=
 +
*Es verhindert, dass der Dienst und zugehörige untergeordnete Prozesse Berechtigungen eskalieren.
 +
 +
NoNewPrivileges=true
 +
==Umsetzung==
 +
*SECURE='NoNewPrivileges=true'
 +
*sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        9.0 UNSAFE    😨
 +
 +
=Namensräume einschränken=
 +
*Es begrenzt alle oder eine Teilmenge von Namespaces auf den Dienst.
 +
*Die Direktive akzeptiert cgroup, ipc, net, mnt, pid, user und uts.
 +
 +
RestrictNamespaces=uts ipc pid user cgroup
 +
 +
*Wie Sie oben sehen können, wurde der net-Namespace nicht festgelegt, da sich der Dienst an eine Netzwerkschnittstelle binden muss.
 +
*Das Isolieren von net von einem Netzwerkdienst macht es nutzlos.
 +
==Umsetzung==
 +
*SECURE='RestrictNamespaces=uts ipc pid user cgroup'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        8.9 EXPOSED  🙁
 +
 +
=ProtectSystem=strict=
 +
*Die erste Option zur Härtung eines Service ist ProtectSystem.
 +
*Diese kennt mehrere Werte: true oder yes lassen wir mal außen vor, da sie aus meiner Sicht zu schwach ist und wenig mit Härtung zu tun hat.
 +
*Wer Näheres wissen möchte kann die Man-Page systemd.exec befragen. Bleiben noch full und strict.
 +
 +
Option Beschreibung
 +
full Mounted /usr, /boot und /etc als nicht beschreibbar.
 +
strict Mounted das gesamte Dateisystem (außer /dev, /proc und /sys) als nicht beschreibbar.
 +
==Umsetzung==
 +
*SECURE='ProtectSystem=strict'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        8.7 EXPOSED  🙁
 +
 +
=CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH=
 +
*Das CapabilityBoundingSet sollte für normale Dienste auf einen leeren Wert gesetzt werden.
 +
*Zusätzlich mit der Option NoNewPrivileges verhindert es zuverlässig, dass ein Prozess seine eigenen Privilegien ändert oder eine der in den vorausgehenden Kapiteln gemachten Einschränkungen umgeht.
 +
==Umsetzung==
 +
 +
*SECURE='CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        6.5 MEDIUM    😐
 +
 +
=ProtectKernelTunables=yes=
 +
*Die Option die sich auf das Dateisystem bezieht: ProtectKernelTunables
 +
*Sie macht /proc/sys, /sys, /proc/sysrq-trigger, /proc/latency_stats, /proc/acpi, /proc/timer_stats, /proc/fs und /proc/irq einfach nicht beschreibbar.
 +
*Damit kann der Service keine Kernel-Einstellungen mehr ändern. Für einen Webserver oder eine Datenbank ist das hoffentlich auch nicht nötig.
 +
==Umsetzung==
 +
 +
*SECURE='ProtectKernelTunables=yes'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        6.3 MEDIUM    😐
 +
 +
=ProtectKernelModules=yes=
 +
*Verhindert das Laden neuer Kernel-Module.
 +
*Hierfür wird zum einen das CapabilityBoundSet entsprechend modifiziert und zum anderen ein System-Call-Filter aktiviert, welcher das Aufrufen von Funktionen zur Modulverwaltung blockiert.
 +
*Diese Option kann häufig ohne weitere Nebenwirkungen gesetzt werden, da nur wenige Dienste wirklich Kernel-Module laden müssen.
 +
==Umsetzung==
 +
 +
 +
*SECURE='ProtectKernelModules=yes'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        6.1 MEDIUM    😐
 +
 +
=ProtectControlGroups=yes=
 +
*Verhindert Schreibzugriff auf alle Einstellungen der Kernel-Control-Groups (unter /sys/fs/cgroup).
 +
*Die meisten Dienste (außer Container-Manager) brauchen diesen Zugriff nicht.
 +
*Systemd verwendet jedoch Control-Groups um einige Einschränkungen für die laufenden Dienste umzusetzen.
 +
*Daher sollte der Schreibzugriff fast immer mit ProtectControlGroups=yes blockiert werden, damit der Prozess nicht doch noch aus seinem Gefängnis entkommen kann.
 +
==Umsetzung==
 +
*SECURE='ProtectControlGroups=yes'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        5.9 MEDIUM    😐
 +
 +
=PrivateDevices=yes=
 +
*Ein PrivateDevices=yes erzeugt für den Service ein eigenes /dev Verzeichnis
 +
*In diesem nur noch die für den Betrieb eines Linux-Programmes nötigen Geräte vorhanden sind:
 +
==Umsetzung==
 +
*SECURE='PrivateDevices=yes'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        5.6 MEDIUM    😐
 +
 +
=RestrictSUIDSGID=true=
 +
*SECURE='RestrictSUIDSGID=true'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        5.4 MEDIUM    😐
 +
 +
 +
=IPAddressDnex=0.0.0.0/0=
 +
*SECURE='IPAddressDeny=0.0.0.0/0'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        5.4 MEDIUM    😐
 +
 +
 +
 +
=IPAddressAllow=10.0.10.0/24=
 +
*SECURE='IPAddressAllow=10.0.10.0/24'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        5.4 MEDIUM    😐
 +
 +
=SystemCallFilter=yes=
 +
*Mit dieser Option können einzelne System-Calls verboten werden.
 +
*Aufgrund der Menge und des durch die Weiterentwicklung von Linux dynamischen Angebots an Systemaufrufen sollte man es sich hier tunlichst verkneifen eigene Listen zu pflegen.
 +
*Systemd bietet hierfür einige Standardsets an Systemaufrufen an, welche man deaktivieren kann.
 +
*Die Liste findet sich in der Man-Page von systemd.exec.
 +
*Für den Normalbetrieb bringt systemd ein Set von Systemaufrufen mit, welches normalerweise für alle gängigen Dienste ausreicht:
 +
 +
 +
*SECURE='SystemCallErrorNumber=EPERM'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        4.0 OK        🙂
 +
 +
 +
*SECURE='SystemCallFilter=@system-service'
 +
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 +
*systemctl daemon-reload && systemctl restart simplehttp.service
 +
*systemd-analyze security | grep simp
 +
simplehttp.service                        4.0 OK        🙂
 +
 +
=Läuft der Dienst überhaupt noch?=
 +
*ss -lntp  | grep 8000
 +
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*    users:(("python3",pid=3333,fd=3))
 +
 +
 +
=Ergebnis=
 +
<pre>
 +
[Unit]
 +
Description=Simple Http Server
 +
Documentation=https://docs.python.org/3/library/http.server.html
 +
 +
[Service]
 +
Type=simple
 +
ExecStart=/usr/bin/python3 -m http.server
 +
ExecStop=/bin/kill -9 $MAINPID
 +
 +
#Secure Features
 +
SystemCallFilter=@system-service
 +
IPAddressDeny=0.0.0.0/0
 +
IPAddressAllow=192.168.0.0/16
 +
RestrictSUIDSGID=true
 +
PrivateDevices=yes
 +
ProtectControlGroups=yes
 +
ProtectKernelModules=yes
 +
ProtectKernelTunables=yes
 +
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH
 +
ProtectSystem=strict
 +
RestrictNamespaces=uts ipc pid user cgroup
 +
NoNewPrivileges=true
 +
PrivateTmp=yes
 +
 +
[Install]
 +
WantedBy=multi-user.target
 +
</pre>
  
 
=Links=
 
=Links=
 
*https://www.linuxjournal.com/content/systemd-service-strengthening
 
*https://www.linuxjournal.com/content/systemd-service-strengthening
 +
*https://www.flashsystems.de/articles/systemd-hardening/

Aktuelle Version vom 12. März 2025, 12:58 Uhr

Vorwort

  • In diesem Workshop geht es darum einen systemd Dienst sicherer zumachen

Debuggen

  • Wir benutzen hierzu systemd-analyze
  • Dieses Tool analysiert die Sicherheit und die Sandboxing-Einstellungen der Dienste.
  • Der Befehl prüft auf verschiedene sicherheitsrelevante Diensteinstellungen
  • Er weist jeder einen numerischen „Exposure Level“-Wert zu, je nachdem, wie wichtig die Einstellung ist.
  • Anschließend berechnet es ein Gesamtexpositionsniveau für die gesamte Einheit durch eine Schätzung
  • Diese lieht im Bereich von 0.0 bis 10.0, die uns sagt, wie exponiert ein Dienst sicherheitstechnisch ist.
  • systemd-analyze security
UNIT                                 EXPOSURE PREDICATE HAPPY
cron.service                              9.6 UNSAFE    😨
dbus.service                              9.6 UNSAFE    😨
emergency.service                         9.5 UNSAFE    😨
getty@tty1.service                        9.6 UNSAFE    😨
rc-local.service                          9.6 UNSAFE    😨
rescue.service                            9.5 UNSAFE    😨
rsyslog.service                           9.6 UNSAFE    😨
ssh.service                               9.6 UNSAFE    😨
strongswan-starter.service                9.6 UNSAFE    😨
systemd-ask-password-console.service      9.4 UNSAFE    😨
systemd-ask-password-wall.service         9.4 UNSAFE    😨
systemd-fsckd.service                     9.5 UNSAFE    😨
systemd-initctl.service                   9.4 UNSAFE    😨
systemd-journald.service                  4.3 OK        🙂
systemd-logind.service                    2.6 OK        🙂
systemd-networkd.service                  2.9 OK        🙂
systemd-timesyncd.service                 2.1 OK        🙂
systemd-udevd.service                     8.0 EXPOSED   🙁
user@0.service                            9.8 UNSAFE    😨
user@1000.service                         9.4 UNSAFE    😨
webserver.service                         9.6 UNSAFE    😨

Vorgehensweise

  • Wir können nun Schritt für Schritt die Verbesserungen überprüfen, die an unserem systemd-Dienst vorgenommen wurden.
  • Wie Sie sehen können, sind jetzt mehrere Dienste als UNSAFE gekennzeichnet, was wahrscheinlich daran liegt, dass nicht alle Anwendungen die von systemd bereitgestellten Funktionen anwenden.

Einstieg

  • Beginnen wir mit einem einfachen Beispiel.
  • Wir wollen eine systemd-Unit erstellen, um den Befehl python3 -m http.server als Dienst zu starten:
[Unit]
Description=Simple Http Server
Documentation=https://docs.python.org/3/library/http.server.html

[Service]
Type=simple
ExecStart=/usr/bin/python3 -m http.server
ExecStop=/bin/kill -9 $MAINPID

[Install]
WantedBy=multi-user.target
  • Wir speichern diese Datei unter /etc/systemd/system/simplehttp.service ab

Wir starten den Dienst

  • systemctl start simplehttp.service

Überprüfung

  • systemd-analyze security | grep simp
simplehttp.service                        9.6 UNSAFE    😨

PrivateTmp

  • Es erstellt einen Dateisystem-Namensraum unter /tmp/systemd-private-*-[Unit-Name]-*/tmp
  • Dies wird anstelle eines gemeinsam genutzten /tmp oder /var/tmp benutzt.
  • Viele der mit Red Hat Enterprise Linux veröffentlichten Unit-Dateien enthalten diese Einstellung.
  • Dies entfernt die eine ganze Klasse von Schwachstellen im Zusammenhang mit der Vorhersage und Ersetzung von Dateien entfernt, die in /tmp verwendet werden.

Die Änderung

[Unit]
Description=Simple Http Server
Documentation=https://docs.python.org/3/library/http.server.html 

[Service]
Type=simple
ExecStart=/usr/bin/python3 -m http.server
ExecStop=/bin/kill -9 $MAINPID

#Secure Features
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

Neu einlesen und restart

  • systemctl daemon-reload && systemctl restart simplehttp.service

Neue Untersuchung

  • systemd-analyze security | grep simp
simplehttp.service                        9.2 UNSAFE    😨
Der Wert hat sich von 9.6 auf 9.2 verbessert

NoNewPrivileges

  • Es verhindert, dass der Dienst und zugehörige untergeordnete Prozesse Berechtigungen eskalieren.
NoNewPrivileges=true

Umsetzung

  • SECURE='NoNewPrivileges=true'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        9.0 UNSAFE    😨

Namensräume einschränken

  • Es begrenzt alle oder eine Teilmenge von Namespaces auf den Dienst.
  • Die Direktive akzeptiert cgroup, ipc, net, mnt, pid, user und uts.
RestrictNamespaces=uts ipc pid user cgroup
  • Wie Sie oben sehen können, wurde der net-Namespace nicht festgelegt, da sich der Dienst an eine Netzwerkschnittstelle binden muss.
  • Das Isolieren von net von einem Netzwerkdienst macht es nutzlos.

Umsetzung

  • SECURE='RestrictNamespaces=uts ipc pid user cgroup'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        8.9 EXPOSED   🙁

ProtectSystem=strict

  • Die erste Option zur Härtung eines Service ist ProtectSystem.
  • Diese kennt mehrere Werte: true oder yes lassen wir mal außen vor, da sie aus meiner Sicht zu schwach ist und wenig mit Härtung zu tun hat.
  • Wer Näheres wissen möchte kann die Man-Page systemd.exec befragen. Bleiben noch full und strict.
Option	Beschreibung
full	Mounted /usr, /boot und /etc als nicht beschreibbar.
strict	Mounted das gesamte Dateisystem (außer /dev, /proc und /sys) als nicht beschreibbar.

Umsetzung

  • SECURE='ProtectSystem=strict'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        8.7 EXPOSED   🙁

CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH

  • Das CapabilityBoundingSet sollte für normale Dienste auf einen leeren Wert gesetzt werden.
  • Zusätzlich mit der Option NoNewPrivileges verhindert es zuverlässig, dass ein Prozess seine eigenen Privilegien ändert oder eine der in den vorausgehenden Kapiteln gemachten Einschränkungen umgeht.

Umsetzung

  • SECURE='CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        6.5 MEDIUM    😐

ProtectKernelTunables=yes

  • Die Option die sich auf das Dateisystem bezieht: ProtectKernelTunables
  • Sie macht /proc/sys, /sys, /proc/sysrq-trigger, /proc/latency_stats, /proc/acpi, /proc/timer_stats, /proc/fs und /proc/irq einfach nicht beschreibbar.
  • Damit kann der Service keine Kernel-Einstellungen mehr ändern. Für einen Webserver oder eine Datenbank ist das hoffentlich auch nicht nötig.

Umsetzung

  • SECURE='ProtectKernelTunables=yes'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        6.3 MEDIUM    😐

ProtectKernelModules=yes

  • Verhindert das Laden neuer Kernel-Module.
  • Hierfür wird zum einen das CapabilityBoundSet entsprechend modifiziert und zum anderen ein System-Call-Filter aktiviert, welcher das Aufrufen von Funktionen zur Modulverwaltung blockiert.
  • Diese Option kann häufig ohne weitere Nebenwirkungen gesetzt werden, da nur wenige Dienste wirklich Kernel-Module laden müssen.

Umsetzung

  • SECURE='ProtectKernelModules=yes'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        6.1 MEDIUM    😐

ProtectControlGroups=yes

  • Verhindert Schreibzugriff auf alle Einstellungen der Kernel-Control-Groups (unter /sys/fs/cgroup).
  • Die meisten Dienste (außer Container-Manager) brauchen diesen Zugriff nicht.
  • Systemd verwendet jedoch Control-Groups um einige Einschränkungen für die laufenden Dienste umzusetzen.
  • Daher sollte der Schreibzugriff fast immer mit ProtectControlGroups=yes blockiert werden, damit der Prozess nicht doch noch aus seinem Gefängnis entkommen kann.

Umsetzung

  • SECURE='ProtectControlGroups=yes'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        5.9 MEDIUM    😐

PrivateDevices=yes

  • Ein PrivateDevices=yes erzeugt für den Service ein eigenes /dev Verzeichnis
  • In diesem nur noch die für den Betrieb eines Linux-Programmes nötigen Geräte vorhanden sind:

Umsetzung

  • SECURE='PrivateDevices=yes'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        5.6 MEDIUM    😐

RestrictSUIDSGID=true

  • SECURE='RestrictSUIDSGID=true'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        5.4 MEDIUM    😐


IPAddressDnex=0.0.0.0/0

  • SECURE='IPAddressDeny=0.0.0.0/0'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        5.4 MEDIUM    😐


IPAddressAllow=10.0.10.0/24

  • SECURE='IPAddressAllow=10.0.10.0/24'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        5.4 MEDIUM    😐

SystemCallFilter=yes

  • Mit dieser Option können einzelne System-Calls verboten werden.
  • Aufgrund der Menge und des durch die Weiterentwicklung von Linux dynamischen Angebots an Systemaufrufen sollte man es sich hier tunlichst verkneifen eigene Listen zu pflegen.
  • Systemd bietet hierfür einige Standardsets an Systemaufrufen an, welche man deaktivieren kann.
  • Die Liste findet sich in der Man-Page von systemd.exec.
  • Für den Normalbetrieb bringt systemd ein Set von Systemaufrufen mit, welches normalerweise für alle gängigen Dienste ausreicht:


  • SECURE='SystemCallErrorNumber=EPERM'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        4.0 OK        🙂


  • SECURE='SystemCallFilter=@system-service'
  • sed -ie "/#Secure Features/a$SECURE" /etc/systemd/system/simplehttp.service
  • systemctl daemon-reload && systemctl restart simplehttp.service
  • systemd-analyze security | grep simp
simplehttp.service                        4.0 OK        🙂

Läuft der Dienst überhaupt noch?

  • ss -lntp | grep 8000
LISTEN 0      5            0.0.0.0:8000      0.0.0.0:*    users:(("python3",pid=3333,fd=3)) 


Ergebnis

[Unit]
Description=Simple Http Server
Documentation=https://docs.python.org/3/library/http.server.html

[Service]
Type=simple
ExecStart=/usr/bin/python3 -m http.server
ExecStop=/bin/kill -9 $MAINPID

#Secure Features
SystemCallFilter=@system-service
IPAddressDeny=0.0.0.0/0
IPAddressAllow=192.168.0.0/16
RestrictSUIDSGID=true
PrivateDevices=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH
ProtectSystem=strict
RestrictNamespaces=uts ipc pid user cgroup
NoNewPrivileges=true
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

Links