# Hardening drop-in for left4me-web.service.
#
# Source of truth: this file (in left4me/deploy/files/). ckn-bw deploys
# it to /etc/systemd/system/left4me-web.service.d/10-hardening.conf via a
# target-side symlink into the checkout.
#
# See docs/superpowers/specs/2026-05-15-hardening-defenses-survey.md
# and 2026-05-15-hardening-test-plan.md for the threat model and the
# verification matrix.
#
# This unit is the web app; some sudo-incompatible directives are
# intentionally absent:
#   NoNewPrivileges       — blocks sudo's setuid escalation
#   PrivateUsers          — breaks sudo's host-root mapping
#   RestrictSUIDSGID      — blocks setuid()/setgid()
#   CapabilityBoundingSet — empty value would deny sudo's caps
#   @privileged exclusion in SystemCallFilter  — blocks sudo's setuid syscall
# All of those are unconditional on the gameserver unit (no sudo there).
[Service]
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ProtectProc=invisible
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectClock=true
ProtectControlGroups=true
ProtectHostname=true
LockPersonality=true
# `native x86` (not just `native`) — the install job fork-execs
# steamcmd_linux, a 32-bit binary, which makes i386-numbered syscalls.
# Under `native` alone the kernel SIGSYS-kills it (bash exit 159 =
# 128+SIGSYS). Mirrors the server unit, which needs the same allowance
# for srcds_linux. See deploy/files/etc/systemd/system/left4me-server@.service.d/10-hardening.conf.
SystemCallArchitectures=native x86
SystemCallFilter=@system-service
SystemCallFilter=~@debug @mount @raw-io @reboot @swap @cpu-emulation @obsolete
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RemoveIPC=true
KeyringMode=private
UMask=0027
