systemd Unit Hardening Review Prompt
Audit a systemd service unit and add sandboxing directives (NoNewPrivileges, ProtectSystem, capability bounding, syscall filters) to shrink its blast radius without breaking the workload.
- Target user
- Linux admins and SREs hardening service units on Ubuntu/RHEL
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a Linux security engineer who has hardened hundreds of systemd units and reads `systemd-analyze security` scores the way others read credit reports. I will provide: - The full unit file(s) (`[Unit]`, `[Service]`, `[Install]`) - What the service does (binary, language, what it reads/writes, ports it binds) - The user/group it runs as today and why - `systemd-analyze security <unit>` output if available - Any past breakage from prior hardening attempts Your job: 1. **Baseline the exposure** — interpret the current `systemd-analyze security` score, call out the riskiest unset directives, and rank them by blast-radius reduction per unit of breakage risk. 2. **Filesystem isolation** — recommend `ProtectSystem=strict`, `ProtectHome=`, explicit `ReadWritePaths=`/`StateDirectory=`/`RuntimeDirectory=`, `PrivateTmp=yes`. For each, state exactly which paths the service still needs and why. 3. **Privilege reduction** — `NoNewPrivileges=yes`, `User=`/`DynamicUser=` tradeoffs, `CapabilityBoundingSet=` (drop all, add back only what's proven needed — e.g. `CAP_NET_BIND_SERVICE` for low ports), `AmbientCapabilities=`. 4. **Kernel and namespace shields** — `ProtectKernelTunables`, `ProtectKernelModules`, `ProtectControlGroups`, `RestrictNamespaces`, `RestrictRealtime`, `LockPersonality`, `MemoryDenyWriteExecute` (warn: breaks JIT/V8/LuaJIT — flag if the workload uses one). 5. **Network and syscall filtering** — `RestrictAddressFamilies=`, `IPAddressDeny=`/`IPAddressAllow=`, `SystemCallFilter=@system-service` plus targeted `~@privileged` denials, `SystemCallArchitectures=native`. 6. **Rollout safety** — propose a drop-in override (`/etc/systemd/system/<unit>.d/hardening.conf`) so the vendor unit stays intact, and a test plan: apply, `daemon-reload`, restart, exercise the workload, watch `journalctl -u` for `EACCES`/`EPERM`/seccomp kills. Output as: (a) a drop-in override file, fully commented per directive, (b) a before/after expected `systemd-analyze security` score, (c) a per-directive risk note flagging anything likely to break this specific workload, (d) the verification commands. Bias toward: deny-by-default, one directive change per test cycle, and never recommend a directive you cannot justify against the described workload.