← All challenges
mediumlinux~25 min

The export daemon runs as root with no guardrails

A unit file straight from a wiki page - root, no restart policy, no sandboxing. Harden it with a service account, restart-on-failure, and systemd's filesystem and privilege guards.

Scenario

order-exportd ships orders to a partner every few minutes. The unit file was copied from a wiki page years ago: it runs as root, dies silently when the partner API hiccups (no restart policy), and has full write access to the entire filesystem and the shared /tmp. It parses data from the network; if it's ever compromised, the attacker is root with the run of the box.

A service account svc-export already exists.

Your job

Harden order-exportd.service without breaking it:

  • run as svc-export, not root,
  • restart automatically on failure,
  • NoNewPrivileges=yes: the process can never gain privileges, even via setuid binaries,
  • ProtectSystem=strict (or full): the OS is read-only as far as this service is concerned,
  • PrivateTmp=yes: its own private /tmp, invisible to other services,
  • keep ExecStart and the [Install] section working.

What "done" looks like

systemctl show order-exportd reports the hardened settings, the service still starts, and systemd-analyze security order-exportd stops screaming.

Teaches: systemd as a sandbox: User=, NoNewPrivileges, ProtectSystem and PrivateTmp turn a unit file into a real security boundary, not just a process launcher.

What gets checked

Your solution is verified against each of these:

  • The service runs as a dedicated non-root user
  • Restart= is set so a crash restarts the daemon
  • NoNewPrivileges prevents privilege escalation after start
  • ProtectSystem makes the OS read-only to the service
  • PrivateTmp isolates the service's temp files
  • ExecStart and the install target are intact

Solve it in your browser

No setup, no install. Write your solution in the editor and hit Check. The in-house engine renders and grades it instantly, then issues your proof the moment every check passes.

Solve in browser →

Prefer your own lab?

  1. Build the fix locally. New to the tooling? See setting up your lab.
  2. Push your topology file, device configs, and any playbooks to a public repo (GitHub or GitLab).
  3. Submit the repo link. We review it by hand, confirm it works, and issue your proof page.
Submit your solution →