systemd

From Kicksecure
Jump to navigation Jump to search
Design Previous page: Donation systray Index page: Design Next page: seccomp systemd

systemd versus non-systemd / Miscellaneous / Find systemd dependency cycles.

systemd security features

[edit]

Systemd has a long list of security hardening features for systemd unit files.

Non-exhaustive list. Written April 2026.

The goal of the list isn't replacing systemd upstream documentation, completeness, or perfection. The purpose is to provide a rationale for using systemd.

This table intentionally uses short upstream verbatim excerpts that give a reader an initial clue why a directive can improve service isolation. For some settings, especially DynamicUser= together with the directory helpers, the security benefit is clearest when multiple directives are combined.

systemd service hardening directives with upstream verbatim excerpts
Directive Upstream excerpt
NoNewPrivileges=yes

can never gain new privileges through execve()

[1]
PrivateTmp=yes

private /tmp/ and /var/tmp/ directories

[1]
PrivateDevices=yes

turn off physical device access by the executed process

[1]
ProtectSystem=strict

the entire file system hierarchy is mounted read-only

[1]
ProtectHome=read-only

the three directories are made read-only instead

[1]
ProtectControlGroups=yes

will be made read-only to all processes of the unit

[1]
ProtectKernelTunables=yes

kernel variables accessible through /proc/sys/, /sys/, /proc/sysrq-trigger, /proc/latency_stats, /proc/acpi, /proc/timer_stats, /proc/fs and /proc/irq will be made read-only

[1]
ProtectKernelModules=yes

explicit module loading will be denied

[1]
ProtectKernelLogs=yes

access to the kernel log ring buffer will be denied

[1]
ProtectClock=yes

writes to the hardware clock or system clock will be denied

[1]
ProtectHostname=yes

changing hostname or domainname via sethostname() and setdomainname() system calls is prevented

[1]
LockPersonality=yes

locks down the personality(2) system call

[1]
MemoryDenyWriteExecute=yes

writable and executable at the same time

[1]
RestrictSUIDSGID=yes

set the set-user-ID (SUID) or set-group-ID (SGID) bits

[1]
RestrictRealtime=yes

any attempts to enable realtime scheduling in a process of the unit are refused

[1]
RestrictNamespaces=yes

Restricts access to Linux namespace functionality

[1]
SystemCallArchitectures=native

disabling non-native ABIs

[1]
SystemCallFilter=@system-service

relatively safe basic choice for the majority of system services

[1]
SystemCallErrorNumber=EPERM

to return when the system call filter configured with SystemCallFilter= is triggered, instead of terminating the process immediately

[1]
CapabilityBoundingSet=

Controls which capabilities to include in the capability bounding set

[1]
AmbientCapabilities=

Controls which capabilities to include in the ambient capability set

[1]
PrivateUsers=yes

new user namespace

[1]
PrivateMounts=yes

private file system (mount) namespace

[1]
PrivateIPC=yes

sets up a new IPC namespace

[1]
PrivatePIDs=yes

new PID namespace

[1]
ProtectProc=invisible

When set to "invisible" processes owned by other users are hidden from /proc/.

[1]
ProcSubset=pid

If "pid", all files and directories not directly associated with process management and introspection are made invisible in the /proc/ file system

[1]
RemoveIPC=yes

System V and POSIX IPC objects

[1]
UMask=0077

file mode creation mask

[1]
IPAddressDeny=any

implement an allow-listing IP firewall

[2]
IPAddressAllow=...

Access is granted

[2]
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

address family names to allow-list, such as AF_UNIX, AF_INET or AF_INET6

[1]
SocketBindDeny=any

binding is denied when the socket address matches an entry in the SocketBindDeny= list

[2]
SocketBindAllow=...

Binding to a socket is allowed when a socket address matches an entry in the SocketBindAllow= list

[2]
ReadWritePaths=...

Use ReadWritePaths= in order to allow-list specific paths for write access if ProtectSystem=strict is used.

[1]
ReadOnlyPaths=...

Paths listed in ReadOnlyPaths= are accessible for reading only, writing will be refused even if the usual file access controls would permit this.

[1]
InaccessiblePaths=...

Paths listed in InaccessiblePaths= will be made inaccessible for processes inside the namespace along with everything below them in the file system hierarchy.

[1]
TemporaryFileSystem=/var:ro

This is useful to hide files or directories not relevant to the processes invoked by the unit, while necessary files or directories can be still accessed by combining with BindPaths= or BindReadOnlyPaths=:

[1]
DevicePolicy=closed

closed in addition, allows access to standard pseudo devices including /dev/null, /dev/zero, /dev/full, /dev/random, and /dev/urandom.

[2]
DeviceAllow=...

Control access to specific device nodes by the executed processes. This functionality is implemented using eBPF filtering.

[2]
DynamicUser=yes

Setting DynamicUser=yes implies ProtectSystem=strict and ProtectHome=read-only.

[3]
StateDirectory=...

If DynamicUser= is used, the logic for CacheDirectory=, LogsDirectory= and StateDirectory= is slightly altered: the directories are created below /var/cache/private, /var/log/private and /var/lib/private, respectively, which are host directories made inaccessible to unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID recycling.

[1]
CacheDirectory=...

If DynamicUser= is used, the logic for CacheDirectory=, LogsDirectory= and StateDirectory= is slightly altered: the directories are created below /var/cache/private, /var/log/private and /var/lib/private, respectively, which are host directories made inaccessible to unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID recycling.

[1]
LogsDirectory=...

If DynamicUser= is used, the logic for CacheDirectory=, LogsDirectory= and StateDirectory= is slightly altered: the directories are created below /var/cache/private, /var/log/private and /var/lib/private, respectively, which are host directories made inaccessible to unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID recycling.

[1]
RuntimeDirectory=...

If you set it to a directory name of your choice, it will be created below /run when the service is started, and removed in its entirety when it is terminated.

[3]
PrivateNetwork=yes

turn off network access by the executed process

[1]
NetworkNamespacePath=...

Sets a file system path to a Linux network namespace pseudo-file

[1]
RestrictFileSystems=...

Restricts the set of filesystems processes of this unit can open files on

[1]
KeyringMode=private

a new session keyring is allocated when a service process is invoked, and it is not linked up with any user keyring

[1]

systemd versus non-systemd

[edit]

Kicksecure is a systemd-based distribution. Kicksecure is not anti-systemd.

The Kicksecure lead developer isn't convinced by anti-systemd arguments justifying a move to a non-systemd distribution. (Elaborated in forums.)archive.org iconarchive.today icon

Non-systemd is unsupported because no contributors support this use case.

See also:

systemd interface opinion

[edit]

TODO: expand

The interfaces (the way packages and distributions can place configuration files there) of

  • /usr/lib/systemd/system/unit-name.service(.d);
    • ability to easily use capabilities and syscall filters for security hardening
  • systemd tmpfiles.darchive.org iconarchive.today icon / /usr/lib/tmpfiles.d/;

are excellent.

The The Boot Loader Interfacearchive.org iconarchive.today icon LoaderSystemToken feature sounds excellent.

Bad things:

  • journal log being binary
  • adding systemd into the names of tools such as systemd-resolved, systemd-networkd and making these systemd-dependent
  • systemd-boot only supporting Intel/AMD64 architectureKicksecure lead developer opinion.

Systemd User Environment Variables Configuration

[edit]

1

mkdir -p ~/.config/environment.d/

2 Open file ~/.config/environment.d/electrumx.conf in a text editor of your choice as a regular, non-root user.

If you are using a graphical environment, run. featherpad ~/.config/environment.d/electrumx.conf

If you are using a terminal, run. nano ~/.config/environment.d/electrumx.conf

3 Paste the following contents.

COIN=Bitcoin DB_DIRECTORY=~/.electrumx DAEMON_URL=username:password@127.0.0.1 SERVICES=rpC://localhost PEER_DISCOVERY=self

4 Save.

5

systemctl --user daemon-reload

6 Done.

The systemd user environment variables configuration has been created and reloaded.

systemd age API

[edit]

Interesting

[edit]

See Also

[edit]

Footnotes

[edit]

Design Previous page: Donation systray Index page: Design Next page: seccomp

Notification image

We believe security software like Kicksecure needs to remain Open Source and independent. Would you help sustain and grow the project? Learn more about our 14 year success story and maybe DONATE!