出于安全原因,我想对我的浏览器进行沙盒处理,因此我想出了以下包装脚本以在 bwrap 沙盒内运行 Firefox:
$ cat ~/.local/bin/firefox
#!/bin/sh
MYDISPLAY="${DISPLAY##*:}"
MYDISPLAY="${MYDISPLAY%%.*}"
/usr/bin/bwrap \
--unshare-all \
--tmpfs /tmp \
--bind ${HOME}/.cache/mozilla ${HOME}/.cache/mozilla \
--bind ${HOME}/.mozilla ${HOME}/.mozilla \
--bind ${HOME}/Downloads ${HOME}/Downloads \
--bind /tmp/.X11-unix/X${MYDISPLAY} /tmp/.X11-unix/X${MYDISPLAY} \
--ro-bind ${HOME}/.config/mimeapps.list ${HOME}/.config/mimeapps.list \
--ro-bind ${HOME}/.local/share/fonts ${HOME}/.local/share/fonts \
--ro-bind ${HOME}/.local/share/mime ${HOME}/.local/share/mime \
--ro-bind /usr/bin /usr/bin \
--ro-bind /usr/lib /usr/lib \
--ro-bind /usr/lib64 /usr/lib64 \
--ro-bind /usr/share /usr/share \
--ro-bind /etc/alternatives /etc/alternatives \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--ro-bind /etc/ssl /etc/ssl \
--ro-bind /etc/ca-certificates /etc/ca-certificates \
--ro-bind ${XDG_RUNTIME_DIR}/pulse ${XDG_RUNTIME_DIR}/pulse \
--symlink usr/bin /bin \
--symlink usr/lib /lib \
--symlink usr/lib64 /lib64 \
--dev /dev \
--dev-bind /dev/dri /dev/dri \
--proc /proc \
--setenv HOME ${HOME} \
--hostname RESTRICTED \
--share-net \
--die-with-parent \
--new-session \
-- \
/usr/bin/firefox "${@}"
效果很好。但是,如果 Firefox 已在运行,并且我调用了例如,$ firefox "https://example.com"
则会收到以下错误:
我很清楚为什么会发生这种情况:bwrap 创建了第二个沙箱并尝试在新沙箱内第二次启动 Firefox。
我想要实现的目标:在第一个沙箱内为已经运行的 Firefox 添加一个选项卡。
因此我必须以$ firefox "https://example.com"
某种方式在现有的沙箱内运行该命令。有办法实现这一点吗?
答案1
基于官方的Firefox flatpak并且 Flatpakbwrap
内部使用,应该有办法让它工作。请注意,最简单的方法可能是通过该 flatpak 使用 Firefox,并可能调整其配置。
话虽如此,我很好奇并深入研究了实现细节:
出于安全原因,
brwap
只能创建新的命名空间,而不能进入现有的命名空间解决这个问题的唯一方法是在沙箱中运行某种可以接收命令的作业调度程序 - 这基本上就是 Firefox 所做的,所以让我们看看它是如何实现的。通知已运行实例的远程机制使用数据总线在 Linux 上运行时(参见源代码)这里和这里)。因此,新
firefox
进程的沙盒必须能够firefox
通过 DBus 与现有进程的沙盒通信。因此,官方的 Firefox flatpak 明确授予对必要 DBus 接口的访问权限。brwap
本身只允许整个 DBus 套接字通过,存在安全风险。Flatpak 通过将主 DBus Unix 套接字交给新的xdg-dbus-代理 实例(在另一个沙箱中运行)公开一个“过滤的” DBus Unix 套接字 - 后者实际上被提供给应用程序沙箱。
根据 Firefox flatpak 和我对 flatpak 内部结构的了解,调用xdg-dbus-proxy
应该是这样的:
xdg-dbus-proxy \
unix:path=/var/run/user/$UID/bus \
/run/user/$UID/.dbus-proxy/session-bus-proxy-$RANDOMID \
--filter \
--own="org.mpris.MediaPlayer2.firefox.*" \
--own="org.mozilla.firefox.*" \
--own="org.mozilla.firefox_beta.*"
几点说明:
- 尚未测试。
$RANDOMID
应该是在您的 Firefox 脚本的不同调用之间唯一的字母数字字符串。- 应使用类似如下的方式 将套接字
/run/user/$UID/.dbus-proxy/session-bus-proxy-$RANDOMID
传递到您的调用中:bwrap
/usr/bin/bwrap ... \ --ro-bind /run/user/$UID/.dbus-proxy/session-bus-proxy-$RANDOMID:/run/sandbox/bus \ --setenv DBUS_SESSION_BUS_ADDRESS unix:path=/run/sandbox/bus
- 该
flatpak
实现的作用远不止这些,比如确保在主进程关闭时所有内容一起终止。