diff --git a/app_containers/.local/bin/run_app_container b/app_containers/.local/bin/run_app_container index 0d08a15..9bd1a27 100755 --- a/app_containers/.local/bin/run_app_container +++ b/app_containers/.local/bin/run_app_container @@ -5,24 +5,9 @@ die() { exit 1 } -cleanup() { - rm -rf "$container_xdg_runtime" - # Remove the temporary facl-based permissions - setfacl -x u:$((user_on_host)) $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY - xhost -si:localuser:\#$((user_on_host)) - - for input in $(find /dev/input -type c); do - sudo setfacl -x u:$user_on_host $input - done -} - [ -z "$CONTAINER_NAME" ] && die "\$CONTAINER_NAME not set" [ -z "$DISPLAY" ] && die "\$DISPLAY not set (you must run the script in a desktop environment" -# Use a GUI-available askpass program for sudo -# This should be made configurable -export SUDO_ASKPASS=$HOME/.local/bin/askpass-bemenu - # Source configuration files if any config="$HOME/.config/app_containers/$CONTAINER_NAME.sh" if [ -f "$config" ]; then @@ -30,8 +15,8 @@ if [ -f "$config" ]; then fi # Create a XDG_RUNTIME_DIR for guest on host -container_xdg_runtime="$(mktemp -d -p /var/tmp)" -trap cleanup EXIT +container_xdg_runtime="$(mktemp -d)" +trap 'rm -rf -- "$container_xdg_runtime"' EXIT # Link the current wayland session to the container's xdg runtime # Note that the session itself must be bind-mounted first @@ -52,52 +37,17 @@ fi [ -S $host_pulse ] || die "PulseAudio UNIX socket not found" -# Default user -run_as=$UID +# Default username (assume `user` always has the same uid as the host user) +run_as=user +homedir=/home/user if [ "$CONTAINER_RUN_AS_ROOT" = true ]; then - run_as=0 + run_as=root + homedir=/root fi -homedir=/ -for line in $(sudo -A cat /var/lib/machines/$CONTAINER_NAME/etc/passwd); do - if [ "$(echo "$line" | cut -d: -f3)" == "$run_as" ]; then - homedir="$(echo "$line" | cut -d: -f6)" - break - fi -done - -# Userns-related config -# Default to identity mapping, which does not provide uid isolation but does for capabilities -private_users=identity -bind_opts="" -user_on_host=$run_as -if [ "$CONTAINER_USE_USERNS" = true ]; then - private_users=$(shuf -i 65536-$((2147483647 - 65536)) -n1) # Pick a random starting offset - bind_opts="idmap" - user_on_host=$((private_users + run_as)) -fi - -# Grant the user inside the container access to the Wayland / Xorg display -# For the Wayland socket, a simple facl rule would suffice -# For Xorg, we need to use the `xhost` facilities -setfacl -m u:$user_on_host:rwx $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY -xhost +si:localuser:\#$user_on_host - -# Grant the user inside the container access to input devices -# Note: any new device plugged in when the container is running would not -# be added properly here. -for input in $(find /dev/input -type c); do - sudo -A setfacl -m u:$user_on_host:rw- $input -done - -# Bind-mounts defined by the user (possibly in the container-specific config file) -# Format should be "src:target". target cannot be omitted -for mount in ${CONTAINER_BIND_MOUNTS[@]}; do - SYSTEMD_NSPAWN_EXTRA_ARGS+=" --bind=$mount:$bind_opts" -done - -sudo -A systemd-nspawn -M $CONTAINER_NAME \ - --private-users=$private_users --private-users-ownership=map \ +SUDO_ASKPASS=$HOME/.local/bin/askpass-bemenu sudo -A systemd-nspawn -M $CONTAINER_NAME \ + `# This doesn't provide userns isolation, but it does provide capability isolation` \ + --private-users=identity \ `# DNS (when containers do not have their own netns)` \ --bind-ro=/run/systemd/resolve/stub-resolv.conf:/etc/resolv.conf \ `# GPU` \ @@ -107,7 +57,7 @@ sudo -A systemd-nspawn -M $CONTAINER_NAME \ --bind-ro=/dev/input \ --property=DeviceAllow='char-input r' \ `# Xdg runtime` \ - --bind=$container_xdg_runtime:/run/xdg:$bind_opts \ + --bind=$container_xdg_runtime:/run/xdg \ --setenv=XDG_RUNTIME_DIR=/run/xdg \ `# Xorg / Xwayland` \ --bind=/tmp/.X11-unix \