安全性与租户隔离如何让 Deno Subhosting 安全运行非受信任代码
Deno Subhosting 提供了最简单、最安全的方式,允许第三方开发者编写和运行自定义代码,从而扩展您平台的功能。例如,Deno Subhosting 为 Netlify 的边缘函数提供支持,以便其用户能够通过网站实现更多功能。
但任何时候在云端执行第三方代码,安全性都会成为一个可以理解且至关重要的担忧——我们如何防止开发者编写恶意代码,试图访问其他用户的代码甚至我们的内部系统?
安全运行任意代码是为 Deno Deploy 和 Deno Subhosting 提供支持的无服务器 V8 隔离云的首要任务,在平台设计的每一步都考虑到了最大化租户隔离。为了理解我们的无服务器平台是如何从零开始考虑安全性的,让我们首先深入了解威胁模型。
威胁模型
我们的无服务器计算平台允许任何人在互联网上部署和运行代码。为了确保单个恶意行为者不会拖垮整个系统,我们制定了以下 5 项指令
每次部署(单个租户)必须
- 仅访问其自身的运行时(JavaScript 对象、方法)
- 仅访问其自身的数据(文件、代码、数据库、环境变量)
- 无法访问 Deno Deploy 内部系统,例如底层操作系统和内部服务
- 不会拒绝其他隔离环境的资源(例如 CPU、内存)
- 不得将 Deno Deploy 用于非预期用途(例如比特币挖矿)
基于此威胁模型,我们可以通过三个主要方面来隔离租户
让我们在下文逐一探讨。
API 限制
为防止代码出现恶意行为,我们设置了多重保障措施,从应用程序层面限制其功能。这包括
- 使用 V8 隔离:谷歌将V8 隔离定义为
……一个独立的 V8 引擎实例。V8 隔离拥有完全独立的状态。来自一个隔离的对象不得在其他隔离中使用。
每个 V8 隔离都是一个沙箱,其构建方式使得程序无法对其他隔离执行任何操作。例如,隔离之间没有可共享的 JavaScript 方法或对象
使用虚拟化文件系统:当部署中的代码使用文件系统方法时,它们实际上不会触及文件系统,因为它们是虚拟化的,并且作用域限定在该隔离内。
拥有独立的虚拟私有云 (VPC) 网络:我们的无服务器平台使用两个 VPC——一个用于将来自互联网的入站请求路由到我们的运行器,另一个独立的 VPC 供隔离使用以访问互联网(例如,如果您的部署调用
fetch()
,它将使用此网络)。
这三项措施协同工作,为每次部署中的应用程序提供隔离。
纵深防御
除了简单地隔离每个租户中的应用程序代码之外,我们的威胁模型之一是确保代码无法访问底层系统,例如操作系统。我们的基础设施使用以下几项措施来防范这种情况
在更严格的 Deno 运行时上运行其自身进程:虽然 Deno 运行时已提供可选的权限系统来限制 JavaScript 程序的功能,但我们的无服务器基础设施通过使用更严格的 Deno 版本进一步扩展了这一点。例如,部署可以读取自己的静态资产,但无法写入文件系统。
使用Linux 命名空间:命名空间将 Linux 内核资源进行分区,使得一组进程看到一组资源,而另一组进程看到不同的资源。开发此功能是为了进一步隔离服务,并最大限度地减少更改的“爆炸半径”。这是 Docker 和 Kubernetes 常用的隔离技术。
使用seccomp 过滤器:目前,每个隔离都在其自身的进程和命名空间中运行,如果它要与另一个进程交互,它将需要使用在正常操作下不会使用的系统调用。如果进程正在寻找异常系统调用,我们可以检测到尝试突破沙箱的行为。seccomp(“安全计算”)过滤器允许我们检查进程是否正在尝试使用异常系统调用,从而尝试恶意行为。
这些措施保护进程免受访问可能使其与其他租户交互的低级命令和系统的影响。
资源公平性
最后,安全的另一个方面是确保每个租户都能使用其分配到的资源。这带来了另一个好处,即确保 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。