bundles/left4me: add HARDENING_{COMMON,SERVER,WEB} constants
Three shared dicts capturing the proven hardening composition from the left4me hardening test plan (left4me commit 461b8d0). HARDENING_COMMON is the directive set both managed units take verbatim; HARDENING_SERVER adds the sudo-incompatible flags + filesystem virtualization + i386 amendment + PrivatePIDs + SocketBindAllow; HARDENING_WEB adds the sudo-compatible syscall filter. Not yet spread into the unit emission — that's the next commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
91b7265136
commit
85b9af0aaa
1 changed files with 91 additions and 0 deletions
|
|
@ -108,6 +108,97 @@ defaults = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Hardening composition — proven via the hardening test plan (left4me
|
||||||
|
# commit 461b8d0). See:
|
||||||
|
# docs/superpowers/specs/2026-05-15-hardening-threat-model.md
|
||||||
|
# docs/superpowers/specs/2026-05-15-hardening-defenses-survey.md
|
||||||
|
# docs/superpowers/specs/2026-05-15-hardening-test-plan.md
|
||||||
|
# docs/superpowers/specs/2026-05-15-hardening-refactor-design.md
|
||||||
|
# (paths in the left4me repo)
|
||||||
|
|
||||||
|
# Directives both managed units take verbatim.
|
||||||
|
HARDENING_COMMON = {
|
||||||
|
'ProtectProc': 'invisible',
|
||||||
|
'ProcSubset': 'pid',
|
||||||
|
'ProtectKernelTunables': 'true',
|
||||||
|
'ProtectKernelModules': 'true',
|
||||||
|
'ProtectKernelLogs': 'true',
|
||||||
|
'ProtectClock': 'true',
|
||||||
|
'ProtectControlGroups': 'true',
|
||||||
|
'ProtectHostname': 'true',
|
||||||
|
'LockPersonality': 'true',
|
||||||
|
'ProtectSystem': 'strict',
|
||||||
|
'ProtectHome': 'true',
|
||||||
|
'PrivateTmp': 'true',
|
||||||
|
'RestrictNamespaces': 'true',
|
||||||
|
'RestrictRealtime': 'true',
|
||||||
|
'RemoveIPC': 'true',
|
||||||
|
'KeyringMode': 'private',
|
||||||
|
'UMask': '0027',
|
||||||
|
'RestrictAddressFamilies': 'AF_INET AF_INET6 AF_UNIX',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gameserver unit: COMMON + sudo-incompatible flags + filesystem
|
||||||
|
# virtualization + i386 amendment + per-instance PID namespace + bound
|
||||||
|
# socket binds.
|
||||||
|
HARDENING_SERVER = {
|
||||||
|
**HARDENING_COMMON,
|
||||||
|
'NoNewPrivileges': 'true',
|
||||||
|
'RestrictSUIDSGID': 'true',
|
||||||
|
'PrivateUsers': 'true',
|
||||||
|
# PrivatePIDs is the test-plan amendment that closes D2.b: same-uid
|
||||||
|
# ProtectProc=invisible cannot hide gunicorn from srcds (both run
|
||||||
|
# as uid 980); a private PID namespace does.
|
||||||
|
'PrivatePIDs': 'true',
|
||||||
|
'PrivateIPC': 'true',
|
||||||
|
'PrivateDevices': 'true',
|
||||||
|
'CapabilityBoundingSet': '',
|
||||||
|
'AmbientCapabilities': '',
|
||||||
|
# srcds_linux is i386 (Source 2007 engine). Bare 'native' kills
|
||||||
|
# every 32-bit syscall and traps srcds_run in a respawn loop.
|
||||||
|
'SystemCallArchitectures': 'native x86',
|
||||||
|
'SystemCallFilter': (
|
||||||
|
'@system-service',
|
||||||
|
'~@debug @mount @raw-io @reboot @swap @cpu-emulation @obsolete @privileged',
|
||||||
|
),
|
||||||
|
'TemporaryFileSystem': '/var/lib /etc /opt /home /root /srv /mnt /media',
|
||||||
|
'BindReadOnlyPaths': (
|
||||||
|
'/var/lib/left4me/installation',
|
||||||
|
'/var/lib/left4me/overlays',
|
||||||
|
'/etc/left4me/host.env',
|
||||||
|
'/etc/ssl',
|
||||||
|
'/etc/ca-certificates',
|
||||||
|
'/etc/resolv.conf',
|
||||||
|
'/etc/nsswitch.conf',
|
||||||
|
'/etc/alternatives',
|
||||||
|
),
|
||||||
|
'BindPaths': '/var/lib/left4me/runtime/%i',
|
||||||
|
# Lock srcds bindable sockets to the game port range. Hard-coded
|
||||||
|
# range because systemd directive variable substitution is uneven.
|
||||||
|
'SocketBindAllow': (
|
||||||
|
'udp:27000-27999',
|
||||||
|
'tcp:27000-27999',
|
||||||
|
),
|
||||||
|
# MemoryDenyWriteExecute=true permanently excluded — Source engine
|
||||||
|
# i386 .so files have text relocations that need mprotect(W+X)
|
||||||
|
# during the dynamic linker's relocation pass.
|
||||||
|
}
|
||||||
|
|
||||||
|
# Web unit: COMMON + sudo-compatible additions. EXCLUDES
|
||||||
|
# NoNewPrivileges, PrivateUsers, RestrictSUIDSGID, empty
|
||||||
|
# CapabilityBoundingSet, and ~@privileged in the syscall filter — all
|
||||||
|
# sudo-incompatible until a future refactor replaces sudo with
|
||||||
|
# systemctl-managed transient units.
|
||||||
|
HARDENING_WEB = {
|
||||||
|
**HARDENING_COMMON,
|
||||||
|
'SystemCallArchitectures': 'native',
|
||||||
|
'SystemCallFilter': (
|
||||||
|
'@system-service',
|
||||||
|
'~@debug @mount @raw-io @reboot @swap @cpu-emulation @obsolete',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'nginx/vhosts',
|
'nginx/vhosts',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue