跳到主要内容
Deno Subhosting cover image.

Deno Subhosting 如何通过安全性和租户隔离安全地运行不受信任的代码

Deno Subhosting 通过允许第三方开发者编写和运行自定义代码,提供了一种最简单和最安全的方式来扩展你平台的功能。例如,Deno Subhosting 为 Netlify 的边缘函数提供支持,以便他们的用户可以使用他们的网站做更多的事情。

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

Diagram of tenant isolation in Deno Deploy and Deno Subhosting

我们的 V8 隔离云使用多种工具将每个租户彼此隔离,并与底层操作系统隔离。我们将在下面深入探讨每一个工具。

安全地运行任意代码是 Deno Deploy 和 Deno Subhosting 提供支持的无服务器 v8 隔离云的首要任务,最大化租户隔离在我们平台设计的每一步都被考虑在内。为了理解我们的无服务器平台从一开始是如何考虑安全性的,让我们首先深入了解威胁模型。

威胁模型

我们的无服务器计算平台允许任何人在互联网上部署和运行代码。为了确保一个不良行为者不会拖垮系统的其余部分,我们制定了以下 5 条指令

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

  • 仅能访问其自身的运行时(JavaScript 对象、方法)
  • 仅能访问其自身的数据(文件、代码、数据库、环境变量)
  • 不能访问 Deno Deploy 内部组件,例如底层操作系统和内部服务
  • 不拒绝其他隔离区所需的资源(例如 CPU、内存)
  • 不将 Deno Deploy 用于非预期用例(例如,挖比特币)

鉴于此威胁模型,我们可以从三个主要主题来隔离租户

让我们在下面分别介绍。

API 限制

为了防止代码出现恶意行为,有许多安全措施限制了应用程序级别的功能。这包括

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

每个 V8 隔离区都是一个沙箱,其构建方式使得程序不可能对另一个隔离区做任何事情。例如,隔离区之间不能共享任何 JavaScript 方法或对象

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

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

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

深度防御

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

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

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

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

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

资源公平性

最后,安全的另一个领域是确保每个租户都能使用分配给它的资源。这也带来了另一个好处,即确保 Deno Deploy 和 Deno Subhosting 的每个用户都能获得公平的资源份额,并且不会有一个用户占用所有 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