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:
-
oidentdwhich needs to monitor TCP connections via/proc/net/nf_conntrack(root:root,400). No matter how much you try toBindPathsandReadWritePathsyour way around the problem, the permissions still block you from reading the file as aDynamicUser(or other unprivileged user) withoutCAP_DAC_READ_SEARCH. -
uptimedwhich 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/procwithsubset=pid. A lot of the other hardening directives will automatically enableMountAPIVFS, making the rest of the system-wide files in/procvisible to the process even if you try to manually disable it withMountAPIVFS=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.