Skip to content

Instantly share code, notes, and snippets.

@Daniel-Abrecht
Last active February 3, 2024 17:30
Show Gist options
  • Save Daniel-Abrecht/5cd05da1525abf80ea8e63d63a5fdf82 to your computer and use it in GitHub Desktop.
Save Daniel-Abrecht/5cd05da1525abf80ea8e63d63a5fdf82 to your computer and use it in GitHub Desktop.
A simple jail using unprivileged userspace namespaces
#!/bin/sh
set -e
PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin"
self="$(realpath "$0")"
rodirs="
bin
sbin
lib
lib64
usr
etc
$rodirs"
rwdirs="
var/lock
$rwdirs"
if [ -d "$HOME/bin" ]
then
PATH="$PATH:$HOME/bin"
rodirs="$rodirs
$HOME/bin"
fi
if [ -d "$HOME/.cache" ]
then
rwdirs="$rwdirs
$HOME/.cache"
fi
if ! [ -x "$1" ]
then
echo "Usage: $(basename "$0") program [args]" >&2
exit 1
fi
case "$__inside__" in
"")
export __inside__=1
export tmp="$(mktemp -d)"
( sleep 5; rmdir "$tmp"; ) &
exec unshare --kill-child -mripf "$self" "$@"
;;
1)
export __inside__=2
export mypwd="${PWD#/}"
mount -t tmpfs -o rprivate jail "$tmp"
cd "$tmp"
mkdir proc run tmp sys dev
mount -o noexec,nodev,nosuid -t proc proc proc
mount -t tmpfs tmpfs run
mount -t tmpfs tmpfs tmp
mount -o rbind,rprivate /sys sys
mount -o rbind,rprivate /dev dev
if [ -n "$mypwd" ]
then
mkdir -p "$mypwd"
mount -o rbind "/$mypwd" "$mypwd"
fi
IFS="
"
for dir in $rodirs
do
dir="${dir#/}"
[ -d "/$dir" ] || continue
mkdir -p "$dir"
mount -o rbind,rprivate,ro "/$dir" "$dir"
done
for dir in $rwdirs
do
dir="${dir#/}"
if [ -d "/$dir" ]
then
mkdir -p "$dir"
mount -o rbind,rprivate,rw "/$dir" "$dir" || true
fi
done
# " \t\n", no nice way to escape it in posix sh
IFS="
"
mkdir .root
mount -o rbind .root .root
pivot_root . .root
exec chroot . "$self" "$@"
;;
2)
export __inside__=3
read _ uid _ </proc/self/uid_map
read _ gid _ </proc/self/gid_map
umount -lr /.root
umount /.root
rmdir /.root
chmod 555 /
mount -o remount,ro / /
exec unshare --map-user="$uid" --map-group="$gid" "$self" "$@"
;;
3)
unset tmp
cd "$mypwd"
unset mypwd
unset __inside__
exec "$@"
;;
esac
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment