#!/bin/sh # 2018DECTMP # Максимально близкий chroot. Т. е. chroot'имся так, чтобы расшарить с хостом максимальное число ресурсов, в отличие от systemd-nspawn, который, наоборот, стремится к максимальной изоляции. Цель в том, чтобы как можно больше вещей в chroot'е работало, например, X-клиенты. Вместе с тем любое добавление нужно вносить в скрипт только если оно требуется для какого-то из приложений, например, для запуска X-клиентов. Т. е. максимально близкий настолько, насколько это нужно, чтобы всё работало, но не ближе # Любое действие делаем так, чтобы охватить как можно больше применений. Например, работоспособность X-клиентов, вероятно, можно было обеспечить копированием x authority в chroot. Но мы вместо этого делаем bind mount /tmp, т. к., возможно, это приведёт к тому, что заработает что-то ещё # Делаем unshare, чтобы удаление каталога снаружи не привело к удалению чего либо, кроме самого каталога # Информация: "sudo aplay" в X работает, т. к. sudo пробрасывает DISPLAY и XAUTHORITY # Мы по максимуму избегаем bind-монтирования /dev, чтобы chroot не получил доступ к блочным устройствам set -e [ $# -lt 2 ] && echo "Usage: ${0##*/} [--no-chroot] DIR EXEC-CMD..." >&2 && exit 1 # Для отладки if [ "$1" = "--no-chroot" ]; then SHOULD_CHROOT=false shift else SHOULD_CHROOT=true fi DIR="$1" shift exec unshare --mount sh -c ' set -e SHOULD_CHROOT="$1" shift DIR="$1" shift mount --bind "$DIR" "$DIR" # Чтобы работал opam, он использует bwrap mkdir -p "$DIR/proc" umount -R "$DIR/proc" 2> /dev/null || : mount --bind /proc "$DIR/proc" # Чтобы можно было получить доступ к файлам хоста с помощью /proc/1/root mkdir -p "$DIR/tmp" umount -R "$DIR/tmp" 2> /dev/null || : mount --bind /tmp "$DIR/tmp" # Т. к. /tmp содержит XAUTHORITY mkdir -p "$DIR/run" umount -R "$DIR/run" 2> /dev/null || : mount --rbind /run "$DIR/run" # Нужен для pulseaudio. Нужен именно rbind. Этот фрагмент добавлен при тестировании на X-сервере mkdir -p "$DIR/etc" : >> "$DIR/etc/machine-id" umount "$DIR/etc/machine-id" 2> /dev/null || : mount --bind /etc/machine-id "$DIR/etc/machine-id" # Нужен для pulseaudio. Этот фрагмент добавлен при тестировании на X-сервере mkdir -p "$DIR/dev/pts" umount -R "$DIR/dev/pts" 2> /dev/null || : mount --bind /dev/pts "$DIR/dev/pts" # Нужен для xterm mkdir -p "$DIR/dev/dri" umount -R "$DIR/dev/dri" 2> /dev/null || : mount --bind /dev/dri "$DIR/dev/dri" # Нужен для "ffmpeg -f kmsgrab". Этот фрагмент добавлен при тестировании на X-сервере mkdir -p "$DIR/dev/shm" umount -R "$DIR/dev/shm" 2> /dev/null || : mount -t tmpfs tmpfs "$DIR/dev/shm" # Нужен, чтобы запустить Chromium от юзера. Этот фрагмент добавлен при тестировании на X-сервере mkdir -p "$DIR/etc" if [ -f /etc/resolv.conf ]; then # Если нет интернета, то файл может не резолвиться rm -f "$DIR/etc/resolv.conf" cp --dereference /etc/resolv.conf "$DIR/etc" fi if $SHOULD_CHROOT; then exec chroot "$DIR" "$@" else exec "$@" fi ' dummy-argv0 "$SHOULD_CHROOT" "$DIR" "$@"