前言¶
在 DeepSeek Harness(DSH)里,智能体通过 web_fetch 拉取网页内容。内置的 @deepseek-ai/dsh-web-fetch-http 会在发请求前解析目标主机名,并要求 整组 DNS 答案(所有 A/AAAA)均为公网单播地址;只要有一个非公网地址就会报错,例如:
URL hostname "example.com" resolves to a non-public IP address
若本机使用 Clash/Mihomo、sing-box、Surge 等 fake-IP + TUN 转发,DNS 往往把几乎所有域名解析到保留网段(如 198.18.0.0/15、2001:2::/48),再由 TUN 把连接映射回真实目标。这类地址属于基准测试网段(IPv4 见 RFC 2544,IPv6 见 RFC 5180),内置 SSRF 守卫会在建立连接之前就拒绝 URL;而 curl 或普通 Node fetch 不检查解析结果,因此仍能访问。
社区插件 dsh-fakeip-http(维护者 Jayve,分类 admin-security)针对上述场景:在 不替换 web.fetchProvider=http、不把 synthetic 网段简单加入白名单的前提下,仅在内置守卫已判定 WEB_BLOCKED_URL 时,按策略接受与转发器一致的 synthetic 解析结果,并继续阻断回环、私网、链路本地、组播、文档用、保留地址以及 IP 字面量等目标。
本文为社区插件介绍;插件 README 标明为 unofficial community plugin,与 DeepSeek 无隶属或背书关系。
这是什么¶
dsh-fakeip-http 是 DSH 的 Cordis 补丁型插件(npm 包名 dsh-fakeip-http,当前资料中版本 1.0.1,许可证 MIT)。它找到内置 HttpFetchProvider 实例,包装其 resolveAddresses:先跑原有校验;仅当原校验因非公网解析抛出 WEB_BLOCKED_URL 时,再本地解析同一主机名,并在 整组答案 均落在用户配置的 synthetic CIDR、且主机名符合 fake-IP 策略时,返回这些 synthetic 地址供连接固定(pin)。TLS SNI 与 Host 仍使用原始主机名,以便 TUN 侧正确回映射。
目录页:https://www.skillhub.cn/plugins/Jayve/dsh-fakeip-http
源码与文档:https://github.com/Jayve/dsh-fakeip-http
工作原理(与内置守卫的关系)¶
决策路径可概括为:
web_fetch
│
▼
built-in SSRF guard ─── 公网真实地址 ──────────────▶ 行为不变
│
│ WEB_BLOCKED_URL
▼
fake-IP policy(本插件)
│
├─ 普通 DNS 主机名(非 IP 字面量、非本地/特殊后缀)
├─ 每个 A/AAAA 均为 synthetic
└─ 配置的 CIDR 不与 special-use 空间重叠
│
▼
pin synthetic ──▶ TUN 转发 ──▶ 真实目标
要点:插件 不会 新增「允许列表」条目;公网目标仍由内置守卫在第一道关口放行。策略失败时重抛 原始 错误,并附带简短诊断后缀。
安全边界(README 中的不变量)¶
下列行为在资料中有明确说明,安装前建议通读仓库内 docs/security-model.md(若需细节):
| 情况 | 行为 |
|---|---|
| 公网真实地址 | 原校验通过,不进入 fallback |
| 回环 / RFC 1918 / CGNAT / 链路本地 / 组播 / 文档用 / 保留等 | 拒绝;fallback 只接受配置的 synthetic 块 |
IP 字面量(如 http://198.18.0.1/) |
始终拒绝,不进入 fallback |
localhost、*.local、*.lan、*.internal 等及单标签名 |
不参与 fake-IP |
| 答案混合 fake-IP 与真实地址 | 视为歧义/污染,拒绝 |
| 配置的 CIDR 与 special-use 重叠 | 加载时拒绝并记录日志,不安全项被排除 |
| 显式 HTTP(S) 代理、每次重定向跳 | 仍按原逻辑解析与校验 |
代码里 enabled 默认为 false;随包发布的 cordis.patch.yml 会显式设为 true。只安装包而不应用补丁时不会静默放宽守卫。
环境与依赖¶
- DeepSeek Harness Desktop 或 Web:0.2.1-rc.2 至 0.2.x(
package.json中dsh引擎:>=0.2.1-rc.2 <0.3.0)。 web.fetchProvider保持http(默认)。- 本机 DNS 经 fake-IP 转发器解析,且你知道其 synthetic 网段(与
cidrs配置一致)。
Node 引擎要求:^22.19.0 || >=24.0.0。包为纯 JavaScript,无依赖、无构建步骤。
安装与启用¶
按使用场景选择 profile(Web 常用 web,桌面端常用 desktop)。
从 npm:
dsh plugin --profile web add dsh-fakeip-http
从 GitHub:
dsh plugin --profile web add github:Jayve/dsh-fakeip-http
桌面端示例:
dsh plugin --profile desktop add dsh-fakeip-http
安装后 重启 Harness 进程,检查合成配置是否包含本插件层:
dsh --profile web --dump-config
在输出中查找 # == dsh-fakeip-http 以及 enabled: true 的 fake-IP 配置行。
卸载:
dsh plugin --profile web remove dsh-fakeip-http
移除 bundle 会去掉其 patch 层,不会改动 web.fetchProvider。若曾用本地开发包 @local/dsh-fakeip-http(同一 row id fakeip-http),应先移除再安装正式包,避免重复 id。
配置¶
默认片段(随 cordis.patch.yml 下发,可按转发器实际网段修改):
- id: fakeip-http
name: dsh-fakeip-http
config:
enabled: true
cidrs:
- 198.18.0.0/15
- 2001:2::/48
enabled:是否接受 synthetic 答案;代码默认false,补丁中常为true。cidrs:允许接受的 synthetic 网段;默认含198.18.0.0/15与2001:2::/48。与 special-use 重叠的块会被拒绝;若全部被拒绝则回退到默认。
改 cidrs 前应对照转发器文档,例如 Clash/Mihomo 的 dns.fake-ip-range(常见 198.18.0.1/16)、sing-box 的 inet4_range / inet6_range 等(README 中有对照表,截断处未列全的以仓库 README 为准)。
典型用法与验证¶
在新会话中测试外网主机名(应经 fake-IP 解析并由 TUN 转发):
web_fetch https://example.com
期望:HTTP 200 与页面正文。
再确认守卫仍严格:
web_fetch http://127.0.0.1:1203/ # 仍应失败(回环)
web_fetch http://198.18.0.1/ # 仍应失败(IP 字面量,无 fallback)
web_fetch http://10.0.0.1/ # 仍应失败(私网)
适用场景与注意¶
适合: 已在 DSH 上使用 fake-IP DNS + TUN 的开发者或运维,需要智能体 web_fetch 与系统代理行为一致,又不愿关闭或绕过内置 SSRF 校验。
注意:
- 插件以 当前 dsh 进程权限 运行;安装前请自行审阅源码与 MIT 许可证,并确认
cidrs与本地转发器一致,避免误配 special-use 重叠(无效项会被剔除,但理解策略仍必要)。 - 这不是「把
198.18.0.0/15加入白名单」,而是有条件的 DNS 解析 fallback;IP 字面量访问 synthetic 地址仍会被拒绝。 - DSH 生态强调「一切皆插件」;SkillHub 等社区目录为独立站点,并非 DeepSeek 官方应用商店。
结尾¶
dsh-fakeip-http 在 fake-IP 网络下补齐 web_fetch 与 TUN 转发器的协作,同时保留对本地与特殊用途地址的阻断。需要安装说明、安全模型与 CI 状态时,以 GitHub 仓库 README(含 简体中文)为准。