Secure Remote Access is the current field-guide cluster.Linux • Security • Self-hosting • Practical tools
Linux Server Hardening

systemd Sandboxing Directives to Learn First

systemd has useful sandboxing and hardening directives, but they are not magic paste-in security. The right starting point is to understand what each directive restricts, apply one change at a time, and test the actual service before declaring it hardened.

For small-server operators, the first directives to learn are the ones that limit filesystem writes, home-directory access, devices, privileges, capabilities, and network families.

Why systemd hardening is worth learning

A systemd service already defines how a daemon starts, which user it runs as, and how it is supervised. Hardening directives extend that unit file so the service gets fewer ways to touch the host if it is compromised.

That is useful because many self-hosted services do not need broad access to the filesystem, devices, kernel features, or the user’s home directories. Reducing those privileges can limit damage when an application bug becomes a security problem.

The catch: services are different. A directive that is safe for one daemon may break another.

The first directives to understand

Start with directives that map cleanly to a question you can answer about the service. Avoid giant hardening blocks copied from random examples.

Directive family Question it answers Why it matters
User= and Group= Should this service run as root? Non-root services have less default host power
ProtectSystem= Should the service write to OS paths? Makes parts of the filesystem read-only or stricter
ProtectHome= Should it read home directories? Blocks accidental access to user data
PrivateTmp= Does it need shared /tmp? Gives the service a private temporary area
NoNewPrivileges= Should child processes gain new privileges? Blocks common privilege-escalation paths
CapabilityBoundingSet= Which Linux capabilities are needed? Removes powerful kernel-level privileges
RestrictAddressFamilies= Which network families are needed? Limits unusual socket families
ReadWritePaths= Which paths must remain writable? Allows narrow write access when the rest is protected

The systemd.exec manual is the primary reference for these execution-environment and sandboxing settings. Use it over copied snippets.

Filesystem restrictions are usually the easiest win

Filesystem restrictions are often the safest first improvement because you can reason about them from the service’s data paths. If a service only needs to write under /var/lib/myapp and /var/log/myapp, it probably should not write anywhere else.

The pattern is:

  1. identify the service’s required state, config, cache, and log paths;
  2. make the broader system read-only where appropriate;
  3. add explicit writable paths only where needed;
  4. restart in a maintenance window;
  5. inspect logs for permission failures.

Do not skip step one. If you do not know where the service writes, hardening becomes guesswork.

Privilege restrictions need more care

Directives such as NoNewPrivileges= and CapabilityBoundingSet= can be powerful, but they require a clearer understanding of what the daemon needs from the kernel. Removing all capabilities may work for a simple web app and fail for a service that binds low ports, manages networking, or interacts with system resources.

The safe method is incremental:

This is where a systemd tool primer helps. You need to be comfortable reading service status and logs before tightening the sandbox.

Do not harden SSH casually

SSH is your recovery path. A broken SSH service can become a lockout, especially on a remote VPS without console access.

If you are hardening SSH, use a dedicated lockout-safe process like the Ubuntu SSH hardening guide and keep a second session or provider console ready. Generic systemd sandboxing advice should not be pasted into ssh.service during a casual maintenance pass.

The same caution applies to firewalls, VPN daemons, Tailscale, WireGuard, and tunnel connectors. Hardening the thing you rely on for access is a higher-risk change.

How to decide what to apply first

Apply the directive that matches your clearest risk and has the easiest test. Small, verified restrictions beat broad, untested hardening blocks.

A practical order:

  1. make sure the service runs as a dedicated user where appropriate;
  2. restrict home-directory access if it is not needed;
  3. isolate temporary directories;
  4. restrict write paths;
  5. reduce capabilities only after checking requirements;
  6. use more advanced namespace and syscall restrictions last.

This pairs well with a small VPS exposure audit. First know what is running; then harden the services that matter.

FAQ

Is systemd-analyze security enough to harden a service?

No. It is a useful review aid, but it cannot know every service-specific requirement. Treat it as a starting point, not an automatic fix list.

Can I copy a systemd hardening block from another service?

You can use examples for learning, but do not paste them blindly. Each directive should match what your service actually needs.

Which directive should I use first?

Start with the service user and filesystem access. Those are easier to reason about and easier to verify than broad capability or syscall restrictions.

Sources