(no title)
mivirl | 11 months ago
Systemd has a lot of neat sandboxing features [1] which aren't well known but can be very useful for this. You can get pretty far using systemd-run [2] in a script like this:
#!/bin/sh
uid="$(id -u)"
gid="$(id -g)"
cwd="$(pwd -P)"
sudo systemd-run --system --pty --same-dir --wait --collect --service-type=exec \
--uid="$uid" \
--gid="$gid" \
-p "TemporaryFileSystem=/:ro /tmp" \
-p "BindReadOnlyPaths=-/bin -/sbin -/usr/bin -/usr/sbin -/lib -/lib64 -/usr/lib -/usr/lib64 -/usr/libexec" \
-p "BindPaths=$cwd" \
-p "PrivateNetwork=true" \
-p "PrivateDevices=true" \
-p "PrivateIPC=true" \
-p "RestrictNamespaces=true" \
-p "RestrictSUIDSGID=true" \
-p "CapabilityBoundingSet=" \
"$@"
Which creates a blank filesystem with no network or device access and only bind mount the specified files.Unfortunately TemporaryFileSystem require running as a system instance of the service manager rather than per-user instance, so that will generally mean running as root (hence sudo). One approach is to create a suid binary that does the same without needing sudo.
[1] https://www.freedesktop.org/software/systemd/man/latest/syst...
[2] https://www.freedesktop.org/software/systemd/man/latest/syst...
You could also use bubblewrap [3] pretty similarly, and may not need to use sudo if unprivileged user namespaces are allowed by your kernel.
#!/bin/sh
cwd="$(pwd -P)"
bwrap --new-session --die-with-parent \
--tmpfs /tmp \
--ro-bind-try /bin /bin \
--ro-bind-try /sbin /sbin \
--ro-bind-try /usr/bin /usr/bin \
--ro-bind-try /usr/sbin /usr/sbin \
--ro-bind-try /lib /lib \
--ro-bind-try /lib64 /lib64 \
--ro-bind-try /usr/lib /usr/lib \
--ro-bind-try /usr/lib64 /usr/lib64 \
--ro-bind-try /usr/libexec /usr/libexec \
--bind "$cwd" "$cwd" \
--dev-bind /dev/null /dev/null \
--dev-bind /dev/zero /dev/zero \
--dev-bind /dev/random /dev/random \
--unshare-net \
--unshare-ipc \
--cap-drop ALL \
--chdir "$cwd" \
"$@"
[3] https://github.com/containers/bubblewrap
homebrewer|11 months ago
It might also be helpful to just use --unshare-all, and then whitelist things you actually need (--share-net, etc).