bwrapexample/sandbox.sh

108 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
USERID=`id -u`
GROUPID=`id -u`
NEW_HOME=$HOME
NATIVEUSERID=`id -u`
# The below would enforce even more disconnection from the system but confuses some programs
#USERID=123456
#GROUPID=123456
#NEW_HOME=/home/123456
# This is actually a nicety for users so they can add custom configs in sandbox/$1/addconf.sh
if [ -e $HOME/sandbox/$1/addconf.sh ]
then
ADDITIONALLINES=`cat $HOME/sandbox/$1/addconf.sh`
else
ADDITIONALLINES=""
fi
env=()
# With this we add every known environment variable to be unset, to minimize data leaks
# This is not secured against the keys being malicious.
for line in `compgen -v`; do
env+=("--unsetenv $line")
done
pci=()
# This is needed to give access for pci devices, so gpu acceleration (should mostly) work
for line in `ls /sys/devices/ | grep pci`; do
pci+=("--dev-bind /sys/devices/$line /sys/devices/$line")
done
# Same here, the calling tool needs to ensure $HOME and the passed arguments are not malicious.
# This creates the sandbox target directories
mkdir -p $HOME/sandbox/$1/main/$NEW_HOME
mkdir -p $HOME/sandbox/$1/tmp
#Adding Wayland, Pulse and Xorg sockets to overriden paths in /tmp
#where we also set XDG_TEMP_DIR to so XDG clients can interact with it
WAYLAND=""
if [ "$WAYLAND_DISPLAY" != "" ] && [ -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]
then
WAYLAND="--bind $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY /tmp/$WAYLAND_DISPLAY"
WAYLAND="$WAYLAND --setenv WAYLAND_DISPLAY $WAYLAND_DISPLAY"
fi
#Relies on the XDG socket, change this if you want a network based pulse!
PULSE=""
if [ -S "$XDG_RUNTIME_DIR/pulse/native" ]
then
PULSE="--bind $XDG_RUNTIME_DIR/pulse/native /tmp/pulse_socket"
PULSE="$PULSE --setenv PULSE_SERVER /tmp/pulse_socket"
fi
XORG=""
if [ "$DISPLAY" != "" ] && [ -d /tmp/.X11-unix ]
then
XORG="--bind /tmp/.X11-unix /tmp/.X11-unix"
XORG="$XORG --setenv DISPLAY $DISPLAY"
#Disable X Shared Memory (Might not be supported by all clients like wine)
#either compile wine yourself or disable the ipc namespace in that case
XORG="$XORG --setenv QT_X11_NO_MITSHM 1 --setenv _X11_NO_MITSHM 1 --setenv _MITSHM 0"
fi
env -i \
bwrap `#The base bwrap` \
--bind $HOME/sandbox/$1/main/ / `#this re-binds the virtual / in the users home to the bubblewrapped /` \
--bind $HOME/sandbox/$1/tmp/ /tmp `#Allow writing to a virtual /tmp as well` \
--ro-bind /bin /bin `#allow access to systems binaries` \
--ro-bind /etc /etc `#allow access to shared config etc` \
--ro-bind /usr /usr `#lots of .so files and executables here as well` \
--ro-bind /usr/sbin /sbin `#These are just compat rebinds` \
--ro-bind /usr/lib64 /lib64 `#compat` \
--ro-bind /usr/lib /lib `#compat` \
--proc /proc `#adds a virtual proc dir` \
--dev /dev `#adds a virtual dev dir` \
--dev-bind /dev/dri /dev/dri `#we have to bind this so tools can access accelerated rendering` \
--tmpfs /var `#allow writing from and to var, but a new empty one` \
--tmpfs /run --dir /run/user/$USERID `#same for run, but make sure the virtual user run dir exists` \
--bind $HOME/sandbox/$1/main/$NEW_HOME $NEW_HOME `#binding the user home to our wanted directory` \
--dev-bind /sys/dev/char /sys/dev/char `#more bindings for gpu accel access` \
${pci[@]} `#this will add all gpus in the system as dev-bind, so we can access them (gpu accel)` \
--unshare-all `#even if in the future more can be unshared, auto-do it` \
--unshare-user `#dont just try to unshare the user, enforce doing so!` \
--share-net `#bwrap override: allow network access` \
--new-session `#separates the called shell so the tool running cant inject into the calling cli` \
--hostname sb `#sets the virtual hostname` \
--uid $USERID `#force this virtual user id` \
--gid $GROUPID `#force this virtual group id` \
--die-with-parent `#if the first calling process dies - kill all children` \
--as-pid-1 `#the virtual process will get pid1 and think its the init process, to hide PIDs` \
--cap-drop ALL `#drops capabilities even if you run this as root (you likely shouldnt)` \
--chdir $NEW_HOME `#change working dir in the virtual env to this` \
`#${env[@]} # alternative way to get rid of all env vars, as they can expose host information. Superseded by env -i` \
--setenv HOME "$NEW_HOME" `#tricks some applications to accept the virtual home` \
--setenv PWD "$NEW_HOME" `#same` \
--setenv LC_ALL "en_US.UTF-8" `#set common lang - likely should get this from main os but no bug reports for it so far. :P` \
--setenv XDG_RUNTIME_DIR "/tmp" `#put desktop app temp files here if they rely on xdg` \
--setenv TERM "xterm-256color" `#enforce full color terms` \
--setenv COLORTERM "truecolor" `#not setting this can crash some term emulators` \
--setenv DEFAULT_USER $USERID `#more user trickery` \
--setenv PATH "/usr/local/bin:/usr/share/Modules/bin:/usr/lib64/ccache:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin" `#make tools aware of our modified preferred paths` \
--ro-bind /run/systemd/resolve/stub-resolv.conf /run/systemd/resolve/stub-resolv.conf `#Allow Resolving with systemd-resolved` \
$PULSE `#add sound` \
$WAYLAND `#allow wayland passthrough` \
$XORG `#Allow XORG passthrough` \
$ADDITIONALLINES `#add user config` \
$1 `#run the actual tool`