README: init

This commit is contained in:
2025-11-05 21:12:41 +09:00
commit 4277c85c3c

28
README.md Normal file
View File

@@ -0,0 +1,28 @@
# 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 `MTA`s 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.