Let the manager run the helper through sudo
ProtectKernelTunables, ProtectKernelModules and LockPersonality imply NoNewPrivileges for a non-root unit, so sudo refused to start the helper (hostname, reboot, network changes all failed). Guarded by a test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e14e1f83ca
commit
1eabb839d3
2 files changed
+33
-3
No files matched your search
@@ -22,10 +22,10 @@ SyslogIdentifier=voxip-kiosk-manager
|
|||||||
# "sudo -n voxip-kiosk-helper" inherits this unit's mount namespace and must
|
# "sudo -n voxip-kiosk-helper" inherits this unit's mount namespace and must
|
||||||
# be able to write /etc (hostname, NetworkManager profiles). The web process
|
# be able to write /etc (hostname, NetworkManager profiles). The web process
|
||||||
# itself runs unprivileged as user voxip and can only write its own dirs.
|
# itself runs unprivileged as user voxip and can only write its own dirs.
|
||||||
ProtectKernelTunables=yes
|
# Also no ProtectKernelTunables/ProtectKernelModules/LockPersonality,
|
||||||
ProtectKernelModules=yes
|
# RestrictSUIDSGID, SystemCall*, ...: for a non-root unit those imply
|
||||||
|
# NoNewPrivileges, and sudo then refuses to run (tests/test_units.py).
|
||||||
ProtectControlGroups=yes
|
ProtectControlGroups=yes
|
||||||
LockPersonality=yes
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
UNITS = Path(__file__).resolve().parent.parent / "systemd"
|
||||||
|
|
||||||
|
# Settings that make systemd set no_new_privs for a unit that does not run as root
|
||||||
|
# (systemd.exec(5)). sudo cannot gain root under that flag.
|
||||||
|
IMPLY_NO_NEW_PRIVILEGES = (
|
||||||
|
"NoNewPrivileges", "SystemCallFilter", "SystemCallArchitectures", "RestrictAddressFamilies",
|
||||||
|
"RestrictNamespaces", "PrivateDevices", "ProtectKernelTunables", "ProtectKernelModules",
|
||||||
|
"ProtectKernelLogs", "ProtectClock", "MemoryDenyWriteExecute", "RestrictRealtime",
|
||||||
|
"RestrictSUIDSGID", "DynamicUser", "LockPersonality",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def settings(unit):
|
||||||
|
result = {}
|
||||||
|
for line in (UNITS / unit).read_text().splitlines():
|
||||||
|
key, sep, value = line.partition("=")
|
||||||
|
if sep and not line.startswith("#"):
|
||||||
|
result[key.strip()] = value.strip()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def test_manager_can_use_sudo_for_the_helper():
|
||||||
|
unit = settings("voxip-kiosk-manager.service")
|
||||||
|
assert unit["User"] == "voxip"
|
||||||
|
for key in IMPLY_NO_NEW_PRIVILEGES:
|
||||||
|
assert unit.get(key, "no") in ("no", "false", ""), key
|
||||||
|
for key in ("ProtectSystem", "ProtectHome", "PrivateTmp"):
|
||||||
|
assert key not in unit, key
|
||||||
Reference in new issue
Block a user