资讯动态

局域网访问为何少一半配置页:DSH 的安全边界设计复盘

发布时间:2026/10/20 10:48:14 来源:尧图企业网站定制
局域网访问为何少一半配置页DSH 的安全边界设计复盘1. 引言一个诡异现象困扰了我很久同一台机器上的同一个应用用本机地址访问和用局域网地址访问看到的配置页数量不一样——回环地址 7 个局域网地址只有 3 个少的全是敏感能力终端、Agent 循环、子智能体、网页搜索。先后怀疑过缓存、窗口宽度、CSS 样式最后才发现这不是 bug是应用的安全边界设计。本文从源码层复盘这个机制帮你在以后再遇到局域网少功能时少走弯路。2. 概念/架构访问地址决定功能面访问地址判定结果持久化策略插件面板「官方」组http://localhost:3080/本机回环isLoopbacktruehost7 个智能体团队/自动授权审查/语音输入/终端/Agent 循环/子智能体/网页搜索http://192.168.x.x:3080/局域网远程isLoopbackfalsememory3 个智能体团队/自动授权审查/语音输入终端/Agent 循环/子智能体/网页搜索隐藏反复排查后确认不是缓存、不是窗口宽度、不是样式插件——是访问地址决定的。3. 问题/现象真实对比同一浏览器、同一会话、同一构建只换 hostname检查项回环地址局域网地址插件面板「官方」组7 个配置页3 个配置页终端 / Agent 循环 / 子智能体 / 网页搜索显示隐藏已安装插件组正常正常不受降级影响4. 根因源码级4.1 触发点persistence 判定设置客户端dsh-client-ui-settings/lib/client.jsL1509的关键一行constpersistencectx.remote.$host.isLoopback?host:memory;isLoopback true本机回环→ persistence host→ 完整isLoopback false局域网 IP→ persistence memory→ 降级4.2 回环判定只认 localhost / 127.x连接客户端dsh-client-connection/lib/client.jsL1333-L1337的判定函数functionisLoopbackHostname(hostname){if(hostnamelocalhost||hostname[::1])returntrue;constpartshostname.split(.);returnparts.length4parts[0]127parts.every((part)/^\d{1,3}$/.test(part)Number(part)255);}局域网 IP 不满足首段不是 127→ 判为远程。⚠️关键trusted-host 不影响此判定。就算启动时加了--trusted-host 192.168.x.x:3080它只影响浏览器信任的 API 权限不影响isLoopback 的持久化降级。这是两个独立的机制——我当时就栽在这里。从「访问地址」到「两套持久化策略」的完整判定流程如下访问 hostname │ ▼ isLoopbackHostname(hostname) 判定 │ ├── localhost 或 [::1] ────────────────▶ isLoopback true ├── 4 段且首段为 127如 127.0.0.1─────▶ isLoopback true └── 其余如 192.168.x.x───────────────▶ isLoopback false │ persistence isLoopback ? host : memory │ ┌──────────────────────────────┴──────────────┐ ▼ ▼ host 持久化 memory 持久化 完整功能面 敏感配置页隐藏4.3 降级效果敏感配置页按服务是否 serve隐藏设置壳客户端dsh-client-ui-settings-shell/lib/client.jsL182终端/Agent 循环/子智能体/网页搜索同款ctx.effect(()ctx.configForms.whileServed([BASH_NS,PWSH_NS],(served)ctx.slots.inject(plugins.item,()ctx.slots.register({...}))))whileServeddsh-client-ui-settings/lib/client.jsL1330-L1349逻辑constservednewSet(mirror.getSnapshot().view?.namespaces.map(vv.ns)??[])constwatchednamespaces.some(nsserved.has(ns))if(watched)offregister(served)// serve 了才注册卡片elseif(!watchedoff){off();offundefined}// 没 serve 就卸载memoryLAN模式下 bash / pwsh / subagent / web-search 的 namespace 不被 serve → 终端 / Agent 循环 / 子智能体 / 网页搜索 4 个配置页不注册 → 只显示 3 个无需服务条件的。从「LAN 访问」到「少一半配置页」的降级链路如下memory 模式LAN 访问触发降级 │ ▼ bash / pwsh / subagent / web-search 的 namespace 未被 serve │ ▼ whileServed 判定 watched false → 不注册卡片已注册则卸载 │ ▼ 终端 / Agent 循环 / 子智能体 / 网页搜索 4 个配置页隐藏 │ ▼ 插件面板「官方」组只剩 3 个 智能体团队 / 自动授权审查 / 语音输入5. 安全设计意图为什么这么设计隐藏的配置页为什么 LAN 下隐藏终端shellBash/PowerShell 执行能力远程暴露风险高Agent 循环控制 Agent 派发工具调用敏感子智能体递归层级/模型敏感网页搜索搜索提供方配置敏感核心设计默认把非本机回环访问视为不可信远程避免 shell 等能力从局域网被滥用。这是刻意的安全护栏思路与禁止监听 0.0.0.0完全一致——能力越危险暴露面越要收窄。6. 配置/方案实际使用指南场景用哪个地址效果在本机桌面操作http://localhost:3080/完整 7 配置页 全部功能从局域网访问http://192.168.x.x:3080/3 非敏感配置页功能正常管理自制插件两个地址都行已安装插件组始终显示不受降级影响token 与 cookie项行为token两个地址共用同一 token进程级cookie首次访问写 30 天 cookie之后直接开根路径失效清浏览器缓存 / 换机器需重新兑换7. 陷阱/根因常见误区我的踩坑记录#误判排除方法1以为是缓存问题无痕窗口测试还是 3 个 → 排除2以为是窗口宽度调试测矮窗口下回环地址 7 个全可见 → 排除3以为是样式插件误伤禁用后单列但仍 3 个 → 排除4以为 trusted-host 能解决不影响 isLoopback 判定 → 排除8. 总结/改进这次排查最大的收获现象奇怪时先怀疑设计而非故障。结论内容1地址决定身份——应用通过 hostname 判断你是不是本机本地 vs 远程两套策略2降级是故意的——危险能力在远程访问时隐藏是安全护栏不是 bug3两个机制别混淆——trusted-host 管 API 信任isLoopback 管功能面互不影响产品层面的思考这类按访问来源降级的设计在本地优先应用里越来越常见如浏览器扩展的 host 权限。它把安全决策从开发者自觉变成机制强制——远程就是低权限没有例外。理解它比修复它更重要。9. 参考代码位置文件位置内容dsh-client-ui-settings/lib/client.jsL1509persistence isLoopback ? host : memorydsh-client-connection/lib/client.jsL1333-1337isLoopbackHostname判定dsh-client-ui-settings-shell/lib/client.jsL182终端配置页 whileServed 注册dsh-client-ui-settings/lib/client.jsL1330-1349whileServed 实现dsh-web-app/lib/index.jsL83-89resolveLanTrusttrusted-host与 isLoopback 无关

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑