Bubblewrap
![]() 对于为什么要进行某些操作,推理很可能是不正确的。需要更有经验的人来检查一下。 |
Bubblewrap 是一个非特权沙箱工具。内核特性也包括:用户/IPC/PID/网络/UTS/cgroup 命名空间 和 Seccomp 过滤器。
Bubblewrap 的工作原理,如 README.md 中所述
- bubblewrap 的工作原理是创建一个新的、完全空的挂载命名空间,其中根目录位于 tmpfs 上,该 tmpfs 对主机不可见,并且将在最后一个进程退出时自动清理。然后,您可以使用命令行选项来构建根文件系统和进程环境,以及在命名空间中运行的命令。
安装
安装 bubblewrap
# apk add bubblewrap
bwrap
。如何确定程序需要什么
bwrap
的各种使用方法。前提条件
首先确保在 "$PATH" 中有一个用户可编辑的目录。此页面将使用 "${HOME}/.local/bin/",如果它不存在,则创建它
$ mkdir -p ~/.local/bin
将其添加到 ~/.profile
内容为 ~/.profile
需要重新登录才能应用。
基础 bwrap 设置
nobody
。假设您要沙箱化 imv 并且仅使用 Wayland。以下是您可能执行的操作。
在 "${HOME}/.local/bin/" 中创建 bwrap-imv
并使其可执行
$ touch ~/.local/bin/bwrap-imv $ chmod 0700 ~/.local/bin/bwrap-imv
使用 file
确定 /usr/bin/imv 的文件类型
$ file /usr/bin/imv /usr/bin/imv: POSIX shell 脚本,ASCII 文本可执行文件
由于它只是一个 shell 脚本,我们可以使用 less
查看它
$ less /usr/bin/imv
内容为 /usr/bin/imv
由于我们假设仅 Wayland,我们可以跳到 /usr/libexec/imv-wayland。在其上运行 file
$ file /usr/libexec/imv-wayland /usr/libexec/imv-wayland: ELF 64 位 LSB pie 可执行文件,x86-64,版本 1 (SYSV),动态链接,解释器 /lib/ld-musl-x86_64.so.1,已剥离
它是一个 可执行和可链接格式 (ELF) 文件。所以我们知道我们需要 ELF 解释器 /lib/ld-musl-x86_64.so.1。我们也知道我们需要 /usr/libexec/imv-wayland,因为它必须知道命令的位置。
作为 /usr/libexec/imv-wayland 的参数,放置 "${1:-./}"
,这将只传递第一个参数,如果没有参数,将默认为 ./,当前目录。我们还需要 --ro-bind "${1:-./}" "$(realpath "${1:-./}")" \
,因为我们没有传递整个文件系统。这将使用 realpath
获取绝对路径名,因此您可以传递相对参数并仍然绑定参数
--ro-bind "${1:-./}" "$(realpath "${1:-./}")" \ /usr/libexec/imv-wayland "${1:-./}"

imv
显示该目录下的所有内容,递归地。

查找必要的共享库,除了运行时加载的那些
$ ldd /usr/libexec/imv-wayland
它输出很多内容,但我们只需要几个;大部分的目录路径 /usr/lib/* 和以 /lib/* 开头的 4 个路径。过滤输出以更清楚地查看这些
$ ldd /usr/libexec/imv-wayland | grep ' /lib/'
总计
--ro-bind /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1 \ --ro-bind /lib/libblkid.so.1 /lib/libblkid.so.1 \ --ro-bind /lib/libmount.so.1 /lib/libmount.so.1 \ --ro-bind /lib/libz.so.1 /lib/libz.so.1 \ --ro-bind /usr/lib/ /usr/lib/ \

ldd
手册页谈到了一些安全隐患。这可能不适用,因为他们似乎在谈论 glibc 和 musl-utils 使 /lib/ld-musl-x86_64.so.1 ldd [1]。这是有什么好担心的吗?
由于这是一个 shell 脚本,让我们使用一个有用的命令
set -u
如果 shell 尝试扩展未设置的参数,它将报错(少数例外)。
由于这是用于 GUI Wayland 程序,所以让我们也添加一些前提条件
--setenv XDG_RUNTIME_DIR "$XDG_RUNTIME_DIR" \
用于确定 wayland 套接字的目录;
--setenv WAYLAND_DISPLAY "$WAYLAND_DISPLAY" \
用于确定套接字;
--ro-bind "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" \
只读挂载。
让我们也添加一些锦上添花的功能
--unshare-all \
将创建一个新的 user/ipc/pid/net/utc 命名空间,并尝试在可能的情况下创建一个新的 cgroup 命名空间;
--new-session
将为沙箱创建一个新的终端会话,从控制终端断开连接,例如它无法将输入注入到终端中;
--die-with-parent
将确保子进程(在本例中为 imv-wayland
)在 bwrap
父进程死亡时死亡。
我们可能还有一个 config 文件
--ro-bind-try "${XDG_CONFIG_HOME}/imv/config" "${XDG_CONFIG_HOME}/imv/config" \
如果您有本地配置,这将添加到 imv
,如果没有,则仍然继续。
将 "$XDG_CONFIG_HOME" 传递到沙箱
--setenv XDG_CONFIG_HOME "$XDG_CONFIG_HOME" \
但这并不总是定义的,所以让我们回退到 XDG 基本目录 默认值
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
如果设置了 "$XDG_CONFIG_HOME",这将使用它,否则回退到 "$HOME/.config" 的默认值。
--ro-bind /bin/sh /bin/sh \
需要使用 config 并在窗口标题中显示各种信息。

~/.local/bin/bwrap-imv 现在看起来像
内容为 ~/.local/bin/bwrap-imv
现在让我们运行 bwrap-imv
,进入一个带有图像的目录
$ bwrap-imv IMAGE sh: eval: line 0: can't create /dev/null: nonexistent directory ... sh: eval: line 0: can't create /dev/null: nonexistent directory xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb Assertion failed: keyboard->context (../src/keyboard.c: imv_keyboard_create: 20)
添加
--ro-bind /usr/share/X11/xkb/ /usr/share/X11/xkb/ \
到 bwrap-imv
。XKB 是一个键盘键映射支持库。
添加上述内容后,再次运行它
$ bwrap-imv IMAGE sh: eval: line 0: can't create /dev/null: nonexistent directory ... sh: eval: line 0: can't create /dev/null: nonexistent directory libEGL warning: wayland-egl: could not open /dev/dri/renderD128 (No such file or directory)
添加
--dev-bind /dev/dri/renderD128 /dev/dri/renderD128 \
并再次运行
$ bwrap-imv IMAGE libEGL warning: wayland-egl: drmGetMagic failed
--ro-bind /sys/dev/char/ /sys/dev/char/ \
访问字符设备。

--ro-bind /sys/devices/pci0000:00/ /sys/devices/pci0000:00/ \
访问 PCI 资源。

--clearenv \
最后,我们可以取消设置所有环境变量,除了 "$PWD" 和我们使用 --setenv
设置的任何变量。
现在 imv
应该显示图像,并且您的 config 文件应该可以工作(如果您有)。如果您不使用命令,完成的 ~/.local/bin/bwrap-imv 应该看起来像
内容为 ~/.local/bin/bwrap-imv
但是,如果您确实使用命令,您会注意到它仅显示 替换字符。
imv
中的命令通过按 :
输入。如果您尝试使用命令,它会说
Fontconfig error: Cannot load default config file: No such file: (null)
查看 fonts-conf
手册页(来自 fontconfig-doc),我们看到 /etc/fonts/ 是系统字体配置目录,"${XDG_CONFIG_HOME}/fontconfig/" 是每用户配置目录。"${XDG_CONFIG_HOME}/fontconfig/" 使用 --ro-bind-try
添加,因此它不必存在
--ro-bind /etc/fonts/ /etc/fonts/ \ --ro-bind-try "${XDG_CONFIG_HOME}/fontconfig/" "${XDG_CONFIG_HOME}/fontconfig/" \
扫描字体文件的默认目录是 /usr/share/fonts/ 和 "${XDG_DATA_HOME}/fonts/"。"${XDG_DATA_HOME}/fonts/" 使用 --ro-bind-try
添加
--ro-bind /usr/share/fonts/ /usr/share/fonts/ \ --ro-bind-try "${XDG_DATA_HOME}/fonts/" "${XDG_DATA_HOME}/fonts/" \
将 "$XDG_DATA_HOME" 传递到沙箱
--setenv XDG_DATA_HOME "$XDG_DATA_HOME" \
就像 "$XDG_CONFIG_HOME" 一样,这并不总是定义的,所以回退到 XDG 基本目录 默认值
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
如果设置了 "$XDG_DATA_HOME",则使用它,否则使用 "$HOME/.local/share"。
还需要用户字体信息缓存,默认情况下是 "${XDG_CACHE_HOME}/fontconfig/"
--bind-try "${XDG_CACHE_HOME}/fontconfig/" "${XDG_CACHE_HOME}/fontconfig/" \
将 "$XDG_CACHE_HOME" 传递到沙箱
--setenv XDG_CACHE_HOME "$XDG_CACHE_HOME" \
就像 "$XDG_CONFIG_HOME" 一样,这并不总是定义的,所以回退到 XDG 基本目录 默认值
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
如果设置了 "$XDG_CACHE_HOME",则使用它,否则使用 "$HOME/.cache"。
--ro-bind /usr/share/icu/ /usr/share/icu/ \
也是需要的,否则当您执行 :<backspace>
时,它将终止进程。ICU 提供 Unicode 和全球化支持。

更新后的 ~/.local/bin/bwrap-imv 应该看起来像这样
内容为 ~/.local/bin/bwrap-imv
查看沙箱中存在的内容
最后,通过将 /usr/libexec/imv-wayland "${1:-./}"
替换为 /bin/sh
并添加 --ro-bind /bin/ /bin/ \
来测试所有允许的内容。四处查看,看看文件系统是什么样的
内容为 ~/.local/bin/bwrap-imv
调用 bwrap-imv
$ bwrap-imv IMAGE
显示哪些环境变量处于活动状态
$ printenv
查看根目录下的目录
$ ls -la / ... bin ... dev ... etc ... home ... lib ... sys ... tmp ... usr
完成时 exit
$ exit
不要忘记改回来
内容为 ~/.local/bin/bwrap-imv
完成了基本 bwrap
包装器。
Seccomp
![]() |
.desktop 集成
![]() 这可能应该在 Default_applications 中记录并链接到此处。在使用 |
XDG 桌面条目规范 是一组标准,描述了如何启动特定程序,它如何在菜单中显示等等。
imv
的默认 .desktop 文件位于 /usr/share/applications/imv.desktop。将其移动到 "${XDG_DATA_HOME}/applications/bwrap-imv.desktop"。
只需要更改 3 个选项:Name/Name[en_US],在图形文件管理器(如果您已安装)的应用程序菜单中显示的内容;Exec,要执行的程序
内容为 "${XDG_DATA_HOME}/applications/bwrap-imv.desktop"
程序 xdg-open
(来自 xdg-utils 软件包)可用于根据 MIME 类型 + "${XDG_CONFIG_HOME}/mimeapps.list" 和 "${XDG_DATA_HOME}/applications/mimeinfo.cache" 中相应的条目打开文件。
如果尚未安装 desktop-file-utils,请安装它,它带有两个需要的命令 desktop-file-validate
和 update-desktop-database
# apk add desktop-file-utils
验证
最好使用 desktop-file-validate
验证 imv.desktop
$ desktop-file-validate "${XDG_DATA_HOME}/applications/bwrap-imv.desktop"
更新数据库
这将使 "${XDG_DATA_HOME}/applications/" 中的条目优先于系统范围的文件(/usr/share/applications/)。但是 "${XDG_CONFIG_HOME}/mimeapps.list" 优先于两者。
更新数据库将创建 "${XDG_DATA_HOME}/applications/mimeinfo.cache"
$ update-desktop-database "${XDG_DATA_HOME}/applications"
故障排除
找不到缺少的路径
如果所有其他方法都失败,请从广泛开始,并努力缩小范围。查看 bwrap
是否完全适用于该程序
$ bwrap \ --dev-bind / / PROGRAM
如果这有效,则开始缩小范围
$ bwrap \ --ro-bind /bin/ /bin/ \ --dev-bind /dev/ /dev/ \ --ro-bind /lib/ /lib/ \ --ro-bind /sys/ /sys/ \ --ro-bind /usr/ /usr/ \ PROGRAM
继续操作,直到您尽可能缩小范围。