Bubblewrap/示例 - Arch Linux 中文维基

跳至內容

# Bubblewrap/示例

出自 Arch Linux 中文维基
< Bubblewrap
翻譯狀態：

- 本文（或部分內容）譯自 Bubblewrap/Examples，最近一次同步於 2026-03-10，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

## dhcpcd

創建一個簡單的 dhcpcd 沙箱：

- 確定可用的內核命名空間（kernel namespaces）：

    $ ls /proc/self/ns
    cgroup  ipc  mnt  net  pid  uts

注意：缺少 `user` 意味著內核以 `CONFIG_USER_NS=n` 參數構建或是被限制了用戶命名空間（user namespace）。

- 將宿主的整個 `/` 目錄以讀寫模式綁定到沙箱中的 `/`。
- 將一個新的 devtmpfs 文件系統掛載到沙箱中的 `/dev`。
- 創建一個新的 IPC（進程間通信）和 cgroups（控制組) 命名空間。
- 創建一個新的 UTS 命名空間並將 `dhcpcd` 設置為主機名（hostname）。

    # /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（進程標識符）以及控制組命名空間（control group namespaces）。
- 創建一個新的 UTS 命名空間並將 `unbound` 設置為主機名（hostname）。

    # /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

提示：參見 systemd#修改現存單元文件以了解如何啟用 systemd 單元文件的 bubblewrapping，包括 `unbound.service`。

## MuPDF

本文或本章節的事實準確性存在爭議。

原因： 轉發 X11 socket 可能導致沙箱逃逸。（在 Talk:Bubblewrap/示例 中討論）

在 shell 包裝器（wrapper）中創建環境時，能體現出 bwrap 的強大和靈活性：

- 將宿主系統的 `/usr/bin` 目錄以只讀模式綁定到沙箱中的 `/usr/bin`。
- 將宿主系統的 `/usr/lib` 目錄以只讀模式綁定到沙箱中的 `/usr/lib`。
- 將宿主系統的 `/usr/lib` 目錄軟連結到沙箱中的 `/lib64`。
- 在沙箱中創建一個 tmpfs 文件系統，覆蓋 `/usr/lib/gcc`。
  - 這麼做可以有效地阻止 `/usr/lib/gcc` 中的內容出現在沙箱中。
- 在沙箱中創建一個新的 tmpfs 文件系統，作為 `$HOME` 目錄。
- 將 `.Xauthority` 文件和「Documents」目錄以只讀模式綁定到沙箱。
  - 這麼做可以有效且遞歸地允許訪問 `.Xauthority` 文件和「Documents」目錄。
- 在沙箱中創建一個新的 tmpfs 文件系統，作為 `/tmp` 目錄。
- 將 X11 socket 以只讀模式綁定到沙箱中以允許訪問。
- 複製並創建用於容納宿主內核所支持的所有命名空間的私有容器（private containers）。
  - 如果內核不支持非特權的（non-privileged）用戶命名空間，跳過創建過程並繼續操作。
- 勿將網絡組件放置到私有命名空間內。
  - 這麼做可以允許聯網訪問 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  Desktop

- 如果在綁定掛載 `.Xauthority` 後再創建 tmpfs 文件系統，結果將覆蓋先前文件，因此沙箱中只能夠找到「Documents」這個目錄：

    --ro-bind $HOME/.Xauthority $HOME/.Xauthority \
    --tmpfs $HOME \
    --ro-bind $HOME/Desktop $HOME/Desktop \

    bash-4.4$ ls -a
    .  ..  Desktop

## p7zip

還未對已知漏洞進行修補的應用程式是 bubblewrap 的主要候選對象：

- 將宿主系統中的 `/usr/bin/7za` 可執行文件路徑以只讀模式綁定到沙箱中。
- 將宿主系統的 `/usr/lib` 目錄軟連結到沙箱中的 `/lib64`。
- 用 tmpfs 文件系統覆蓋以禁用沙箱中 `/usr/lib/modules` 和 `/usr/lib/systemd` 的內容。
- 將一個新的 devtmpfs 文件系統掛載到沙箱中的 `/dev`。
- 將宿主系統的 `/sandbox` 目錄以讀寫模式綁定到沙箱中的 `/sandbox`。
  - 7za 僅會在宿主的 `/sandbox` 目錄中運行，或在被 shell 包裝器調用時，在其子文件夾中運行。
- 為應用程式及其進程創建新的 cgroup、IPC、network、PID 和 UTS 命名空間。
  - 如果內核不支持非特權的用戶命名空間，跳過創建過程並繼續操作。
  - 新創建的 network 命名空間將阻止沙箱獲取網絡訪問權限。
- 為沙箱設置計算機名，例如 `p7zip`。
- 取消設置 `XAUTHORITY` 環境變量以隱藏 X11 conection cookie 的位置。
  - 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

面向網絡且擁有巨大的潛在被攻擊面的應用程式同樣是 bubblewrap 的理想候選對象：

- 將 Transmission 包含在沙箱中以響應磁力連結和種子連結並啟動。
- 示例的 wrap 在GNOME（Wayland）下支持音頻（PulseAudio）和列印服務（CUPS/Avahi）。
  - `~/.config/transmission/settings.json` 中的 PATH 應反映 `--setenv HOME` 變量。
- 環境中的按鍵綁定不支持變量擴展，因此使用了完整路徑。
- 同時還支持 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 "$XDG_RUNTIME_DIR" \
    --ro-bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \
    --ro-bind "$XDG_RUNTIME_DIR/wayland-1" "$XDG_RUNTIME_DIR/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 "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse" \

- `/sandbox` 作為用戶所定義的目錄，並沒有特殊含義，僅用於存放所需的個人資料信息。
  - 可通過腳本或定時任務，也可手動將清理過的配置文件複製到 `/sandbox`。

    $ cp -pR ~/.mozilla /sandbox/

文件位置可以來自網絡共享、USB 掛載設備，或是來自本地文件系統，甚至是 ramfs 或 tmpfs。

- 設置 `/home/r` 以隱藏真實的 `/home/example`。
- 設置新的用戶標識符和組標識符。

注意：確保新的用戶標識符（UID）和組標識符（GID）不會與 `/etc/passwd` 和 `/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 下運行 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` sysctl 已被設置為 0，會無法實現沙箱運行 chromium。用戶可以自行設置為 1，但不建議這麼做（FS#36969）。

一種解決方法是讓 chromium 使用 bubblewrap 創建的命名空間。可以用 zypakAUR 實現，這個方法同樣被 flatpak 用於在一個額外命名空間中運行基於 electron 的應用程式。這個連結是有關如何使用 zypak 運行 chromium/electron 的示例代碼。

- PipeWire：`--ro-bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0" \`
  - 不使用 pipewire 的用戶可移除此行內容。
- `--bind $HOME/.config/chromium $HOME/.config/chromium \` 將用戶的 chromium 配置目錄以讀寫模式掛載到沙箱中。
- `--bind $HOME/Downloads $HOME/Downloads \` 將用戶的「~/Downloads」目錄以讀寫模式掛載到沙箱中。
- 通過增加更多隔離處理可優化本例。

## Steam

本文或本章節的事實準確性存在爭議。

原因： 轉發 X11 可能導致沙箱逃逸。（在 Talk:Bubblewrap/示例 中討論）

Steam 正常運行時需要訪問 D-Bus。

下面的示例使用 `xdg-dbus-proxy` 將有限的宿主系統 bus 訪問權限暴露給沙箱。一旦 bwrap 退出，此 proxy 將被一同終止。

    steam.py

    #!/usr/bin/env python3
    from glob import glob
    import os
    from pathlib import Path
    import subprocess

    HOME = Path.home()
    XDG_RUNTIME_DIR = Path(os.getenv("XDG_RUNTIME_DIR", "/tmp"))
    XDG_CACHE_HOME = Path(os.getenv("XDG_CACHE_HOME", HOME / ".cache"))
    XDG_DATA_HOME = Path(os.getenv("XDG_DATA_HOME", HOME / ".local/share"))
    DBUS_PROXY_PATH = XDG_RUNTIME_DIR / "bus-proxy"
    DBUS_PROXY_PATH.mkdir(exist_ok=True, parents=True)

    #
    STEAM_HOME = XDG_DATA_HOME / "steam_home"
    STEAM_HOME.mkdir(exist_ok=True, parents=True)

    # xdg-dbus-proxy
    r, w = os.pipe()
    session_bus_proxy = DBUS_PROXY_PATH / str(os.getpid())
    system_bus_proxy = DBUS_PROXY_PATH / f"{os.getpid()}-system"
    subprocess.Popen([
        "/usr/bin/xdg-dbus-proxy",
        f"--fd={w}",
        # session bus
        os.environ["DBUS_SESSION_BUS_ADDRESS"],
        str(session_bus_proxy),
        "--filter",
        "--own=com.steampowered.*",
        "--talk=org.freedesktop.portal.*",
        "--talk=org.gnome.SettingsDaemon.MediaKeys",
        "--talk=org.kde.StatusNotifierWatcher",
        "--talk=org.freedesktop.ScreenSaver",
        "--talk=org.freedesktop.PowerManagement",
        "--talk=org.freedesktop.Notifications",
        # systrem bus
        "unix:path=/run/dbus/system_bus_socket",
        str(system_bus_proxy),
        "--filter",
        "--talk=org.freedesktop.UPower",
        "--talk=org.freedesktop.UDisks2",  # used by wine
    ], pass_fds=[w])
    # wait xdg-dbus-proxy to start
    os.read(r, 1)
    os.set_inheritable(r, True)

    # bwrap
    argv: list[str] = [
        "bwrap",
        "--bind", str(STEAM_HOME), str(HOME),
        "--proc", "/proc",
        "--dev", "/dev",
        "--dir", "/tmp",
        "--unshare-cgroup-try",
        "--unshare-pid",
        "--unshare-user-try",
        "--unshare-uts",
        "--die-with-parent",
        "--sync-fd", str(r), # ensures dbus proxy stops when the bwrap bwrap quits
        "--bind", str(system_bus_proxy), "/run/dbus/system_bus_socket",
        "--bind", str(session_bus_proxy), str(XDG_RUNTIME_DIR / "bus"),
    ]
    def rw(*paths): argv.extend([i for path in paths for i in ("--bind-try", str(path), str(path))])
    def ro(*paths): argv.extend([i for path in paths for i in ("--ro-bind-try", str(path), str(path))])
    def dev(*paths): argv.extend([i for path in paths for i in ("--dev-bind-try", str(path), str(path))])
    def link(*links): argv.extend([i for link in links for i in ("--symlink", str(link[0]), str(link[1]))])

    rw(
        "/usr",
        "/etc",
        "/opt",
        "/run/systemd/resolve/",
        # WARNING: Forwarding the X11 is insecure and might lead to sandbox escapes
        "/tmp/.X11-unix",
        "/tmp/.ICE-unix",
        *glob(str(XDG_RUNTIME_DIR / "wayland*")),
        # audio
        "/var/lib/alsa/",
        *glob(str(XDG_RUNTIME_DIR / "pulse*")),
        *glob(str(XDG_RUNTIME_DIR / "pipewire*")),
        # shader cache
        XDG_CACHE_HOME / "mesa_shader_cache",
        XDG_CACHE_HOME / "mesa_shader_cache_db",
        XDG_CACHE_HOME / "nv",
        XDG_CACHE_HOME / "nvidia",
        XDG_CACHE_HOME / "radv_builtin_shaders",
        XDG_CACHE_HOME / "radv_builtin_shaders64",
        # steam
        XDG_DATA_HOME / "Steam",
    )
    link(
        ("/usr/bin", "/bin"),
        ("/usr/bin", "/sbin"),
        ("/usr/lib", "/lib"),
        ("/usr/lib64", "/lib64"),
        ("/run", "/var/run"),
    )
    dev(
        "/dev/dri",
        "/dev/input",
        "/dev/hugepages",
        *glob("/dev/nvidia*"),
        "/dev/snd",
        "/dev/fuse",
        "/sys/block/",
        "/sys/bus/",
        "/sys/class/",
        "/sys/dev/",
        "/sys/devices/",
        "/sys/module/",
    )
    os.execvp("bwrap", argv + ["--sync-fd", str(r), "/usr/lib/steam/steam"])

- 本例中將 `$XDG_DATA_HOME/steam_home` 掛載為 `$HOME`。用戶可以自行將 `STEAM_HOME` 修改為其他位置。
- Use the `rw()` or `ro()` functions to grant read/write or read-only access, respectively, to a host path. For example, `rw("HOME/.config/unity3d")`.
- 使用 `rw()` 或 `ro()` 以授予宿主 path 的讀寫或只讀權限。例如 `rw("HOME/.config/unity3d")`。

## NPM, Node Version Manager (NVM), Maven Java

為能在項目的工作目錄中使用 bubblewrap 運行「npm」，可以參考下面的命令示例。

Bubblewrap 能夠與 Angular、Cypress 和 Maven Java 共同使用並工作良好。X11 和 Wayland 需要被包含在最開始，因為 Cypress 會啟動一個基於 Electron 的圖形界面。

假設用戶在項目工作目錄下執行 `npm install`，同時「npm」需要讀寫 `node_modules`、`package.json` 等文件，這種方式允許在程序啟動目錄中擁有完整的文件訪問權限。同時「npm」和「nvm」（`npm -g install ...`）也可以訪問的全局安裝目錄。此外 Cypress 也可以運行在 X11 或 Wayland 下。

注意：綁定到 zsh、maven 和其他的目錄可能與實際情況有所不同。

    bwrap_arguments=(
        # 避免成為殭屍進程
        --die-with-parent

        # 依賴項需要網絡訪問
        --unshare-all
        --share-net

        # 創建正確的運行環境
        --tmpfs /
        --tmpfs /run
        --dir /tmp
        --dev /dev
        --proc /proc
        --ro-bind /bin /bin
        --ro-bind /sbin /sbin
        --ro-bind /usr /usr
        --ro-bind /etc /etc
        --ro-bind /lib /lib
        --ro-bind /lib64 /lib64
        --ro-bind /sys /sys
        --ro-bind /var /var

        # systemd-resolve for dns
        --ro-bind /run/systemd/resolve /run/systemd/resolve

        # npm 初始化倉庫時會使用 git，確保已配置好 email 和 username 項
        --ro-bind $XDG_CONFIG_HOME/git/config $XDG_CONFIG_HOME/git/config

        # zsh has to look everywhere cool
        --ro-bind $XDG_CONFIG_HOME/zsh/.zshrc $XDG_CONFIG_HOME/zsh/.zshrc
        --ro-bind $XDG_CONFIG_HOME/zsh/.zshenv $XDG_CONFIG_HOME/zsh/.zshenv
        --ro-bind $HOME/.zshenv $HOME/.zshenv

        # Maven
        --ro-bind /opt/maven /opt/maven
        --ro-bind $HOME/.m2 $HOME/.m2

        # NPM
        --bind "$XDG_DATA_HOME/npm" "$XDG_DATA_HOME/npm"

        # npm、cypress、nvm、maven 等程序需要使用 cache
        --bind "$XDG_CACHE_HOME" "$XDG_CACHE_HOME"

        # x11, needed for cypress
        --ro-bind "$XAUTHORITY" "$XAUTHORITY"

        # wayland, might be useful
        --ro-bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"

        # 假定運行時所在的目錄是項目工作目錄，並且擁有完全的訪問權限
        --bind "$(pwd)" "$(pwd)"
    )

    # 以上方指定的參數運行 bwrap 處理的用戶命令：
    $ bwrap "${bwrap_arguments[@]}" "$@"

分類：​

- 沙箱
- 內核

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

Bubblewrap/示例
新增話題