Bubblewrap/例

提供: ArchWiki
ナビゲーションに移動 検索に移動

dhcpcd

シンプルな dhcpcd のサンドボックスを作成:

  • 利用可能なカーネル名前空間を確認:
$ ls /proc/self/ns 
cgroup  ipc  mnt  net  pid  uts
ノート: user が存在しない場合、CONFIG_USER_NS=n でカーネルのユーザー名前空間が無効になっているか使用が制限されています。
  • ホストの / ディレクトリ全体を読み書き可能でサンドボックスの / にバインド。
  • 新しい devtmpfs ファイルシステムをサンドボックスの /dev にマウント。
  • 新しい IPC 名前空間とコントロールグループ名前空間を作成。
  • 新しい UTS 名前空間を作成して dhcpcd をホストネームとして設定。
# /usr/bin/bwrap --bind / / --dev /dev --unshare-ipc --unshare-cgroup --unshare-uts --hostname dhcpcd /usr/bin/dhcpcd -q -b

Unbound

粒度の細かい複雑な Unbound のサンドボックスを作成:

  • システムの /usr ディレクトリを読み取り専用でサンドボックスの /usr にバインド。
  • システムの /usr/lib ディレクトリからサンドボックスの /lib64 に対してシンボリックリンクを作成。
  • システムの /etc ディレクトリを読み取り専用でサンドボックスの /etc にバインド。
  • サンドボックスの中に空の /var/run ディレクトリを作成。
  • 新しい devtmpfs ファイルシステムをサンドボックスの /dev にマウント。
  • 新しい IPC 名前空間と PID 名前空間とコントロールグループ名前空間を作成。
  • 新しい UTS 名前空間を作成して unbound をホストネームとして設定。
# /usr/bin/bwrap --ro-bind /usr /usr --symlink usr/lib /lib64 --ro-bind /etc /etc --dir /var --dir /run --dev /dev --unshare-ipc --unshare-pid --unshare-cgroup --unshare-uts --hostname unbound /usr/bin/unbound -d
ヒント: unbound.service などの systemd ユニットファイルを bubblewrap する方法は systemd#ユニットファイルの編集 を見てください。

Desktop

デスクトップエントリで bubblewrap を活用:

  • ホストの / ディレクトリ全体を読み書き可能でサンドボックスの / にバインド。
  • サンドボックスの /var/etc ディレクトリを読み取り専用で再バインド
  • 新しい devtmpfs ファイルシステムをサンドボックスの /dev にマウント。
  • サンドボックスの /run ディレクトリに tmpfs ファイルシステムを作成。
  • 新しいネットワーク名前空間を作成してネットワークアクセスを無効化。
[Desktop Entry]
Name=nano Editor
Exec=bwrap --bind / / --dev /dev --tmpfs /run --unshare-net  st -e nano -o . %f
Type=Application
MimeType=text/plain;
ノート: /dev/pty に書き込むには --dev /dev が必要です。
  • mupdf.sh シェルラッパーを組み込んだ MuPDF のデスクトップエントリの例:
[Desktop Entry]
Name=MuPDF
Exec=mupdf.sh %f
Icon=application-pdf.svg
Type=Application
MimeType=application/pdf;application/x-pdf;
ノート: mupdf.sh は PATH が通った場所に配置してください。例: PATH=$PATH:$HOME/bwrap

MuPDF

この記事またはセクションの正確性には問題があります。
理由: Forwarding the X11 socket may lead to a sandbox escape (議論: トーク:Bubblewrap/例#)

bwrap の能力と柔軟性が一番良くわかるのはシェルラッパーの中に環境を作成するときです:

  • ホストの /usr/bin ディレクトリを読み取り専用でサンドボックスの /usr/bin にバインド。
  • ホストの /usr/lib ディレクトリを読み取り専用でサンドボックスの /usr/lib にバインド。
  • システムの /usr/lib ディレクトリからサンドボックスの /lib64 に対してシンボリックリンクを作成。
  • サンドボックスの /usr/lib/gcc の上に tmpfs ファイルシステムを作成。
    • 上記の設定でサンドボックスから /usr/lib/gcc の中身を効率的に遮蔽できます。
  • 新しい tmpfs ファイルシステムをサンドボックスの $HOME ディレクトリとして作成。
  • .Xauthority ファイルと Documents ディレクトリをサンドボックスに読み取り専用としてバインド。
    • 上記の設定で .Xauthority ファイルと Documents ディレクトリが再帰的にホワイトリストに追加されます。
  • 新しい tmpfs ファイルシステムをサンドボックスの /tmp ディレクトリとして作成。
  • X11 ソケットをサンドボックスに読み取り専用としてバインドしてホワイトリストに追加。
  • 実行中のカーネルによってサポートされている全ての名前空間に対してプレイベートなコンテナを複製・作成。
    • カーネルが非特権のユーザー名前空間をサポートしてなかった場合、作成がスキップされます。
  • ネットワークコンポーネントをプライベート名前空間に配置しない。
    • 上記の設定で URI ハイパーリンクを辿ってネットワークにアクセスできます。
#!/bin/sh
#~/bwrap/mupdf.sh
(exec bwrap \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib /usr/lib \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/gcc \
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Documents $HOME/Documents \
--tmpfs /tmp \
--ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
--unshare-all \
--share-net \
/usr/bin/mupdf "$@")
ヒント: 既存の実行ファイルを /usr/bin/sh に置き換えてシェルラッパーを実行することでサンドボックスの中身やファイルシステムのデバッグや確認ができます。
$ bwrap \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib /usr/lib \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/gcc \
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Desktop $HOME/Desktop \
--tmpfs /tmp \
--ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
--unshare-all \
--share-net \
/usr/bin/sh
bash-4.4$ ls -AF
.Xauthority  Documents/

bubblewrap によるファイルシステムを作成するときに一番重要なルールは実行されるコマンドの順番です。上記の MuPDF の例の場合:

  • tmpfs ファイルシステムを作成してから .Xauthority ファイルと Documents ディレクトリをバインドマウントした場合:
--tmpfs $HOME \
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--ro-bind $HOME/Documents $HOME/Documents \
bash-4.4$ ls -a
.  ..  .Xauthority  Documents
  • .Xauthority をバインドマウントしてから tmpfs ファイルシステムを作成して上書きするとサンドボックスからは Documents ディレクトリだけが見えます:
--ro-bind $HOME/.Xauthority $HOME/.Xauthority \
--tmpfs $HOME \
--ro-bind $HOME/Documents $HOME/Documents \
bash-4.4$ ls -a
.  ..  Documents

p7zip

既知の脆弱性 に対してパッチが適用されていないアプリケーションは特に bubblewrap を使用する価値があります:

  • ホストの /usr/bin/7za 実行パスを読み取り専用でサンドボックスにバインド。
  • システムの /usr/lib ディレクトリからサンドボックスの /lib64 に対してシンボリックリンクを作成。
  • tmpfs オーバーレイでサンドボックス化した /usr/lib/modules/usr/lib/systemd の中身をブラックリストに追加。
  • 新しい devtmpfs ファイルシステムをサンドボックスの /dev にマウント。
  • ホストの /sandbox ディレクトリを読み書き可能でサンドボックスの /sandbox ディレクトリにバインド。
    • シェルラッパーから呼び出すことで 7za はホストの /sandbox ディレクトリとそのサブディレクトリの中でしか実行されなくなります。
  • アプリケーションとプロセスのために新しい cgroup/IPC/ネットワーク/PID/UTS 名前空間を作成。
    • カーネルが非特権のユーザー名前空間をサポートしていなかった場合、作成はスキップされます。
    • 新しいネットワーク名前空間を作成することでサンドボックスからネットワークにアクセスできなくなります。
  • p7zip というホストネームをサンドボックスに追加。
  • XAUTHORITY 環境変数の設定を解除して X11 の接続クッキーの場所を遮蔽。
    • 7za を動作させるのに X11 ディスプレイサーバーに接続する必要はありません。
  • 新しいターミナルセッションを起動してキーボードの入力がサンドボックス外に流出することを防止。
#!/bin/sh
#~/bwrap/pz7ip.sh
(exec bwrap \
--ro-bind /usr/bin/7za /usr/bin/7za \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/modules \
--tmpfs /usr/lib/systemd \
--dev /dev \
--bind /sandbox /sandbox \
--unshare-all \
--hostname p7zip \
--unsetenv XAUTHORITY \
--new-session \
/usr/bin/7za "$@")
ノート: サンドボックスのファイルシステムを横断・確認するには実行パスに /usr/bin/sh/usr/bin/ls が必要です。
bwrap \
--ro-bind /usr/bin/7za /usr/bin/7za \
--ro-bind /usr/bin/ls /usr/bin/ls \
--ro-bind /usr/bin/sh /usr/bin/sh \
--symlink usr/lib /lib64 \
--tmpfs /usr/lib/modules \
--tmpfs /usr/lib/systemd \
--dev /dev \
--bind /sandbox /sandbox \
--unshare-all \
--hostname p7zip \
--unsetenv XAUTHORITY \
--new-session \
/usr/bin/sh
bash: no job control in this shell
bash-4.4$ ls -AF         
dev/  lib64@  usr/
bash-4.4$ ls -l /usr/lib/modules 
total 0
bash-4.4$ ls -l /usr/lib/systemd
total 0
bash-4.4$ ls -AF /dev
console  full  null  ptmx@  pts/  random  shm/  stderr@  stdin@  stdout@  tty  urandom  zero
bash-4.4$ ls -A /usr/bin
7za  ls  sh

Firefox

大規模な表面攻撃領域を持つネットワークに面したアプリケーションも、バブルラップの理想的な候補です。

  • サンドボックスに含まれる Transmission は magnet と torrent のリンクで起動します。
  • サンプルラップはオーディオ (PulseAudio) と印刷 (CUPS/Avahi) を GNOME (Wayland) 環境でサポートします。
    • ~/.config/transmission/settings.json のパスは --setenv HOME 変数を反映させる必要があります。
  • 変数展開をサポートしない環境では、キーボードバインディングを可能にするためにフルパスが使用されます。
  • Firefox#ハードウェアビデオアクセラレーション|WebRenderer]] とハードウェア (加速) コンポジットのサポートが含まれます。
 bwrap \
--symlink usr/lib /lib \
--symlink usr/lib64 /lib64 \
--symlink usr/bin /bin \
--symlink usr/bin /sbin \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/lib64 /usr/lib64 \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib/firefox /usr/lib/firefox \
--ro-bind /usr/share/applications /usr/share/applications \
--ro-bind /usr/share/gtk-3.0 /usr/share/gtk-3.0 \
--ro-bind /usr/share/fontconfig /usr/share/fontconfig \
--ro-bind /usr/share/icu /usr/share/icu \
--ro-bind /usr/share/drirc.d /usr/share/drirc.d \
--ro-bind /usr/share/fonts /usr/share/fonts \
--ro-bind /usr/share/glib-2.0 /usr/share/glib-2.0 \
--ro-bind /usr/share/glvnd /usr/share/glvnd \
--ro-bind /usr/share/icons /usr/share/icons \
--ro-bind /usr/share/libdrm /usr/share/libdrm \
--ro-bind /usr/share/mime /usr/share/mime \
--ro-bind /usr/share/X11/xkb /usr/share/X11/xkb \
--ro-bind /usr/share/icons /usr/share/icons \
--ro-bind /usr/share/mime /usr/share/mime \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--ro-bind /usr/share/ca-certificates /usr/share/ca-certificates \
--ro-bind /etc/ssl /etc/ssl \
--ro-bind /etc/ca-certificates /etc/ca-certificates \
--dir /run/user/"$(id -u)" \
--ro-bind /run/user/"$(id -u)"/pulse /run/user/"$(id -u)"/pulse \
--ro-bind /run/user/"$(id -u)"/wayland-1 /run/user/"$(id -u)"/wayland-1 \
--dev /dev \
--dev-bind /dev/dri /dev/dri \
--ro-bind /sys/dev/char /sys/dev/char \
--ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 \
--proc /proc \
--tmpfs /tmp \
--bind /home/example/.mozilla /home/example/.mozilla \
--bind /home/example/.config/transmission /home/example/.config/transmission \
--bind /home/example/Downloads /home/example/Downloads \
--setenv HOME /home/example \
--setenv GTK_THEME Adwaita:dark \
--setenv MOZ_ENABLE_WAYLAND 1 \
--setenv PATH /usr/bin \
--hostname RESTRICTED \
--unshare-all \
--share-net \
--die-with-parent \
--new-session \
/usr/bin/firefox

プライバシーの強化

  • 特定のエントリを削除することで、さらに制限をかけることができます。
    • 以下の項目を削除すると、オーディオのサポートが解除されます。
--ro-bind /run/user/"$(id -u)"/pulse /run/user/"$(id -u)"/pulse \
  • /sandbox は、任意のプロファイル情報を保持するためにユーザが定義した任意の場所を表します。
$ cp -pR ~/.mozilla /sandbox/

場所は、ネットワーク共有、USB マウント、ローカルファイルシステム、または ramfs/tmpfs の場所 のいずれかです。

  • 実際の/home/example を見えなくするために /home/r を設定します。
  • 新しいユーザ ID、グループ ID を設定する
ノート: 選択した UID と GID が /etc/passwd/etc/groups にリストされている既存の値と競合しないことを確認してください。 /etc/groups に記載されている既存の値と矛盾しないようにします。
bwrap \
....
--bind /sandbox/.mozilla /home/r/.mozilla \
--bind /sandbox/Downloads /home/r/Downloads \
...
--setenv HOME /home/r \
...
--uid 200 --gid 400 \
...
/usr/bin/firefox --no-remote --private-window

Chromium

wayland と pipewire を使ったシンプルな chromium サンドボックスです。

bwrap \
    --symlink usr/lib /lib \
    --symlink usr/lib64 /lib64 \
    --symlink usr/bin /bin \
    --symlink usr/bin /sbin \
    --ro-bind /usr/lib /usr/lib \
    --ro-bind /usr/lib64 /usr/lib64 \
    --ro-bind /usr/bin /usr/bin \
    --ro-bind /etc /etc \
    --ro-bind /usr/lib/chromium /usr/lib/chromium \
    --ro-bind /usr/share /usr/share \
    --dev /dev \
    --dev-bind /dev/dri /dev/dri \
    --proc /proc \
    --ro-bind /sys/dev/char /sys/dev/char \
    --ro-bind /sys/devices /sys/devices \
    --ro-bind /run/dbus /run/dbus \
    --dir "$XDG_RUNTIME_DIR" \
    --ro-bind "$XDG_RUNTIME_DIR/wayland-1" "$XDG_RUNTIME_DIR/wayland-1" \
    --ro-bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0" \
    --ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
    --tmpfs /tmp \
    --dir $HOME/.cache \
    --bind $HOME/.config/chromium $HOME/.config/chromium \
    --bind $HOME/Downloads $HOME/Downloads \
    /usr/bin/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland
警告: linux-hardened カーネルを使用している場合、 kernel.unprivileged_userns_clone が 0 に設定されているため、クロムのサンドボックス化に bubblewrap を使用することはできません。sysctl が 0 に設定されているためです。これを 1 に設定することはできますが、これは推奨されません FS#36969

もう一つの解決策は、chromium が bubblewrap によって作成された名前空間を使用することです。これは zypakAUR によって実現できます。これは flatpak によっても使用され、追加の名前空間の中で electron ベースのアプリを実行します。chromium/electron で zypak を使用する方法を示すサンプルコードがあります こちら

  • PipeWire です。--ro-bind "/run/user/$(id -u)/pipewire-0" "/run/user/$(id -u)/pipewire-0" \.
    • PipeWire を使用しない場合、この行は削除してかまいません。
  • --bind $HOME/.config/chromium $HOME/.config/chromium \ は、サンドボックス内のクロム設定ディレクトリを読み書き可能な状態にマウントします。
  • --bind $HOME/Downloads $HOME/Downloads \ は、サンドボックス内の ~/Downloads ディレクトリを読み書き可能な状態でマウントします。
  • この例はさらに改良して、より分離しやすくすることができます。

Skype for Linux

この記事またはセクションの正確性には問題があります。
理由: Forwarding the X11 and/or DBus sockets may lead to a sandbox escape (議論: トーク:Bubblewrap/例#)

skypeforlinux-stable-binAUR /usr/bin/skypeforlinux の代わりに /usr/share/skypeforlinux/skypeforlinux で開始する必要があります。これは、後者がメイン プロセスをバックグラウンドでフォークし、--die-with-parent bwrap オプションと競合します。 次の例は、以下の機能を提供します。

  • 環境変数が全てアンセットされていることを確認します。
  • ネットワークはホストと共有 (--share-net), /etc/resolv.conf は bind-mounted です.
  • Xorg アクセス: /tmp/.X11-unix/X0 ソケットをバインドし、$DISPLAY を設定します。
  • D-Bus: /run/user/$UID/bus ソケットを結び、$DBUS_SESSION_BUS_ADDRESS を設定します。
  • Audio: PulseAudio ソケットをバインドしてください。
  • Video: デバイス /dev/video0 をディバインドします。

Skype プロファイルを保持するホスト上のディレクトリは、$HOST_PROFILE_PATH で構成できます。

env -i bwrap \
    --ro-bind /usr /usr \
    --dir /home/r \
    --dir /tmp \
    --dir /var \
    --dir /run/user/$UID \
    --proc /proc \
    --dev /dev \
    --symlink usr/lib /lib \
    --symlink usr/lib64 /lib64 \
    --symlink usr/bin /bin \
    --symlink usr/sbin /sbin \
    --symlink ../tmp /var/tmp \
    --bind "$HOST_PROFILE_PATH" /home/r/.config/skypeforlinux \
    --ro-bind /etc/resolv.conf /etc/resolv.conf \
    --ro-bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 \
    --ro-bind /run/user/$UID/bus /run/user/$UID/bus \
    --ro-bind /run/user/$UID/pulse /run/user/$UID/pulse \
    --dev-bind /dev/video0 /dev/video0 \
    --chdir / \
    --unshare-all \
    --share-net \
    --hostname RESTRICTED \
    --die-with-parent \
    --new-session \
    --setenv PATH /usr/bin \
    --setenv HOME /home/r \
    --setenv XDG_RUNTIME_DIR "/run/user/$UID" \
    --setenv DISPLAY "$DISPLAY" \
    --setenv DBUS_SESSION_BUS_ADDRESS "unix:path=/run/user/$UID/bus" \
    /usr/share/skypeforlinux/skypeforlinux

Steam

この記事またはセクションの正確性には問題があります。
理由: Forwarding the X11 and/or DBus sockets may lead to a sandbox escape (議論: トーク:Bubblewrap/例#)

シンプルな Steam サンドボックス

#!/usr/bin/bash
set -e

STEAM_HOME="$HOME/.local/share/steam_sandbox"
RUN_USER="/run/user/$UID"

mkdir -p "$STEAM_HOME"

_bind() {
	_bind_arg=$1
	shift
	for _path in "$@"; do
		args+=("$_bind_arg" "$_path" "$_path")
	done
}

bind() {
	_bind --bind-try "$@"
}

robind() {
	_bind --ro-bind-try "$@"
}

devbind() {
	_bind --dev-bind-try "$@"
}

args=(
	--tmpfs /tmp
	--proc /proc
	--dev /dev
	--dir /etc
	--dir /var
	--dir "$RUN_USER"
	--bind "$STEAM_HOME" "$HOME"
	--dir "$HOME"
	--dir "$XDG_CONFIG_HOME"
	--dir "$XDG_CACHE_HOME"
	--dir "$XDG_DATA_HOME"
	--dir "$XDG_STATE_HOME"
	--symlink /usr/lib /lib
	--symlink /usr/lib /lib64
	--symlink /usr/bin /bin
	--symlink /usr/bin /sbin
	--symlink /run /var/run
)

robind \
	/usr \
	/etc \
	/opt \
	/sys \
	/var/empty \
	/var/lib/alsa \
	/var/lib/dbus \
	"$RUN_USER/systemd/resolve"

devbind \
	/dev/dri \
	/dev/nvidia* \

# steam
bind \
	"$HOME/.Xauthority" \
	"$HOME/.local/bin/proton" \
	"$HOME/.pki" \
	"$HOME/.steam" \
	"$HOME/.steampath" \
	"$HOME/.steampid" \
	"$HOME/Downloads" \
	"$RUN_USER"/.mutter-X* \
	"$RUN_USER"/ICE* \
	"$RUN_USER"/dbus* \
	"$RUN_USER"/gnome* \
	"$RUN_USER"/pipewire* \
	"$RUN_USER"/pulse* \
	"$RUN_USER"/wayland* \
	"$RUN_USER/at-spi" \
	"$RUN_USER/bus" \
	"$RUN_USER/dconf" \
	"$RUN_USER/systemd" \
	"$XDG_CACHE_HOME/mesa_shader_cache" \
	"$XDG_CACHE_HOME/nv" \
	"$XDG_CACHE_HOME/nvidia" \
	"$XDG_CACHE_HOME/radv_builtin_shaders64" \
	"$XDG_CONFIG_HOME/Epic" \
	"$XDG_CONFIG_HOME/Loop_Hero" \
	"$XDG_CONFIG_HOME/MangoHud" \
	"$XDG_CONFIG_HOME/ModTheSpire" \
	"$XDG_CONFIG_HOME/RogueLegacy" \
	"$XDG_CONFIG_HOME/RogueLegacyStorageContainer" \
	"$XDG_CONFIG_HOME/cef_user_data" \
	"$XDG_CONFIG_HOME/proton" \
	"$XDG_CONFIG_HOME/pulse" \
	"$XDG_CONFIG_HOME/unity3d" \
	"$XDG_DATA_HOME/3909/PapersPlease" \
	"$XDG_DATA_HOME/Colossal Order" \
	"$XDG_DATA_HOME/Dredmor" \
	"$XDG_DATA_HOME/FasterThanLight" \
	"$XDG_DATA_HOME/HotlineMiami" \
	"$XDG_DATA_HOME/IntoTheBreach" \
	"$XDG_DATA_HOME/Paradox Interactive" \
	"$XDG_DATA_HOME/PillarsOfEternity" \
	"$XDG_DATA_HOME/RogueLegacy" \
	"$XDG_DATA_HOME/RogueLegacyStorageContainer" \
	"$XDG_DATA_HOME/Steam" \
	"$XDG_DATA_HOME/SuperHexagon" \
	"$XDG_DATA_HOME/Terraria" \
	"$XDG_DATA_HOME/applications" \
	"$XDG_DATA_HOME/aspyr-media" \
	"$XDG_DATA_HOME/bohemiainteractive" \
	"$XDG_DATA_HOME/cdprojektred" \
	"$XDG_DATA_HOME/feral-interactive" \
	"$XDG_DATA_HOME/frictionalgames" \
	"$XDG_DATA_HOME/icons" \
	"$XDG_DATA_HOME/proton" \
	"$XDG_DATA_HOME/vpltd" \
	"$XDG_DATA_HOME/vulkan" \
	"/var/lib/bluetooth" \
	/run/systemd \
	/tmp/.ICE-unix \
	/tmp/.X11-unix 

exec bwrap "${args[@]}" /usr/lib/steam/steam "$@"

ファイルシステムの分離

警告: bubblewrap のユーザーはファイルシステムツリーを定期的に更新しなければなりません。

(/var, /usr/bin, /usr/lib の中身など) ファイルシステムの中身を遮蔽しながらソフトウェアのインストールをサンドボックス化したい場合、pacman で Arch のパッケージを分離したファイルシステムツリーにインストールすることができます。

pacman を使ってソフトウェアをファイルシステムツリーにインストールするには、fakerootfakechroot のインストールが必要です。

例として pacman で xterm パッケージを隔離ファイルシステムツリーにインストールしたいとすると、ツリーを以下のように準備します:

$ MYPACKAGE=xterm
$ mkdir -p ~/sandboxes/${MYPACKAGE}/files/var/lib/pacman
$ mkdir -p ~/sandboxes/${MYPACKAGE}/files/etc
$ cp /etc/pacman.conf ~/sandboxes/${MYPACKAGE}/files/etc/pacman.conf

~/sandboxes/${MYPACKAGE}/files/etc/pacman.conf を編集して使用する pacman の設定を調整すると良いでしょう:

  • 不必要なカスタムリポジトリやホスト環境でしか必要ない IgnorePkg, IgnoreGroup, NoUpgrade, NoExtract の設定を削除。
  • CheckSpace オプションを削除して pacman がディスク容量をチェックするために root ファイルシステムを検索するときのエラーを消す。

base グループと必須の fakeroot を分離ファイルシステムツリーにインストール:

$ fakechroot fakeroot pacman -Syu \
    --root ~/sandboxes/${MYPACKAGE}/files \
    --dbpath ~/sandboxes/${MYPACKAGE}/files/var/lib/pacman \
    --config ~/sandboxes/${MYPACKAGE}/files/etc/pacman.conf \
    base fakeroot

同じオプションを使って bubblewrap を何度も呼び出すことになるので、以下のようにエイリアスを作成:

$ alias bw-install='bwrap                        \
     --bind ~/sandboxes/${MYPACKAGE}/files/ /    \
     --ro-bind /etc/resolv.conf /etc/resolv.conf \
     --tmpfs /tmp                                \
     --proc /proc                                \
     --dev /dev                                  \
     --chdir /                                   '

ロケール を設定してください:

$ nano -w ~/sandboxes/${MYPACKAGE}/files/etc/locale.gen
$ bw-install locale-gen

pacman のキーリングを設定:

$ bw-install fakeroot pacman-key --init
$ bw-install fakeroot pacman-key --populate archlinux

以下のように xterm パッケージをインストール:

$ bw-install fakeroot pacman -S ${MYPACKAGE}

pacman コマンドが失敗する場合、キーリングを生成するコマンドをもう一度実行してみてください。

これで xterm を含む分離ファイルシステムツリーが作られました。bw-install を使ってファイルシステムツリーをアップグレードすることができます。

bubblewrap でソフトウェアを実行することができます (上記の例では commandxterm になります):

$ bwrap                                          \
     --ro-bind ~/sandboxes/${MYPACKAGE}/files/ / \
     --ro-bind /etc/resolv.conf /etc/resolv.conf \
     --tmpfs /tmp                                \
     --proc /proc                                \
     --dev /dev                                  \
     --chdir /                                   \
     command

一部のファイルをパッケージ間で共有することもできます。既存のファイルシステムツリーのファイルのハードリンクを作成して新しいツリーで再利用することが可能です:

$ cp -al ~/sandboxes/${MYPARENTPACKAGE} ~/sandboxes/${MYPACKAGE}

bw-install fakechroot fakeroot pacman ... から pacman を呼び出して通常通りにインストールを行ってください。