Sandbox the systemd unit: DynamicUser, read-only FS, no capabilities
The Linux install now mirrors the Windows virtual-account hardening: the unit runs with DynamicUser=yes (transient per-service UID, no login), ProtectSystem=strict with only StateDirectory writable (the install dir, so self-update can rewrite the binary), NoNewPrivileges, empty capability sets, restricted address families and a @system-service syscall filter. Install copies the binary to /var/lib/gpu-turnstile and the config to /etc/gpu-turnstile.env; Remove cleans up the unit and binary but keeps the config.
This commit is contained in:
@@ -195,12 +195,22 @@ install|remove` does the same thing.
|
||||
|
||||
### Linux (systemd)
|
||||
|
||||
- `--install-service` writes `/etc/systemd/system/gpu-turnstile.service`
|
||||
with `ExecStart` pointing at the current executable and the `-config`
|
||||
file, then runs `systemctl daemon-reload` and `enable --now`. The unit
|
||||
runs as root (it must be able to overwrite its own binary for
|
||||
self-updates); harden with `ProtectSystem=strict` plus a writable
|
||||
`ReadWritePaths` if desired.
|
||||
- `--install-service` copies the binary to `/var/lib/gpu-turnstile/`,
|
||||
copies the config to `/etc/gpu-turnstile.env` if none exists there yet,
|
||||
writes `/etc/systemd/system/gpu-turnstile.service`, then runs `systemctl
|
||||
daemon-reload` and `enable --now`. `--remove-service` removes the unit
|
||||
and the installed binary; the `/etc` config stays.
|
||||
- **Sandboxing** mirrors the Windows virtual account: the unit runs with
|
||||
`DynamicUser=yes` — a transient per-service UID with no login, no home
|
||||
and no password, managed entirely by systemd. `ProtectSystem=strict`
|
||||
makes the filesystem read-only except `StateDirectory=gpu-turnstile`
|
||||
(the install dir, so self-updates can rewrite the binary), plus
|
||||
`NoNewPrivileges`, `ProtectHome`, `PrivateTmp`, `ProtectKernel*`,
|
||||
`ProtectControlGroups`, `RestrictNamespaces`, `RestrictSUIDSGID`,
|
||||
`RestrictRealtime`, `LockPersonality`, `MemoryDenyWriteExecute`, empty
|
||||
capability sets, `RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6` and
|
||||
`SystemCallFilter=@system-service`. The proxy needs only outbound
|
||||
TCP/UDP and the notify socket, so it loses nothing.
|
||||
- The unit is `Type=notify`: the binary sends `READY=1` via
|
||||
`github.com/coreos/go-systemd` only after the listeners are bound, so
|
||||
`systemctl start` blocks until the proxy accepts connections. A 30 s
|
||||
|
||||
Reference in New Issue
Block a user