[Unit] Description=TESM-Lizenzserver Documentation=file:/srv/tesm-license/docs/BETRIEB.md After=network-online.target Wants=network-online.target [Service] Type=notify-reload User=tesm-license Group=tesm-license WorkingDirectory=/srv/tesm-license Environment=TESM_LICENSE_BASE_DIR=/srv/tesm-license Environment=TESM_LICENSE_DATA_DIR=/srv/tesm-license/data Environment=TESM_LICENSE_LOG_DIR=/var/log/tesm-license Environment=TESM_LICENSE_WEB_PROCESS=1 Environment=TESM_LICENSE_COOKIE_SECURE=1 Environment=PYTHONUNBUFFERED=1 ExecStart=/srv/tesm-license/venv/bin/gunicorn \ --workers 1 --worker-class gthread --threads 8 \ --bind 127.0.0.1:5001 \ --access-logfile - --error-logfile - \ tesm_license.wsgi:app Restart=always RestartSec=5 # -- Haertung --------------------------------------------------------------- # Der Dienst braucht kein Root, keine neuen Privilegien und keinen Zugriff auf # das System ausserhalb seiner eigenen Verzeichnisse. Was er trotzdem braucht # (systemctl, nginx, netplan), laeuft ueber den Helfer und sudo. # Bewusst **kein** NoNewPrivileges: der Dienst ruft den privilegierten Helfer # ueber sudo auf, und sudo ist setuid. Unter NoNewPrivileges verweigert der # Kernel die Rechteerhoehung, sudo bricht ab -- und damit jede Systemaktion aus # der Oberflaeche. Die Sicherheitsgrenze liegt nicht hier, sondern in der # sudoers-Regel (genau ein erlaubter Pfad) und im Helfer selbst (jedes Argument # gegen eine Positivliste). Siehe docs/SICHERHEIT.md. PrivateTmp=yes PrivateDevices=yes # ProtectSystem=full statt strict: "strict" sperrt den **ganzen Prozessbaum** # schreibgeschuetzt -- auch den Helfer, der als root gerade /etc/nginx, # /etc/netplan und /etc/kea schreiben soll. Gemessen: unter "strict" scheitert # schon "nginx -t". Mit "full" bleiben /usr und /boot schreibgeschuetzt, /etc # ist im Namensraum wieder erreichbar -- der unprivilegierte Dienst kommt # trotzdem nicht heran, denn die Dateien gehoeren root. Die Grenze ist damit # die gewoehnliche Dateiberechtigung plus die sudoers-Regel, nicht dieser # Schalter. ProtectSystem=full ProtectHome=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectKernelLogs=yes ProtectControlGroups=yes ProtectClock=yes ProtectHostname=yes ProtectProc=invisible RestrictSUIDSGID=yes RestrictRealtime=yes RestrictNamespaces=yes RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK LockPersonality=yes MemoryDenyWriteExecute=no SystemCallArchitectures=native SystemCallFilter=@system-service SystemCallErrorNumber=EPERM # Bewusst **kein** einschraenkendes CapabilityBoundingSet: sudo braucht # CAP_SETUID/CAP_SETGID, und der Helfer dahinter braucht Root. Was hier fehlt, # kann auch der Helfer nicht mehr erlangen -- gemessen: jede Einschraenkung # fuehrt zu "sudo: unable to change to root gid". Die Grenze ist die # sudoers-Regel und die Argumentpruefung im Helfer, nicht dieser Schalter. UMask=0027 # Genau die Pfade, die der privilegierte Helfer schreibt -- nicht mehr. # ProtectSystem=full sperrt /usr, /boot **und /etc**; ohne diese Freigaben # scheitert der Helfer mit "Read-only file system", obwohl er root ist # (gemessen). Der unprivilegierte Dienst kommt hier trotzdem nicht heran: die # Dateien gehoeren root, und sudo laesst nur den einen Helferpfad zu. ReadWritePaths=/srv/tesm-license/data /var/log/tesm-license /etc/nginx /etc/netplan /etc/logrotate.d /etc/tesm /run [Install] WantedBy=multi-user.target