dsh-sandboxie-redirect
Verified@lone-wolf-akela/dsh-sandboxie-redirect · v0.3.4 · MIT · Web UI
DSH bundle adding a copy-on-write permission preset: shell commands run inside a per-workspace Sandboxie box, so writes outside the workspace land in the box's copy while the real disk is untouched.
Install
dsh plugin add @lone-wolf-akela/dsh-sandboxie-redirect Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-sandboxie-redirect
English: README.md
给 DSH 增加第四种权限预设 「写时复制」 的 bundle:shell 命令跑在本工作区专属的 Sandboxie 沙盒里,工作区内的写入照常落到真实磁盘;工作区外的写入、修改、删除不会失败,但只落进该沙盒的副本。原有三个预设(只读 / 仅工作区 / 完全权限)行为不变。
┌─ 你的 DSH 会话 ───────────────────┐
│ 文件策略:写时复制 │
│ │
│ shell 命令 ──▶ Sandboxie 沙盒 ───┼──▶ 工作区内写入 → 真实磁盘
│ (在沙盒内) (每工作区一个) ┼──▶ 其它位置写入 → 沙盒副本
│ │ 其它位置删除 → 副本里只留删除标记
│ 读/写/编辑 ──▶ 宿主进程(盒外) ┼──▶ 规则不变:工作区内可写,区外拒绝
└───────────────────────────────────┘
- 仅 Windows,且需要先装 Sandboxie-Plus(其服务须在运行)。
- 接入方式是权限预设,不修改 DSH 应用本体。
- 用途是防误写、可撤销、保持系统目录干净。不用于防御恶意程序——Sandboxie 不提供该保证,而插件与承载它的应用拥有同等权限。
术语
| 词 | 含义 |
|---|---|
| 真实磁盘 | 系统里实际存放文件的地方(例如 C:\Users\…)。 |
| 沙盒 / 盒 | Sandboxie 创建的隔离环境;本插件为每个工作区创建一个。 |
| 副本 | 沙盒对"工作区外文件改动"的私有存储(位于沙盒根下),与真实文件分开。 |
| 盒内 / 盒外 | 写时复制下,shell 命令在盒内运行;DSH 应用本体与它的文件工具(读/写/编辑)在盒外。 |
| 合并视图 | 盒内命令读文件时,沙盒把副本内容叠加到真实文件上呈现。 |
| SandMan | Sandboxie-Plus 自带的图形管理界面,可查看、恢复、删除沙盒。 |
安装
前置条件:Sandboxie-Plus(源码)。安装后它的服务须在运行;本插件的所有沙盒都由 Sandboxie 创建与管理。
装在哪儿都行,不需要配置。 插件不假设 Sandboxie 在某个固定目录:它先读 Sandboxie 自己的注册表项(SbieSvc 服务的 ImagePath 最权威——能建沙盒的安装必然有它,其次是驱动服务与卸载项),再看 %ProgramFiles%\Sandboxie-Plus 等常规位置与 PATH,最后才按名字扫一遍常见父目录与各固定磁盘根目录,找含 SbieDll.dll 的文件夹。装在别的盘、用户目录、便携目录都可以。只有全部落空时才会报 "not installed",此时用 DSH_SBIE_DIR 直接指定(见环境变量)。
DSH 自己的安装目录同样不假定。 启动器要用的 koffi.node 是随 DSH 一起装在它 resources\app.asar.unpacked 里的,而启动器是普通 Node 进程(没有 process.resourcesPath)。插件会自己定位 DSH:先看运行启动器的那个 node(桌面应用自带的运行时就在安装目录里,这条路径本身就指回安装位置),再看安装器留下的卸载项,最后才是常规目录与 PATH。DSH 装在别的盘也能正常工作。
本包是 DSH 的 bundle(自带配置层),装进去就自动挂载,不需要手改 profile 文件。
# 装进某个 profile(不存在会创建),并自动加入该 profile 的 bundle 列表
dsh plugin --profile <profile> add @lone-wolf-akela/dsh-sandboxie-redirect
# 先不启动,核对配置层,再启动
dsh --profile <profile> --dump-config # 应看到一行 "# == @lone-wolf-akela/dsh-sandboxie-redirect"
dsh --profile <profile>
也支持本地目录 / 离线 tarball:
dsh plugin --profile <profile> add C:\path\to\dsh-sandboxie-redirect # 本地 checkout(link 方式)
dsh plugin --profile <profile> add .\lone-wolf-akela-dsh-sandboxie-redirect-0.3.1.tgz
哪个 profile 用哪条路? 正在运行的桌面应用独占的 profile(
desktop)会被 CLI 拒绝操作(profile "desktop" is managed exclusively by the Electron application)。这种 profile 请在应用内装:设置 → 插件 → 添加 bundle,填上面的包名。其它 profile 用 CLI 即可。
装完重启客户端,在权限下拉里选择 ❐ Copy-on-write 写时复制。沙盒名称会在第一条 shell 命令之后出现在标题栏。
从"手工挂载"迁移
早期版本是"把目录拷到 ~/.dsh/plugins/dsh-sandboxie-redirect + 在 ~/.dsh/profiles/<profile>/cordis.patch.yml 里加行"。切到 bundle 通道前必须先删掉那些行:同一个 dsh.client 包有两个活动 loader 行会让启动直接失败("resolves from multiple active Loader sources")。要删的是:name 为绝对路径、以 lib\provider.mjs 结尾的那一行,以及本插件加的 sandbox、permission 两行。仓库里的 tools/install.mjs 仍然保留给手工通道使用,且必须在沙盒外运行。
功能
写时复制预设
| 位置 | 行为 |
|---|---|
| 工作区内的写入、修改、删除 | 直接作用于真实磁盘 |
| 工作区外的写入、修改 | 命令报成功,但改动只落在该工作区的副本里;真实磁盘不受影响 |
| 工作区外的删除 | 真实文件保留;副本中只记录删除标记 |
DSH 的文件工具(读/写/编辑)在盒外运行,仍按「仅工作区」判定:工作区内可写、区外拒绝。想读"沙盒视角"的文件,用 shell 命令读(见下文「读侧分歧」)。
该预设下,会话的策略文本会追加一段说明,告知模型本模式的行为与注意事项,不必让模型自己推断。
标题栏的沙箱名称
写时复制模式下,标题栏显示当前沙盒名称(如 dsh_able_willow,悬停可见副本根路径)。它只在两个条件同时满足时出现:该会话的预设是写时复制,且该工作区确已创建沙盒。因此第一条命令后才出现,切换预设或清理沙盒后消失。
权限下拉图标
「写时复制」在下拉与底部按钮中带有图标(复制双矩形),随主题配色。预设名以 ❐ 开头也是同一个原因:出厂下拉的图标来自一张封闭的 id→图标表,自定义预设没有图标,而名字是唯一一定渲染的表面。
sandbox_clear 工具
会话内可用 sandbox_clear 查看或清除本工作区的副本:mode: "inspect" 仅查看(文件数、占用),mode: "clear" 删除副本与配置。任何权限模式下都可用,且只能操作 Sandboxie 认定属于本工作区的沙盒。另有诊断用的 mode: "status":它报告本会话投影登记的状态,用来分辨"投影没被驱动"和"客户端没收到"——标题栏的沙箱名称不显示时先看它(0.3.3 起才真正可用)。
用户注意事项
sandbox_permissions的参数描述不是为本预设写的。 那段文字由 DSH 统一生成、所有预设共用,读起来像"被拒之后的补救"——而写时复制下区外写入不会被拒(它会成功落进副本),所以既不会出现拒绝标记,也没有"被拒的命令"可重试。会话的策略文本会明确说明这一点:升权是"这一次调用直接作用于真实磁盘"的主动手段,不是失败的后续动作。- 读侧分歧(重要):同一个路径,不同工具看到的内容可能不同。
- shell 命令在盒内运行,读到的是合并视图:如果之前有命令在工作区外写过该文件,命令看到的是副本里的版本。
- DSH 的文件工具在盒外运行,读到的一直是真实磁盘上的版本。
- 因此:验证"命令在工作区外写了什么"用 shell 命令读;验证"真实磁盘有没有被改动"用 DSH 的文件工具(或资源管理器)读。
- 副本位置:普通路径在
<沙盒根>\drive\<盘符>\<路径>;用户目录下的路径在<沙盒根>\user\current\<相对路径>。Sandboxie 自己配置的沙盒目录会被自动跟随(FileRootPath,盒级或[GlobalSettings],含%USER%/%SANDBOX%展开);需要时可用DSH_SBIE_ROOT覆盖(见环境变量)。 - 磁盘占用:副本不自动回收,会持续累积。
C:\Windows\Temp:修改其中已存在的文件可能被拒(Sandboxie 原生行为,非本插件所致);新建与删除不受影响。- 并发:同一工作区的并发命令共用一个沙盒,互相可见。
- 升权:写时复制下,若某命令需要更大权限而发起升权,该次调用会整体在盒外运行;下一条命令回到盒内。升权不是"把某个文件变真"的手段。
- 写回:副本改动默认不回灌真实磁盘。需要恢复时在 SandMan 中查看并恢复;
sandbox_clear只做删除,不做写回。 - 卸载 bundle 只会移除预设与配置行,沙盒与副本仍留在磁盘上。想收回空间就先清理(
sandbox_clear,或--manage clean)。
手动管理沙盒
node bin\dsh-sbie-run.mjs --manage list # 列出受管沙盒
node bin\dsh-sbie-run.mjs --manage clean "<工作区>" # 清理某工作区的沙盒
node bin\dsh-sbie-run.mjs --manage delete-box <沙盒名> # 删除指定沙盒
--manage 必须在盒外运行(普通终端,或 danger-full-access 会话):盒内进程看不到沙盒列表。同样的操作也可以在 SandMan 里做。
环境变量
全部可选,都是"逃生阀"而非配置面。
| 变量 | 作用 |
|---|---|
DSH_SBIE_DIR |
Sandboxie 安装目录(含 SbieDll.dll 的那个文件夹)。通常不需要:上面的自动查找会先从注册表、常规位置与 PATH 里找。装在非常规目录且自动查找没命中时用它。 |
DSH_SBIE_NODE |
跑启动器的 node.exe。插件会自动去找(桌面应用自带的运行时,其次 $DSH_HOME/dsh-runtimes),找不到时用它指定。 |
DSH_SBIE_ROOT |
覆盖沙盒根。通常不需要:Sandboxie 配置的 FileRootPath 会被自动跟随。默认 %SystemDrive%\Sandbox\%USERNAME%。 |
DSH_SBIE_LOG_DIR |
诊断日志目录。默认 $DSH_HOME/state/dsh-sandboxie-redirect。 |
DSH_SBIE_INI |
要读取的 Sandboxie 配置文件。默认 %SystemDrive%\Windows\Sandboxie.ini。 |
DSH_SBIE_KOFFI / DSH_SBIE_KOFFI_ROOT |
启动器要用的 koffi.node(或含它的目录)。通常不需要:DSH 的安装位置会被自动定位(见安装)。 |
DSH_SBIE_BOX / DSH_SANDBOX_ROOT |
由插件在命令内注入;"我在哪个盒里"以它们为准,永远不要用工作区路径去推导盒名。 |
诊断文件:上述日志目录下的 provider.log、host.log、tool.log。host.log 上限 512 KB,只记状态迁移。
实现要点(简述)
- bundle 层禁用原
sandbox行(@deepseek-ai/dsh-sandbox-local)并插入本包的 provider,它继承原 provider:只把「写时复制」这一预设分流,其余模式一律委托原 ACL 路径。用runnerCommand做不到这件事——那会作用于所有模式。 - 同一层把
copy-on-write合并进permission的预设目录,保留之前各层贡献的条目。 - shell 命令经
bin/dsh-sbie-run.mjs——一个持有 Sandboxie FFI 的纯 Node 子进程。Sandboxie 由服务创建进程并丢弃标准句柄,因此 stdio 走回环 TCP + 长度前缀帧回传。 - 盒名由工作区路径确定性派生成词对(
dsh_<形容词>_<名词>),不需要状态文件;冲突时按候选序列顺延,且只有当 Sandboxie 配置表明该工作区确实拥有某盒时才采用它。 - 只有"加载 harness 包失败"是致命错误,此时注册的 provider 会失败关闭:拒绝执行命令,而不是不加限制地执行。
开发
环境准备与开发回路见 CONTRIBUTING.md,架构与踩过的坑见 AGENTS.md。常用命令:
npm test # 单元 + 标题栏投影 + bundle 层校验(不需要 DSH、不需要 Sandboxie)
npm run test:acceptance # 验收:真沙盒、真重定向(须在盒外、Medium IL)
npm run pack:check # 看发布的 tarball 里会有什么
安全问题见 SECURITY.md。
许可
MIT —— 见 LICENSE。