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 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
1 changed files with 61 additions and 11 deletions

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
[ -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
if [ -f "$config" ]; then
@ -15,8 +30,8 @@ if [ -f "$config" ]; then
# 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)
# Default user
if [ "$CONTAINER_RUN_AS_ROOT" = true ]; then
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 \
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)"
# Userns-related config
# Default to identity mapping, which does not provide uid isolation but does for capabilities
if [ "$CONTAINER_USE_USERNS" = true ]; then
private_users=$(shuf -i 65536-$((2147483647 - 65536)) -n1) # Pick a random starting offset
user_on_host=$((private_users + run_as))
# 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
# 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"
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 \