To harden a systemd service, restrict the files, privileges, network interfaces, and system calls it can use; to contain resource use, set separate CPU, memory, and task limits. These controls are configured in unit files, but the right settings depend on what the application actually needs and on the systemd and kernel versions installed on the host.
Which systemd settings address security and resource use?
Security sandboxing and resource controls solve different problems. Most execution-environment restrictions are documented in systemd.exec(5); cgroup-based resource controls are documented in systemd.resource-control(5). Check the manuals installed on the target host, because available directives and behavior can vary by systemd version and kernel support.
| Goal | Relevant settings | What to verify |
|---|---|---|
| Reduce filesystem access | ProtectSystem=, ProtectHome=, PrivateTmp= |
Required data paths, writable locations, shared temporary files, and Unix-socket communication |
| Limit privilege gains | NoNewPrivileges=, CapabilityBoundingSet= |
Whether the service or its child processes require privilege-changing operations or specific capabilities |
| Constrain network and kernel interfaces | RestrictAddressFamilies=, SystemCallFilter=, MemoryDenyWriteExecute= |
Address families, system calls, and executable-memory behavior the application uses |
| Contain unit resource use | CPUQuota=, memory controls such as MemoryHigh= and MemoryMax=, TasksMax= |
Workload peaks, acceptable failure behavior, and local cgroup support |
How do filesystem protections affect a service?
ProtectSystem= limits writes
ProtectSystem= provides progressively broader read-only filesystem restrictions. Consult the installed manual for the exact behavior of each value rather than assuming that the setting makes every path inaccessible or immutable. For example, the upstream manual documents an interaction in which /tmp/ and /var/tmp/ remain writable when ProtectSystem=strict is combined with PrivateTmp=.
ProtectHome= restricts private user data
Depending on its value, ProtectHome= can make /home/, /root, and /run/user inaccessible, read-only, or subject to temporary-filesystem behavior. The systemd execution-environment manual recommends enabling it for long-running services, particularly network-facing ones, unless they need access to private user data. The recommendation concerns ProtectHome=; it is not a claim that every service can run without home-directory access.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11#1 Best Overall
PrivateTmp= separates temporary directories
PrivateTmp= gives a service private temporary directories. Before enabling it, check whether the service exchanges files in /tmp or /var/tmp with another unit or process.
Filesystem namespace restrictions are one layer of protection, not a complete isolation boundary. Read-only path restrictions do not prevent every form of communication: Unix sockets in affected directories can still provide a communication path. Check the service’s IPC requirements as well as its file access.
Rank #2
How can you reduce privileges and kernel access?
NoNewPrivileges= prevents certain privilege gains
NoNewPrivileges= prevents the service and its descendants from gaining new privileges through execve() mechanisms such as set-user-ID or set-group-ID bits and filesystem capabilities. Confirm that the service does not rely on those mechanisms before enabling it.
CapabilityBoundingSet= narrows available capabilities
CapabilityBoundingSet= can restrict the capabilities available to unit processes. Determine which capabilities the service needs for its actual operations; removing one without checking can break startup or runtime functions.
RestrictAddressFamilies= limits socket families
RestrictAddressFamilies= constrains which socket address families the service can use. Include every family needed for its network activity and local IPC. A daemon that uses Unix-domain sockets, for example, needs the relevant local family as well as any network families its operation requires.
SystemCallFilter= narrows system calls
SystemCallFilter= supports both allow-list and deny-list approaches. An allow-list can be highly restrictive, so validate it against normal application behavior. Deny lists also need maintenance as system-call interfaces evolve; a filter that works now may need review after kernel or application changes.
Rank #4
MemoryDenyWriteExecute= can conflict with generated code
Some programs generate executable code dynamically, including JIT engines. Such applications may be incompatible with MemoryDenyWriteExecute=. Check application requirements and the installed systemd manual before enabling it.
How should you set CPU, memory, and task limits?
These controls address distinct resources and operate through the kernel’s control-group mechanism. Configure cgroup resource settings in the appropriate unit section, such as [Service], and check the local resource-control manual for the directives supported by the installed systemd version and kernel.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
| Control | Resource bounded | Practical consideration |
|---|---|---|
CPUQuota= |
CPU time relative to one CPU | CPUQuota=20% is the systemd manual’s example for ensuring the executed processes never receive more than 20% CPU time on one CPU. Values above 100% permit use across more than one CPU. |
MemoryHigh= and MemoryMax= |
Memory, using separate memory controls | Check local support and choose ceilings with workload peaks and failure behavior in mind. |
TasksMax= |
Tasks in the unit’s control group | Check local support and account for the service’s normal process and task requirements. |
A ceiling set too low can make a healthy service fail under legitimate load. Base limits on observed workload needs and decide in advance what behavior is acceptable if a limit is reached. These controls are not interchangeable with LimitNOFILE=, LimitNPROC=, and similar per-process limits: those settings have a different scope and behavior from unit-level cgroup controls.
How do you apply restrictions without breaking the service?
- Check the host’s documentation. Record the installed systemd version and consult its local
systemd.exec(5)andsystemd.resource-control(5)manuals. Confirm kernel and cgroup support for the controls you intend to use. - Map the service’s needs. Identify writable data paths, home-directory access, shared temporary files, Unix sockets, network address families, capabilities, and expected system calls.
- Add restrictions incrementally. Start with settings that match known service requirements. Apply extra care to capability restrictions and syscall filters, which can block application behavior that is not obvious from its unit file.
- Set resource ceilings deliberately. Account for normal workload peaks and decide what failure or throttling behavior is acceptable before choosing CPU, memory, or task limits.
- Reload, restart, and exercise the service. After changing a unit file, run
systemctl daemon-reload, restart the service, inspect its status and logs, and test its normal functions. - Recheck after changes. Review the profile after application upgrades and systemd or kernel changes, especially if it includes syscall filters or version-dependent controls.
There is no universal hardening profile established by these directives’ documentation. A restriction is useful only if it reduces access or resource exposure without blocking the service’s required behavior.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

