BlogLinux & scripting
Sandboxing Linux services with systemd security directives
Turn a plain unit file into a locked-down sandbox with ProtectSystem, NoNewPrivileges, and capability limits.
systemd can sandbox a service without containers, SELinux modules, or code changes — just directives in the unit file. Each one removes a capability the process almost certainly does not need, and systemd-analyze security scores how far you have locked it down.
A hardened unit
/etc/systemd/system/api.service
[Service]ExecStart=/usr/local/bin/apiDynamicUser=yesNoNewPrivileges=yesProtectSystem=strictProtectHome=yesPrivateTmp=yesPrivateDevices=yesReadWritePaths=/var/lib/apiCapabilityBoundingSet=RestrictAddressFamilies=AF_INET AF_INET6SystemCallFilter=@system-serviceSystemCallErrorNumber=EPERM
What each directive buys you
Filesystem
ProtectSystem=strict -> / read-only
ProtectHome=yes -> /home hidden
PrivateTmp=yes -> isolated /tmp
ReadWritePaths -> the one exception
Privilege
NoNewPrivileges -> no setuid escalation
CapabilityBoundingSet= -> drop all caps
SystemCallFilter -> syscall allowlist
DynamicUser -> ephemeral UID
Score it
systemd-analyze security api.service-> Overall exposure level: 9.6 UNSAFE (defaults)... add the directives above, daemon-reload ...-> Overall exposure level: 1.8 OK (hardened)Free and reversible
These are host-native, cost nothing at runtime, and you can dial them in one at a time — start with NoNewPrivileges, ProtectSystem, and PrivateTmp.