Systemd Hardening Workshop: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 144: Zeile 144:
 
*Systemd verwendet jedoch Control-Groups um einige Einschränkungen für die laufenden Dienste umzusetzen.  
 
*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.
 
*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'
 
*SECURE='ProtectControlGroups=yes'
 
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service
 
*sed -ie "/#Secure Features/a$SECURE''" /etc/systemd/system/simplehttp.service

Version vom 12. Januar 2023, 18:48 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

Ü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
Automatisches Editieren
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.
  • 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

  • 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

  • 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

  • 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

  • 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

  • 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    😐

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
IPAddressAllow=10.0.10.0/24
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