75 lines
3.4 KiB
Desktop File
75 lines
3.4 KiB
Desktop File
[Unit]
|
|
Description=TESM -- Ueberwachung der PoE-Endgeraete
|
|
After=network-online.target tesm.service
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=tesm
|
|
Group=tesm
|
|
WorkingDirectory=/srv/tesm
|
|
Environment=TESM_BASE_DIR=/srv/tesm
|
|
Environment=TESM_DATA_DIR=/srv/tesm/data
|
|
Environment=TESM_LOG_DIR=/var/log/tesm
|
|
Environment=PYTHONUNBUFFERED=1
|
|
# Vor jedem Start: traegt die Python-Umgebung noch? Ein Release-Upgrade des
|
|
# Betriebssystems tauscht die Minor-Fassung von Python aus, und der venv haengt
|
|
# daran -- danach findet der Dienst kein einziges Paket mehr und scheitert mit
|
|
# "No module named gunicorn". Ist alles heil, kostet diese Zeile Millisekunden;
|
|
# sonst baut sie die Umgebung neu, einmal je Systemstart.
|
|
#
|
|
# Das "+" laesst den Schritt als root laufen. Noetig, weil der venv root
|
|
# gehoert, der Dienst aber als unprivilegierter Benutzer laeuft.
|
|
ExecStartPre=+/usr/local/lib/tesm/tesm-venv /srv/tesm tesm
|
|
ExecStart=/srv/tesm/venv/bin/tesm-monitor
|
|
# Ein Neuaufbau der Python-Umgebung laedt Pakete und dauert Minuten --
|
|
# die Vorgabe von 90 Sekunden wuerde ihn mittendrin abschneiden.
|
|
TimeoutStartSec=900
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
# Das Pruefintervall liest der Prozess bei jedem Durchlauf frisch aus der
|
|
# Datenbank -- der naechtliche Neustart-Timer des Vorgaengers entfaellt damit.
|
|
# 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
|
|
# 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
|
|
ProtectControlGroups=yes
|
|
RestrictSUIDSGID=yes
|
|
RestrictNamespaces=yes
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
|
|
LockPersonality=yes
|
|
SystemCallArchitectures=native
|
|
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/data /var/log/tesm /etc/tesm /run
|
|
# ping braucht CAP_NET_RAW -- als einzige Ausnahme, und nur diese.
|
|
AmbientCapabilities=CAP_NET_RAW
|
|
# 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.
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|