Compare commits

..

9 commits

Author SHA1 Message Date
Peter Cai edcfaef386 app_containers: Move to using CONTAINER_BIND_MOUNTS for extra binds
...instead of the overly generic SYSTEMD_NSPAWN_EXTRA_ARGS variable.
2022-12-31 15:26:51 -05:00
Peter Cai 19f37e343b app_containers: Rename the cleanup routine to cleanup()
exit is actually a keyword in bash
2022-12-31 15:22:16 -05:00
Peter Cai 8ce1f690b7 app_containers: Force the use of SUDO_ASKPASS 2022-12-31 15:21:20 -05:00
Peter Cai edddafda26 app_containers: Grant input devices access to inside the container 2022-12-31 15:20:03 -05:00
Peter Cai da9414d4a8 app_containers: Properly support different UID on host / in container
We simply use the same logic as the user namespaced case.
2022-12-31 15:14:32 -05:00
Peter Cai fd3fcf1e36 app_containers: Detect the user home directory dynamically
...so that we can stop assuming the username inside the container
(although the shortcut generation script still does, but we'll fix that
later, hopefully)
2022-12-31 15:08:55 -05:00
Peter Cai 8aa252305d app_containers: Define SUDO_ASKPASS first 2022-12-31 15:04:35 -05:00
Peter Cai fab54bfafa app_containers: Use UID instead of username for $run_as
Note that we still assume the user name inside the container is `user`.
2022-12-31 15:01:54 -05:00
Peter Cai fc6ee67cf2 app_containers: Optionally support user namespaces
using the env variable CONTAINER_USE_USERNS
2022-12-31 14:46:23 -05:00

View file

@ -5,9 +5,24 @@ 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
@ -15,8 +30,8 @@ if [ -f "$config" ]; then
fi
# Create a XDG_RUNTIME_DIR for guest on host
container_xdg_runtime="$(mktemp -d)"
trap 'rm -rf -- "$container_xdg_runtime"' EXIT
container_xdg_runtime="$(mktemp -d -p /var/tmp)"
trap cleanup EXIT
# Link the current wayland session to the container's xdg runtime
# Note that the session itself must be bind-mounted first
@ -37,17 +52,52 @@ fi
[ -S $host_pulse ] || die "PulseAudio UNIX socket not found"
# Default username (assume `user` always has the same uid as the host user)
run_as=user
homedir=/home/user
# Default user
run_as=$UID
if [ "$CONTAINER_RUN_AS_ROOT" = true ]; then
run_as=root
homedir=/root
run_as=0
fi
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 \
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 \
`# DNS (when containers do not have their own netns)` \
--bind-ro=/run/systemd/resolve/stub-resolv.conf:/etc/resolv.conf \
`# GPU` \
@ -57,7 +107,7 @@ SUDO_ASKPASS=$HOME/.local/bin/askpass-bemenu sudo -A systemd-nspawn -M $CONTAINE
--bind-ro=/dev/input \
--property=DeviceAllow='char-input r' \
`# Xdg runtime` \
--bind=$container_xdg_runtime:/run/xdg \
--bind=$container_xdg_runtime:/run/xdg:$bind_opts \
--setenv=XDG_RUNTIME_DIR=/run/xdg \
`# Xorg / Xwayland` \
--bind=/tmp/.X11-unix \