跳到主要内容
Deno 2 终于来了 🎉️
了解更多
Deno Subhosting cover image.

安全性和租户隔离如何使 Deno 子托管安全地运行不受信任的代码

Deno 子托管 提供了一种最简单、最安全的方式来扩展平台的功能,允许第三方开发者编写和运行自定义代码。例如,Deno 子托管为 Netlify 的边缘函数提供支持,因此他们的用户可以更充分地利用他们的网站。

但是,只要在云中执行第三方代码,安全性就会成为一个可以理解的且至关重要的顾虑——我们如何防止我们的开发者编写恶意代码来尝试访问其他用户的代码甚至我们的内部系统?

Diagram of tenant isolation in Deno Deploy and Deno Subhosting

我们的 V8 隔离云使用多种工具来隔离每个租户,使其彼此独立,也使其与底层操作系统独立。我们将在下面深入研究每个工具。

安全地运行任意代码是 无服务器 V8 隔离云 的首要任务,该云为 Deno Deploy 和 Deno 子托管提供支持,在设计我们的平台的每一步都考虑了最大限度地隔离租户。为了了解我们的无服务器平台是如何从一开始就将安全考虑因素纳入其中,让我们首先深入研究威胁模型。

威胁模型

我们的无服务器计算平台允许任何人部署和运行互联网上的代码。为了确保单个恶意行为者不会破坏整个系统,我们制定了以下 5 条指令

每个部署(单个租户)必须

  • 只能访问其自身的运行时(JavaScript 对象、方法)
  • 只能访问其自身的数据(文件、代码、数据库、环境变量)
  • 不能访问 Deno Deploy 的内部组件,例如底层操作系统和内部服务
  • 不剥夺其他隔离的资源(例如 CPU、内存)
  • 不将 Deno Deploy 用于未经许可的用例(例如,挖矿比特币)

鉴于此威胁模型,我们可以隔离租户的三大主题

让我们在下面深入研究每个主题。

API 限制

为了防止代码出现恶意行为,有许多安全措施限制了应用程序级甚至能够做什么。这包括

  • 使用 V8 隔离:Google 将 V8 隔离 定义为

…V8 引擎的独立实例。V8 隔离具有完全独立的状态。来自一个隔离的对象不能在其他隔离中使用。

每个 V8 隔离都是一个沙盒,其构建方式使得程序无法对另一个隔离做任何事情。例如,没有 JavaScript 方法或对象可以在隔离之间共享

  • 使用虚拟化文件系统:当部署中的代码使用文件系统方法时,它们实际上不会接触文件系统,因为它们是虚拟化的,并且范围限于该隔离。

  • 拥有独立的虚拟专用云 (VPC) 网络:我们的无服务器平台使用两个 VPC——一个用于将来自互联网的传入请求路由到我们的运行器,另一个用于隔离访问互联网(例如,如果您的部署调用 fetch(),它将使用此网络)。

这三者协同工作,为每个部署中的应用程序提供隔离。

纵深防御

除了简单地隔离每个租户中的应用程序代码之外,我们的威胁模型之一是确保代码也不能访问底层系统,例如操作系统。我们的基础设施使用一些东西来防止这种情况

  • 在更严格的 Deno 运行时运行其自身的进程:虽然 Deno 运行时已经提供了一个可选的权限系统来锁定 JavaScript 程序可以执行的操作,但我们的无服务器基础设施通过使用更严格的 Deno 版本进一步扩展了这一点。例如,部署可以读取其自身的静态资产,但不能写入文件系统。

  • 使用 Linux 命名空间:命名空间对 Linux 内核资源进行分区,以便一组进程看到一组资源,而另一组进程看到另一组资源。此功能的开发是为了进一步隔离服务,并最大限度地减少更改的“爆炸半径”。这是 Docker 和 Kubernetes 使用的一种常见的隔离技术。

  • 使用 seccomp 过滤器:到目前为止,每个隔离都在其自身的进程和命名空间中运行,为了与另一个进程进行交互,它需要使用在正常操作下不会使用的系统调用。如果进程正在寻找不寻常的系统调用,我们可以检测到尝试越过沙盒的尝试。Seccomp(“SECure COMPuting”)过滤器允许我们检查进程是否试图使用不寻常的系统调用,因此尝试恶意行为。

这些措施可以保护进程免受访问更低级别的命令和系统,这些命令和系统可能允许它与其他租户进行交互。

资源公平

最后,另一个安全领域是确保每个租户都能使用其分配的资源。这带来了另一个好处,即确保每个 Deno Deploy 和 Deno 子托管的用户都能获得他们应得的资源份额,并且不会出现单个用户独占所有 CPU(例如)的情况。以下工具还确保人们在使用我们的 V8 隔离云时遵守条款和条件(即,不挖矿比特币)。

  • 使用 cgroups:控制组(“cgroups”)允许我们定义一个或多个进程的资源使用量(CPU、内存、磁盘 I/O、网络进出等)的边界。当定义的资源限制被超过时,cgroups 会自动限制进程。cgroup 防御设置上限,从而防止单个部署或租户超过 CPU 使用量,这可能会对周围租户的性能产生负面影响。

  • 使用我们的 WatchDog 进行监控:我们构建了自己的内部服务 WatchDog,该服务监控任何给定运行器上隔离的 CPU 利用率和内存。例如,WatchDog 会终止在一段时间内超过其内存限制或长时间阻塞事件循环的隔离(即,它们变得没有响应)。

这些工具确保资源在所有租户之间公平共享,并且不会出现单个部署利用我们的平台的情况。

重新审视威胁模型

那么上述工具如何融入我们的威胁模型?让我们来看一下

每个部署(单个租户)必须

  • 只能访问其自身的运行时(JavaScript 对象、方法)

    这是通过在每个部署中运行其自身的 V8 隔离,拥有虚拟化文件系统以及拥有独立的 VPC 网络来实现的。

  • 只能访问其自身的数据(文件、代码、数据库、环境变量)

    这是通过使用其自身的进程、命名空间和 seccomp 过滤器来实现的。

  • 不能访问 Deno Deploy 的内部组件,例如底层操作系统和内部服务

    这是通过 API 限制和独立的 VPC 网络来实现的,以及纵深防御措施,例如将每个进程放在独立的命名空间中并配置 seccomp 来检测进程不应该进行的系统调用。

  • 不剥夺其他隔离的资源(例如 CPU、内存)

    这是通过 cgroups 和 Deno WatchDog 来实现的。cgroup 防御设置上限,而 WatchDog 会终止在一段时间内超过其内存限制或长时间阻塞事件循环的隔离。

  • 不将 Deno Deploy 用于未经许可的用例(例如,挖矿比特币)

    Deno WatchDog 被编程为检测违反我们条款和条件的不寻常行为。

构建安全的组织

安全是为 Web 构建时的一个重要问题。不仅 在运行时内置了一个可选的权限系统,它也是我们全球分布式无服务器托管平台的重点关注领域。我们在设计托管基础设施时做出的每个决定都考虑到了安全因素。

最后,为了进一步彰显我们对安全性的承诺,这不仅体现在我们的运行时和托管平台,Deno 公司还独立接受了审计并获得了 SOC 2 合规认证

放心地运行用户的不信任代码。 立即注册 Deno Subhosting