From d0cf308c0a199a0e8f0ac575142725f9e98e7173 Mon Sep 17 00:00:00 2001 From: Thomas Stallinger Date: Fri, 7 Aug 2026 08:00:40 +0200 Subject: [PATCH] hardening: systemd-Sandboxing fuer kundenplattform.service erweitern Audit ergab: der Dienst laeuft korrekt als unprivilegierter User (nicht root, kein sudo, nologin-Shell, bestaetigt per ps/id auf anode), aber systemd-analyze security kam trotz der vier bestehenden Basis-Direktiven (NoNewPrivileges/PrivateTmp/ProtectSystem=strict/ProtectHome) nur auf 8.3/10 "EXPOSED" - der volle Capability-Bounding-Set, kein Syscall-Filter, keine Namespace-/Kernel-/Proc-Beschraenkungen. Ergaenzt: CapabilityBoundingSet= (leer - der Dienst braucht keine einzige Linux-Capability), SystemCallFilter=@system-service, RestrictAddressFamilies (nur INET/INET6/UNIX), RestrictNamespaces, RestrictSUIDSGID, LockPersonality, MemoryDenyWriteExecute, ProtectKernel{Modules,Tunables,Logs}, ProtectControlGroups, ProtectClock, ProtectHostname, ProtectProc=invisible, ProcSubset=pid, PrivateDevices, RemoveIPC, RestrictRealtime, UMask=0077. Vor dem Scharfschalten per systemd-run mit exakt dieser Direktivenkombination gegen den echten Code getestet (nicht nur gegen eine leere Testanwendung): Login/JWT-Signierung, Postgres-Lese-/ Schreibzugriff via psycopg, ausgehender HTTP-Aufruf via httpx an provisioning-server, Fernet-Verschluesselung des WLAN-PSK - alles ohne Fehler unter der vollen Sandbox. Co-Authored-By: Claude Sonnet 5 --- kundenplattform.service | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kundenplattform.service b/kundenplattform.service index de909cb..50b27bb 100644 --- a/kundenplattform.service +++ b/kundenplattform.service @@ -21,5 +21,36 @@ ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/kundenplattform +# Erweiterte Sandboxing-Direktiven (2026-08-07 ergänzt, systemd-analyze +# security lag zuvor bei 8.3 "EXPOSED" trotz obiger Basis-Härtung). Braucht +# der Dienst nachweislich nicht - reines Python/uvicorn mit psycopg +# (Postgres via TCP), httpx (ausgehende HTTP-Aufrufe an provisioning-server) +# und cryptography (Fernet-Verschlüsselung des WLAN-PSK, siehe +# encryption.py) - alles unter genau dieser Direktivenkombination per +# systemd-run gegen den echten Code getestet (Login/JWT, DB-Lese-/ +# Schreibzugriff, ausgehender HTTP-Aufruf, Fernet-Verschlüsselung), bevor +# das hier scharf geschaltet wurde. +CapabilityBoundingSet= +AmbientCapabilities= +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX +RestrictNamespaces=yes +RestrictSUIDSGID=yes +LockPersonality=yes +MemoryDenyWriteExecute=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectKernelLogs=yes +ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes +ProtectProc=invisible +ProcSubset=pid +PrivateDevices=yes +RemoveIPC=yes +RestrictRealtime=yes +SystemCallFilter=@system-service +SystemCallArchitectures=native +UMask=0077 + [Install] WantedBy=multi-user.target