如何在 Docker 容器中安全地运行 Puppeteer / Chromium?

信息安全 linux 沙盒 码头工人
2021-08-31 06:37:51

尝试在 Docker 中运行 Puppeteer,一个控制无头 Chromium 的 Node 库(以便执行诸如创建网站的 PDF 之类的事情)是一件令人惊讶的繁琐事情。

问题是,据我了解,要以 root 身份运行,您需要 option --no-sandbox,这被正确地谴责为不安全和糟糕的解决方案。问题是首选替代品似乎同样糟糕:

  • 用 运行容器CAP_ADD=SYS_ADMIN,我想我不需要进一步评论,或者

  • 以非 root 身份运行,但要在非 root 沙箱中运行 Puppeteer,您需要启用 kernel 选项unprivileged_userns_clone,一旦我开始研究发现据说

“打开 Linux 内核中的严重漏洞”(链接

“非特权用户命名空间非常危险”(链接

令我惊讶的是,做一些像运行 Web 浏览器这样简单且相对较低级别的事情似乎需要如此广泛的权限,这显然会打开广泛的攻击媒介。如果我要 root 手机或破坏操作系统安全例程,我正在阅读的那种警告是我期望阅读的。

我是不是误解了这里的情况,还是在 Docker 容器中运行 Chromium 等于将我的服务器开放给一半的互联网?

3个回答

看起来最好的选择是使用自定义 seccomp 配置文件

你可以在这里看到一个例子

您需要的文件的其他链接以防它们消失:

wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json
wget https://raw.githubusercontent.com/Zenika/alpine-chrome/master/chrome.json

示例用法:

docker container run -it --rm --security-opt seccomp=$(pwd)/chrome.json zenika/alpine-chrome

我认为以非 root 用户身份运行 puppeteer 不需要对底层主机的配置进行任何修改,因为有许多 Docker 镜像可以成功地做到这一点。

一个例子是基于 Puppeteer 构建的DecktapeDocker 映像(在 GH 存储库中链接了命令)以用户身份运行node并在未修改的 Linux 实例上运行。

我有同样的问题,并在 stackexchange 上遇到了同样可怕的答案/评论。在阅读了另一个答案中链接的lwn.net 文章,并阅读了 stackexchange 上所有明显相关的答案后,我想我已经理解了这个问题。

问题似乎在于创建隔离环境涉及克隆“用户名称空间”。使用默认设置,unprivileged_userns_clone=0您可以克隆一次命名空间,但是,一旦进入命名空间,就无法再次进一步克隆命名空间。由于 docker 和 chrome 都创建了一个沙盒命名空间,因此不可能从 docker 容器内部运行 chrome 而无需跳过额外的环节。请注意,运行打包为 AppImage 的电子应用程序时会出现同样的问题。

因此,要回答这里提出的具体问题:不,我认为这并不等于将您的服务器开放给一半的互联网,尽管设置unprivileged_userns_clone=1不是最安全的选择。

似乎有三种方法可以解决这个问题:

  1. 使用 --no-sandbox 运行 chrome(或电子)。这可能没问题,因为 docker 已经提供了一定程度的隔离。
  2. 按照另一个答案的建议设置自定义 seccomp 配置文件
  3. 覆盖kernel.unprivileged_userns_clone内核中的默认设置以允许嵌套命名空间克隆。这是据称危险的活动。似乎禁用 unprivileged_userns_clone 是一种强化措施,它可以防止在某种程度上可能并且可能确实存在的一类未知但潜在的漏洞。因此,这可能不是一个绝对明显的安全风险。它在一定程度上削弱了安全性,但似乎不会让您面临直接且已知的“野外”安全威胁。

简短版本:我同意这个答案,但我无法投票赞成这个答案,因为我还没有足够的声誉。