DEV Community

Cover image for Understanding Systemd.exec - Part 1: How to Secure Applications Running in Systemd?
Ganesh Kumar
Ganesh Kumar

Posted on

Understanding Systemd.exec - Part 1: How to Secure Applications Running in Systemd?

Hello, I'm Ganesh. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on GitHub. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.

If you are running applications with systemd and want to restrict how they interact with Linux kernel features (like filesystem, processes, and capabilities), you can use the systemd.exec configuration options.

In this article I will be going to explain how to use these options to secure your application.

What are systemd.exec options?

Systemd.exec options are a set of configuration options that are used to configure how a systemd service interacts with the Linux kernel.

This feature is mainly used to provide security for the applications running in systemd.

Why we need this option in first place?

  • Hardening services (Postgres, Nginx, workers, etc) which are mostly open to the internet
  • Reducing blast radius after compromise
  • Lightweight (no container overhead)

How is this different from Docker?

  • Works on a single process/service.
  • Applies restrictions on top of the host.
  • Uses kernel features (namespaces, cgroups, capabilities)
  • Shares the same root filesystem (by default)
  • No packaging, no images

What is the real usecase?

Let's take an example of service.

/etc/systemd/system/myapp.service
Enter fullscreen mode Exit fullscreen mode

Inside this file, we can control:

  • Where the app runs
  • Which user it runs as
  • What it can access
  • How secure / isolated it is
  • What resources it can use

Most common options

  1. Run a service as non-root (security)

Set User= Group= to a non-privileged user (e.g. postgres, www-data).
This will prevent the service from running as root, which can lead to security vulnerabilities.

For example:

[Service]
User=postgres
Group=postgres
Enter fullscreen mode Exit fullscreen mode
  1. Restrict filesystem access

Set ProtectSystem= ProtectHome= ReadWritePaths= ReadOnlyPaths= to control filesystem access.
This will make service only read/ write specifed directory.

Example:

[Service]
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/postgresql
ReadOnlyPaths=/var/lib/postgresql/16/bin
Enter fullscreen mode Exit fullscreen mode
  1. Isolate runtime environment (like lightweight container)

Set PrivateTmp=yes NoNewPrivileges=yes to isolate runtime environment.
As there is no container like docker this will be running in the host but under private tmp and no new privileges.

Example:

[Service]
PrivateTmp=yes
NoNewPrivileges=yes
Enter fullscreen mode Exit fullscreen mode
  1. Limit resources (avoid abuse / crashes)

Set CPUQuota= MemoryMax= MemoryHigh= MemoryLimit= MemoryAccounting= to limit resources.
If we want specific service to use only limited resources, we can use these options.

Example:

[Service]
CPUQuota=50%
MemoryMax=512M
Enter fullscreen mode Exit fullscreen mode
  1. Provide controlled writable directories Set ReadWritePaths= ReadOnlyPaths= to control filesystem access. This will make service only read/ write specifed directory.

Example:

[Service]
ReadWritePaths=/var/lib/postgresql
ReadOnlyPaths=/var/lib/postgresql/16/bin
Enter fullscreen mode Exit fullscreen mode
  1. Drop dangerous privileges

Set CapabilityBoundingSet= to drop dangerous privileges.
This will make service only able to run commands with specific privileges.

Example:

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
Enter fullscreen mode Exit fullscreen mode
  1. Run temporary / ephemeral services Set RuntimeDirectory= StateDirectory= LogsDirectory= to run temporary / ephemeral services. This will run the service in a temporary / ephemeral directory.

Example:

[Service]
RuntimeDirectory=myapp
StateDirectory=myapp
LogsDirectory=myapp
Enter fullscreen mode Exit fullscreen mode
  1. Limit process / thread count Set TasksMax= to limit process / thread count. This will make service only able to run with specific process / thread count.

Example:

[Service]
TasksMax=100
Enter fullscreen mode Exit fullscreen mode
  1. Restrict access to system calls Set SystemCallFilter= SystemCallArchitectures= to restrict access to system calls. This will make service only able to use specific system calls.

Example:

[Service]
SystemCallFilter=open,read,write,close
SystemCallArchitectures=amd64
Enter fullscreen mode Exit fullscreen mode
  1. Security measures for Docker Engine Set Delegate=yes to run Docker Engine with specific privileges. This will make Docker Engine only able to run with specific privileges.

Example:

[Service]
Delegate=yes
Enter fullscreen mode Exit fullscreen mode

Conclusion

We could able to use systemd.exec options to secure application running in systemd.

But Until we integrate with real application and test these options, we can't be sure about the security.

In the next article we will see how service react with integrations of these options.

Reference Man Page Systemd : https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

git-lrc

Any feedback or contributors are welcome! It’s online, source-available, and ready for anyone to use.
⭐ Star it on GitHub: https://github.com/HexmosTech/git-lrc

Top comments (0)