diff --git a/deploy/files/usr/local/libexec/left4me/left4me-script-sandbox b/deploy/files/usr/local/libexec/left4me/left4me-script-sandbox index d317b5b..bbbf496 100755 --- a/deploy/files/usr/local/libexec/left4me/left4me-script-sandbox +++ b/deploy/files/usr/local/libexec/left4me/left4me-script-sandbox @@ -7,12 +7,16 @@ # absolute path to a bash file already written by the web app; # bind-mounted read-only at /script.sh inside the sandbox. # -# The script runs under bubblewrap inside a transient systemd scope so we get -# cgroup-v2 limits (memory / tasks / cpu) and a wallclock kill via -# RuntimeMaxSec. The sandbox drops to the unprivileged l4d2-sandbox UID; -# host filesystems are exposed read-only except /overlay (rw) and tmpfs -# /tmp + /run. Network namespace is *not* unshared — scripts must reach the -# public internet to download workshop / l4d2center / cedapug content. +# The script runs as a transient systemd .service with the full hardening +# surface: cgroup limits + walltime kill, NoNewPrivileges, ProtectSystem, +# ProtectHome, kernel-tunable / -module / -log protection, namespace +# restriction, address-family restriction, capability bounding (empty), +# seccomp filter (@system-service @network-io), MemoryDenyWriteExecute, +# LockPersonality, RestrictSUIDSGID. Network namespace is *not* restricted — +# scripts must reach the public internet to download workshop / l4d2center +# / cedapug content. PID namespace is shared with the host (no +# PrivatePID= directive in systemd); host PIDs are visible via /proc but +# not signal-able due to UID mismatch. set -euo pipefail [[ $# -eq 2 ]] || { echo "usage: $0