2025-11-05 21:12:41 +09:00
2025-11-05 21:12:41 +09:00

Systemd sandbox proxy

Warning

This software is unfinished

This is a small collection of tools that can be used to achieve more granular sandboxing for systemd units.

systemd-file-proxy

This program intends to assist a sandboxed service with reading select files with strict permissions, without needing to have those permissions.

A typical use case would be a service that could have run just fine as an unprivileged user, were it not for one or two files in /proc or /sys owned by root with 400 permissions, which the program needs to read in order to function. Some real life examples of this would be:

  • oidentd which needs to monitor TCP connections via /proc/net/nf_conntrack (root:root, 400). No matter how much you try to BindPaths and ReadWritePaths your way around the problem, the permissions still block you from reading the file as a DynamicUser (or other unprivileged user) without CAP_DAC_READ_SEARCH.

  • uptimed which wants to read the current bootid via /proc/stat (root:root, 444). While this is readable as an unprivileged user, it keeps you from being able to mount /proc with subset=pid. A lot of the other hardening directives will automatically enable MountAPIVFS, making the rest of the system-wide files in /proc visible to the process even if you try to manually disable it with MountAPIVFS=false.

The systemd-file-proxy will set up an inotify listener on one or more files, and quickly mirror it in a path of choice, with user and permission of choice.

systemd-exec-proxy

This program intends to assist a sandboxed service with executing executables that might need a lot more permissions and potentially a dynamic set of them.

The main offender here is sendmail, which is a binary that could be provided by a variety of MTAs and will often come as a setuid binary that messes around in the state directories of said MTA. This is not quite optimal for sandboxing, because you won't be able to passthrough all potential files and directories needed by the different MTAs. On top of this, running with PrivateUsers can make things complicated for the setuid part, even when you don't really need access to the rest of the user list.

systemd-exec-proxy will provide shims that can be put inside the sandbox for the program to execute. The shims will then communicate with the proxy daemon outside of the sandbox via a socket, which will let you execute the real program outside the sandbox. stdin/stdout/stderr and any other file descriptors will be streamed over the socket with multiplexed packets, and the shims will exit with the exit code given by the real program. In the case of separate namespaces, you can configure the daemon to run its commands as specificed users. It is also possible to run the proxy deamon outside in a less strict sandbox. All commands will need to be whitelisted for the daemon to run them, it should not be able to run arbitrary commands as if it was a fancy SSH session.

Description
inotify(7) your root:root 400 file into the chroot, sendmail(8) your way out of chroot
Readme 31 KiB