ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

DotNetIsolator核心概念一文读懂:IsolatedRuntimeHost与IsolatedRuntime完全解析

2026/8/18 18:07:03 拓冰建站 浏览量
DotNetIsolator核心概念一文读懂:IsolatedRuntimeHost与IsolatedRuntime完全解析 DotNetIsolator核心概念一文读懂IsolatedRuntimeHost与IsolatedRuntime完全解析【免费下载链接】DotNetIsolatorA library for running isolated .NET runtimes inside .NET项目地址: https://gitcode.com/gh_mirrors/do/DotNetIsolatorDotNetIsolator 是一个能让你的 .NET 程序在隔离环境中运行其他 .NET 代码的开源库其核心概念就是一对黄金搭档IsolatedRuntimeHost宿主工厂与IsolatedRuntime隔离运行时实例。本文用通俗易懂的方式为新手完整解析这两个核心类的职责、用法与最佳实践帮你快速搞懂如何在自己的项目中搭建 .NET 沙箱环境。 一句话理解IsolatedRuntimeHost 负责造沙箱IsolatedRuntime 负责在沙箱里跑代码。想在自己的项目里安全地执行不可信 .NET 代码掌握这两者是第一步。DotNetIsolator 是什么隔离 .NET 运行时的工作原理DotNetIsolator 的底层方案并不神秘每个隔离运行时实际上是一个WebAssembly 沙箱由 dotnet-wasi-sdk 构建运行在 Wasmtime 之上。这意味着每个IsolatedRuntime都拥有特性说明 独立内存空间与宿主进程完全隔离无法直接读写宿主内存 无系统权限无法直接访问宿主机器的磁盘、网络和操作系统 API 独立程序集通过宿主喂给它程序集才具备运行能力 双向调用宿主可以调隔离环境隔离环境也能回调宿主举个最直观的例子用Invoke在隔离环境里运行一段 lambda你会看到宿主机与沙箱内的架构信息完全不同using var host new IsolatedRuntimeHost().WithBinDirectoryAssemblyLoader(); using var runtime new IsolatedRuntime(host); Console.WriteLine($Im running on {RuntimeInformation.OSArchitecture}); runtime.Invoke(() { Console.WriteLine($Im running on {RuntimeInformation.OSArchitecture}); });输出结果大致为Im running on X64 Im running on Wasm宿主是 X64沙箱里却是 Wasm——这就是隔离 .NET 运行时的直观体现。IsolatedRuntimeHost 核心解析为何它是一次性的宿主工厂IsolatedRuntimeHost是整个体系的入口它负责启动 Wasmtime 引擎、加载 WASI 模块、配置程序集加载器。它的定义位于 IsolatedRuntimeHost.cs。IsolatedRuntimeHost 的三大职责启动 Wasmtime 引擎这一步大约耗时400ms属于重资产所以应该全局只创建一次然后反复复用源码见 IsolatedRuntimeHost.cs。配置程序集加载隔离环境里没有现成的代码需要由宿主投喂程序集字节。不保存运行时状态Host 本身不持有任何与具体沙箱相关的状态因此可以安全地跨线程共享。如果你在使用依赖注入DI完全可以把IsolatedRuntimeHost注册为单例Singleton。最快配置方法WithBinDirectoryAssemblyLoader最常用的配置方式就是从宿主程序的 bin 目录加载程序集using var host new IsolatedRuntimeHost() .WithBinDirectoryAssemblyLoader();它的实现逻辑很简单根据程序集名去 bin 目录找对应的.dll文件并读取字节见 IsolatedRuntimeHost.cs。使用这一配置后你就可以在隔离环境里调用 lambda 方法方法代码就在 bin 目录的 DLL 中在隔离环境里实例化任意类型的对象在宿主与沙箱之间传递、返回自定义类型自动通过 MessagePack 序列化。⚠️ 注意WithBinDirectoryAssemblyLoader并不会让沙箱代码逃逸出隔离边界。即使它能加载宿主程序集也只能在沙箱内使用无法直接访问宿主资源。更严格的程序集加载控制WithAssemblyLoader如果你希望精细控制哪些程序集可以被加载可以用WithAssemblyLoader自定义加载回调using var host new IsolatedRuntimeHost() .WithAssemblyLoader(assemblyName { if (assemblyName MyAssembly) { return File.ReadAllBytes(some/path/to/MyAssembly.dll); } return null; // 未知程序集交给其他 loader });你还可以注册多个加载器按注册顺序依次尝试直到某个加载器返回非空字节为止见 IsolatedRuntimeHost.cs。此外还有WithDirectoryAssemblyLoader可指定任意目录。IsolatedRuntimeHost 的隐藏能力注册 WASI 导入与回调在构造函数里Host 会通过Linker.DefineWasi()注册 WASI 导入并定义两个名为dotnetisolator模块的宿主函数request_assembly处理程序集请求与call_host处理来自沙箱的宿主调用见 IsolatedRuntimeHost.cs。call_host的实现会把调用转发给当前Store关联的IsolatedRuntime再交给AcceptCallFromGuest处理见 IsolatedRuntimeHost.cs——这正是沙箱反向调用宿主的关键通道。IsolatedRuntime 核心解析轻量级沙箱实例IsolatedRuntime是真正跑代码的地方定义位于 IsolatedRuntime.cs。它持有Store、Instance、内存引用以及一系列 WASM 导出函数每个实例都是完全独立的沙箱。创建 IsolatedRuntime 只需两步using var host new IsolatedRuntimeHost().WithBinDirectoryAssemblyLoader(); using var runtime new IsolatedRuntime(host);与 Host 的 400ms 启动成本不同每个 runtime 实例化大约只需 8ms所以你可以非常轻量地按需创建using var runtime1 new IsolatedRuntime(host); using var runtime2 new IsolatedRuntime(host);想开多少个沙箱就开多少个它们之间互不干扰。这也是 DotNetIsolator 最吸引人的设计之一一个昂贵的引擎 N 个廉价的沙箱。在隔离环境里调用 lambda最直观的入口IsolatedRuntime.Invoke是最常用的调用方式它支持捕获闭包变量并自动用 MessagePack 序列化跨边界传递var person1 new Person(3); var person2 new Person(9); var sumOfAges runtime.Invoke(() { // 这段代码运行在隔离环境里 return person1.Age person2.Age; }); Console.WriteLine($The isolated runtime calculated the result: {sumOfAges}); record Person(int Age);注意lambda 对捕获对象或静态字段的修改只会在沙箱内生效不会影响宿主中的对象因为两边没有共享内存。实现细节可参考 IsolatedRuntime.cs。在隔离环境里创建对象IsolatedObject如果不想依赖 bin 目录加载器也可以手动在沙箱里创建对象再调用其方法// 泛型 API IsolatedObject obj1 runtime.CreateObjectPerson(); // 字符串 API宿主项目未引用该程序集时更适用 IsolatedObject obj2 runtime.CreateObject(MyAssembly, MyNamespace, Person);创建后即可调用方法isolatedObject.InvokeVoid(DoSomething, 123); // 无返回值 TimeSpan result isolatedObject.Invokebool, TimeSpan(GetAge, true); // 有返回值也可以先用FindMethod拿到方法引用类似MethodInfo稍后再调用见 IsolatedObject.cs。IsolatedMethod的完整调用重载见 IsolatedMethod.cs。⚠️ 当前限制CreateObject要求类型有无参构造函数带参构造的支持尚未实现见 NOTES.md 中的 TODO 列表。隔离环境反向调用宿主RegisterCallback 双向通道沙箱代码也能回调宿主宿主先注册一个命名回调using var runtime new IsolatedRuntime(host); runtime.RegisterCallback(addTwoNumbers, (int a, int b) a b); runtime.RegisterCallback(getHostTime, () DateTime.Now);然后在沙箱代码里通过DotNetIsolatorHost.Invoke调用var sum DotNetIsolatorHost.Invokeint(addTwoNumbers, 123, 456); var hostTime DotNetIsolatorHost.InvokeDateTime(getHostTime);宿主侧的接收逻辑在 IsolatedRuntime.cs 的AcceptCallFromGuest中实现它会根据回调签名反序列化参数并动态调用。测试用例可以参考 HostCallbackTest.cs。核心概念对比表Host vs Runtime 一张表看懂对比维度IsolatedRuntimeHostIsolatedRuntime 定位宿主工厂重资产沙箱实例轻资产 初始化成本约 400ms建议只建一次约 8ms可随意创建 状态无运行时状态可共享/单例每个实例完全独立 主要职责引擎、链接器、程序集加载配置内存、方法调用、对象管理 对应源码IsolatedRuntimeHost.csIsolatedRuntime.cs记住这个黄金法则Host 造一次、反复用Runtime 按需建、随意开。快速上手指南从零搭建你的第一个 .NET 沙箱想立刻体验按照以下 4 步即可第 1 步安装 NuGet 包dotnet add package DotNetIsolator --prerelease第 2 步创建 Host 并配置程序集加载using var host new IsolatedRuntimeHost() .WithBinDirectoryAssemblyLoader();第 3 步创建 Runtime 并在沙箱内执行代码using var runtime new IsolatedRuntime(host); var isolatedEnvInfo runtime.Invoke(GetEnvironmentInfo);第 4 步对比宿主与沙箱的环境差异static EnvInfo GetEnvironmentInfo() { var sysRoot Environment.GetEnvironmentVariable(SystemRoot) ?? (Not set); return new EnvInfo( Environment.GetEnvironmentVariables().Count, $SystemRoot{sysRoot}); } record EnvInfo(int NumEnvVars, string ExampleEnvVar);输出类似Real env: 64 entries, including SystemRootC:\WINDOWS Isolated env: 0 entries, including SystemRoot(Not set)宿主能看到的 64 个环境变量沙箱里一个都没有——隔离效果立竿见影。安全注意事项把隔离当安全边界前必读如果你打算把 DotNetIsolator 的隔离作为关键安全边界请务必了解 这是实验性预发布包尚未经过安全审查可能存在让沙箱代码影响宿主的缺陷️ WebAssembly 本身是久经考验的沙箱技术浏览器多年运行不可信 WASM 模块但 Wasmtime 与浏览器实现不同 WebAssembly 安全模型并未直接解决 Spectre 这类侧信道攻击问题。结论作为多层安全体系中的其中一层它表现不错但不要指望它单枪匹马抵御恶意代码。如果你的场景只是隔离管理自己的代码而非运行不可信代码大部分安全顾虑其实不适用。总结掌握这两个核心类你就掌握了 DotNetIsolatorIsolatedRuntimeHost一次创建、全局复用负责引擎与程序集加载配置是沙箱的总装车间IsolatedRuntime按需创建、互不干扰负责实际执行与双向调用是沙箱的生产车间两者配合即可在 .NET 中轻松实现隔离的 .NET 运行时隔离磁盘、网络、操作系统等宿主资源。想深入了解源码细节推荐阅读 IsolatedRuntimeHost.cs、IsolatedRuntime.cs以及测试用例 StartupTest.cs、MethodInvocationTest.cs 和 ObjectCreationTest.cs对照示例代码学习效果最佳。动手试试吧【免费下载链接】DotNetIsolatorA library for running isolated .NET runtimes inside .NET项目地址: https://gitcode.com/gh_mirrors/do/DotNetIsolator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考