第 4 卷
6↓ 安全上限取决于 7这些机制各自的设计、成熟度、历史漏洞
安全上限最终由这些内核机制决定,dsh 插不了手,说到底还是开头那句官方概括里的同世界:沙箱进程与宿主共享文件系统和内核,dsh 没有在两者之间砌墙,只是把命令交到了内核
手上。
既然拦住写入这件事交给了内核,dsh 自己要扛的,就只剩这次交接的两端:
交不出去时(失败关闭,fail closed):没有可用的内核机制就抛异常,绝不把命令裸着跑出去。官方的措辞很硬,对受限策略而言,把命令悄悄不加约束地放过去永远不合法
(silent unconfined passthrough is never legal)。
交出去之后(报告执行到什么程度):Windows 因受限令牌必须保留 Everyone、NTFS 硬链接会让路径指向同一文件,内核只能做到这个程度,就报 partial,不夸大;老版本
的 Landlock 接口也是这样——它管得住的动作不全。
但它防不住网络、进程可见性、任何非文件的效果,以及显式切到 danger-full-access 之后的一切。所以它的定位很清楚:隔离交给操作系统,dsh 自己只保证转交正确、报告准
确。
本讲小结
今天这一讲,我们把“进程沙箱到底是个什么边界”这个问题,从头到尾拆开了。
我们看清了进程沙箱与宿主共享内核和文件系统,只管对文件系统的改动;confine 按每次调用解析出的策略把命令包一层,四个机制各有一套拦法(Linux 的 bwrap 换视图、
Landlock 每次查,macOS 的 Seatbelt 照单判,Windows 的受限令牌换身份),消费方只认契约不认平台;而它的边界有多牢靠,最终取决于它委托的内核机制——没提供方就抛异常
不裸跑,管不全就报 partial,把管不住什么说得明明白白。
由调用方一厢情愿地假定。
这,就是进程沙箱的本质——把隔离交给操作系统,自己只问“这次调用的文件效果,我能承诺管住多少”,管不住的部分绝不假装管住了。
到这里,从 Tool 接入能力、seam 让实现可替换、流水线上的守卫,一直到进程沙箱的执行边界,能力这条线终于完整了。但所有这些调用都发生在一次会话里:模型怎么知道前面发生
过什么、长任务的状态存在哪儿、中途断了怎么接着跑?下一讲,我们回到这条主线,聊聊会话。
注:本讲 GitHub 链接
思考题
动手实操:sandbox-demo.ts 第 ① 段是 read-only 模式下往家目录写文件(变量 outside)。把命令里的目标换成 /tmp/_dsh_t.txt 再跑一次,换成 /dev/null 再跑
一次,对比两次退出码。对着 read-only 的 profile 想一想:为什么 /tmp 被拒、/dev/null 却放行?最后把模式改成 workspace-write 再写 /tmp,白名单里新加
的哪一条解释了这次的变化?
小改动:platform-demo.ts 顶部的 policy 是模块级常量,写死了 read-only。改成让 probe() 多接收一个 mode 参数、在函数内部用它构造 policy,三个平台都传
workspace-write 再跑。观察 darwin 那段 profile 多了什么;再看 linux 那段——它报的还是 SANDBOX_UNAVAILABLE 吗?这能说明“失败关闭”和“具体用哪种模式”之间是什么
关系?
欢迎把你的运行结果分享出来。如果你觉得这节课对你有帮助,也欢迎分享给其他朋友,我们下节课再见!
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。