DeepSeek Harness Hub
← 返回列表

手机安全隧道frederico-kluser/deepseek-harness-mobile

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

用密钥链接在手机上安全访问本地编码界面

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/28 · 已提供中文文档
综合分
28.8
GitHub 分
28.8
用户评分
★ Stars
1
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add frederico-kluser/deepseek-harness-mobile
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cosmokit@deepseek-ai/dsh-home-paths@deepseek-ai/dsh-host-frontend-static@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-invariants@deepseek-ai/dsh-subprocess@deepseek-ai/schemastery
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-guard-messenger

CI
npm version
npm downloads
OpenSSF Scorecard

dsh-guard-messenger

在手机上使用你自己的 DeepSeek Harness——完整的 Web UI,真正用于编码——同时绝不将绑定扩展到 loopback 之外:隧道终止于 127.0.0.1(本地访问直接打开),而通过隧道进入的只有那些在链接 ?key= 中持有密钥的人(密钥由机器人发送)——你可以通过 Telegram 或 Discord 开启和关闭访问。

Demo

安装(一行命令)

dsh plugin --profile web add dsh-guard-messenger

通过 git / tarball 安装: 如果你从 git 安装(pnpm add ),
生命周期 prepare(pnpm run build:all)会自动生成 lib/client.js
和 dist/——即 harness 所挂载的 bundle(exports["./client"] → lib/client.js)。
没有这些产物,客户端激活将抛出 MissingClientBundleError。
参见 docs/PANEL-TELEGRAM.md。

威胁模型,5 行说明——在任何功能之前

这个插件出于选择,暴露了一个能在你机器上执行代码的代理。在继续之前,请阅读以下内容:

1. TLS 终止于 Cloudflare 的边缘。 明文(提示词、代码、响应)经过第三方——这正是实现 WAF/Access/缓存的原因。它不是端到端的。
2. 隧道 URL 是公开的,且不是秘密。 保护它的是链接中的密钥 ?key=,而不是地址的隐蔽性。
3. Cloudflare Access 不能放在 quick tunnel 前面。 在 .trycloudflare.com 上,所有认证都必须在应用程序内部完成。
4. Quick tunnel* 没有 SLA——它“仅用于测试和开发”。
5. 这不是“无需思考的默认安全”。 我们缩小了攻击面,通过密钥/会话对边缘进行了认证,并给了你关闭按钮;我们并没有消除这一类风险。

详情以及每项缓解措施的作用:docs/THREAT-MODEL.md。

安全模型(代码实际保证的内容)

对保证的诚实解读——每一行都指向实现它的代码;这里没有“无需思考的默认安全”,只有攻击面缩减和认证。

| 属性 | 方式 |
| --- | --- |
| 绑定绝不会被扩展 | assertSecureBind 在加载时拒绝 0.0.0.0/::,并以显眼的方式失败(src/config/bind.ts) |
| 本地访问直接打开 | 在 127.0.0.1 上,DSH 无屏障响应;保护适用于隧道表面,而非回环(src/tunnel/proxy.ts) |
| 通过隧道仅凭会话或链接中的密钥进入 | 代理对所有内容进行认证:会话(cookie)或链接中的 ?key=;除此之外 → 401 无质询(src/http/gate.ts、src/session/link-token.ts) |
| 来源和 Host 优先 | trustedRemotes(无凭据则 403)和 Host 逐字节比对以防 DNS 重绑定(src/http/gate.ts:15、src/http/host-header.ts) |
| 链接中的密钥可重复使用,可通过轮换撤销 | CSPRNG 256 位;仅以 SHA-256 摘要形式保存;可重复使用直到 /rotacionar(生成新密钥,使会话失效并终止活动连接——WebSocket 和进行中的流会立即断开)或关闭隧道(src/session/link-token.ts、src/tunnel/proxy.ts) |
| 401 是无质询的 | 纯文本,无登录质询(浏览器弹窗已移除)——绝不在提示/表单中要求密码(src/http/responses.ts、denyUnauthorized) |
| 暴力破解有上限 | 第 5 次失败开始延迟;累计 100 次失败会关闭暴露(受限模式),仅回环可通过,且重启无法绕过(src/ratelimit/) |
| 密钥验证为时间恒定 | 摘要使用 timingSafeEqual 比较;令牌在 JSON/inspect 中被脱敏(src/session/link-token.ts、test/security/timing-constante.test.ts) |
| danger-full-access 被否决 | 禁止提权,作为纵深防御被拒绝(src/permissions/deny.ts) |
| 只有配对的所有者才能操控机器人 | 双轴允许列表(userKey/chatKey),默认拒绝(worker/surface/auth.ts) |
| 不保证的内容 | TLS 在 Cloudflare 边缘终止(明文经过那里);隧道 URL 不是秘密;持有链接者可在轮换前访问;?key= 通过查询字符串传输(对中间人可见)——所有者承担的权衡;提示注入仍被接受——设计决策见 docs/THREAT-MODEL.md §4 和 §5.1 |
核心张力,由我们先说出,以免他人代我们说

该项目旨在将 DSH 锁定在回环上。此插件也将其暴露在互联网上。看似矛盾——而诚实的表述是这样的:

绑定仍然在 127.0.0.1,DSH 在那里直接打开(无需登录)。变化在于,现在存在一个受监督的子进程(cloudflared),将 Cloudflare 边缘的流量引导至一个在边缘进行认证的专用代理(会话或 ?key=)。这与 --host 0.0.0.0 不同:本地套接字从未被扩大,暴露是选择性加入、临时的,并可通过一条命令撤销——而保护 /api、SPA 回退和 WebSocket 握手的是该代理,而非回环。
不变的是:逻辑攻击面在扩大。以前,攻击者需要访问机器;现在,通过隧道,他需要链接中的密钥(或一个被盗的会话)。我们把“不可达”换成了“可达且在边缘处经过身份验证”——无需登录,无需输入密码。这种交换随时可以通过关闭按钮逆转(而密钥则通过 /rotacionar 逆转)。

不接受这种交换的人应该使用 Tailscale 或 SSH——我们在 docs/TUNNEL.md 和下面的“何时不使用”一节中更平静地说明了这一点。

它做什么(以及为什么)

1. 保护隧道,而不是 loopback。 DSH 直接在 127.0.0.1 上打开(无需登录);暴露它的是一个专用代理,它对来自互联网的所有内容进行身份验证——/api、SPA 的回退以及 WebSocket 握手。它在加载时拒绝 loopback 之外的绑定地址,并拒绝被禁止的权限(danger-full-access)。它解决了上游讨论 #853 中的攻击面问题。
2. 从不向任何人索要密码。 通过隧道的访问要么通过会话进入,要么通过链接中的密钥 ?key= 进入(CSPRNG,256 位,磁盘上的摘要)。该密钥在 /rotacionar 之前可重复使用(/rotacionar 会生成新密钥、使会话失效并主动关闭已打开的连接——持有旧链接的人会立即掉线,包括 WebSocket),或者直到关闭隧道。401 是无登录挑战的——没有提示,也没有登录表单。
3. 启动一个临时隧道,以便你通过手机访问,其 TTL 会自动将其关闭,还有一个故障关闭探测,防止出现“裸”隧道(背后没有经过身份验证的代理)。
4. 通过 Telegram、Discord 或面板开启/关闭——手动终止按钮。
5. 通过机器人触发 harness 代理——使用允许列表中的一个技能和一个提示,所有者可以让一个 DeepSeek Harness 子代理在自己的机器上工作(/agente),跟踪运行(/agentes)并取消(/parar-agente)。该调度在主机上执行代码:需要两步确认,并且代理以 harness 的权限运行——绝不使用机器人的令牌。完整手册:docs/AGENTS.md。

机器人:UI 按钮和自动链接

在 DSH 的 UI 中有机器人按钮(/__guard-ui),其状态 OFFLINE/ONLINE
与运行时一致:
- OFFLINE → 点击后会显示当前活动提供商的连接说明
(Telegram:在 @BotFather 中创建机器人;Discord:在 Developer
Portal 中创建应用——见 docs/ONBOARDING-DISCORD.md)、dsh-guard-setup --pedir-token、
--parear、发送 /parear ;按照该分步指南操作的人实际上会
让机器人上线;
- ONLINE → 显示使用提示。

配对之后(Telegram 见 docs/ONBOARDING-TELEGRAM.md,
Discord 见 docs/ONBOARDING-DISCORD.md——两个提供商中的命令相同),
机器人的控制命令如下:

| 命令 | 作用 |
| --- | --- |
| /ligar | 启动隧道,当状态变为 READY 时,自动发送带有 ?key= 密钥的链接 |
| /desligar | 关闭隧道(并撤销密钥) |
| /acessar | (重新)发送带有密钥的链接 |
| /rotacionar | 生成新密钥,使会话失效并终止活动连接(WebSocket/流)——立即撤销旧访问权限 |
| /status · /emergencia | 状态、kill switch |
| /agente · /agentes · /parar-agente | 触发、列出和取消 harness 代理——见下文 |

/ligar 发送的链接是
https:///?key=:链接中的密钥用于认证隧道,在轮换(或关闭隧道)之前可重复使用,且当密钥有效时,会被兑换为一个会话,浏览器随即重定向到干净的 URL(不带 ?key=)。
从不要求输入密码——访问通过会话或链接中的密钥完成,本地访问直接打开。

为什么密钥可能出现在聊天中(且这是预期行为): ?key= 是认证机制,而 bot 是投递渠道。它是链接密钥,不是“永久密码”——访问无需输入任何密码。

上述每一项承诺都对应到履行它的代码行:见 docs/ARCHITECTURE.md。

代理:通过 bot 触发 harness 技能

代理调度器(docs/AGENTS.md——完整手册)将 bot 连接到 harness 的
ctx.subagents:所有者选择一个允许列表中的技能并编写一个
提示词,宿主会生成一个进程内子代理(全新会话,父级上下文为零),它在自己的机器上工作,结果会发送到聊天中。

| 命令 | 作用 |
| --- | --- |
| /agente   | 打开两步确认并触发代理(显示的提示词即为实际发送的内容) |
| /agentes | 列出运行记录:•  —  —  (+ 模型摘要) |
| /parar-agente  | 取消一次运行(id 会显示在 /agentes 中) |

为何如此繁琐:调度会在你的机器上执行代码。这是最会增大 bot 暴露面的操作——因此需要两步确认(宿主 nonce,与 /ligar 相同)。而且被触发的代理以 harness 的权限运行,绝不会收到 bot 的 token,也不会收到此插件的任何凭据(S3):请求只携带渲染进规范  块的技能 + 你的提示词文本。运行记录按设计是临时的:只存在于内存中——DSH 重启会取消一切(按 LIFO 执行 dispose),列表会重新从空开始。若未声明允许列表(config.agents.skills),任何代理都无法被触发——从构造上就是 fail-closed。

消息传递提供商

bot 的 worker 是对提供商中立的:核心(路由器、允许列表、配对、outbox)
位于 worker/surface/,每个渠道都隔离在自己的适配器中:
worker/providers/telegram/(唯一加载 grammY 的地方)和 worker/providers/discord/
(自有 WebSocket 网关,无 SDK)。启动时通过 DSH_GUARD_PROVIDER 读取活动提供商
(config.worker.provider,默认 telegram);令牌在 Telegram 中是 TELEGRAM_BOT_TOKEN,在 Discord 中是
DISCORD_BOT_TOKEN —— secrets.env 保存这两行,而 dsh-guard-setup
知道哪个是当前活动提供者的。

添加一个新提供者(WhatsApp、Matrix……)就是实现中立的契约
ProviderAdapter 并在 registry 中注册它。完整手册——架构、逐类型契约、
各提供者及其限制的表格,以及新提供者的分步检查清单——位于
docs/PROVIDERS.md,支持性技能(skills)位于
.agents/skills/dsh-provider-bot 和 .agents/skills/dsh-telegram-provider。

一个请求如何流转(8 行架构)

手机(浏览器)
│  打开 bot 发送的链接:https:////?key=   (密钥通过 query 传递)
▼
❨ Cloudflare edge ❩   TLS → HTTP/2 → WebSocket ;TLS 在此终止(明文经过边缘)
▼
cloudflared — quick tunnel(仅出站连接,无账户,无 SLA)
▼  http://127.0.0.1:3080   (隧道终止于 loopback;本地 socket 并未被放宽)
plugin(专用代理——只有隧道经过这里)
│  在边缘认证:会话(cookie)或有效的 ?key= → 换取会话(302 到干净 URL)
│  403 来源/ Host 不在 allowlist 中 · 401 无质询(无登录) · 200 带会话
▼
DeepSeek Harness Web UI — bind 锁定在 127.0.0.1(绝不 0.0.0.0)

图中隐藏但具有决定性的一点:本地访问直接打开(无屏障)——认证只存在于隧道代理中。链接中的密钥由机器生成(CSPRNG,256 位),在磁盘上仅以摘要形式保存,在轮换前可重复使用,且 ?key= 通过 query 传递(对中间人可见)——这是 expose-port 模型所承担的取舍。拒绝在 loopback 之外 bind 发生在加载时,并伴有响亮的失败——参见 docs/ARCHITECTURE.md 中的模块地图。

快速开始(5 条命令)

1. 安装插件(一行;自动激活 Bundle 清单)
dsh plugin --profile web add dsh-guard-messenger

2. 运行 DSH —— 本地访问直接打开(无登录)
dsh web

3. (可选)连接 bot:dsh-guard-setup + /parear(Telegram 见 docs/ONBOARDING-TELEGRAM.md
,Discord 见 docs/ONBOARDING-DISCORD.md);然后,在 bot 中,
/ligar 发送带密钥 ?key= 的链接

4. 确认本地访问能打开(DSH 直接响应);无密钥的边缘
返回 401 —— 见 docs/INSTALL.md 第 3 步
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3080/

5. 关闭/卸载
dsh plugin remove dsh-guard-messenger

examples/minimal 是一个可安装的最小示例,带有已记录的验收标准(本地直接打开 / 无 ?key= 的边缘返回 401 / 带链接或会话返回 200 / 结束时无任何进程)。

何时不要使用它
- 时间 / 多用户。 这是一个单所有者插件:Telegram 或 Discord 的 userKey/chatKey 允许列表(数字 id,绝不是用户名)以及链接密钥。没有 RBAC,也没有多租户审计。
- 生产 / 正常运行时间。 用 Cloudflare 自己的话说,quick tunnel “仅用于测试和开发”,并且“我们不保证任何 SLA 或正常运行时间”。
- 谁需要合规。 TLS 在 Cloudflare 边缘终止;明文会经过那里。这不是端到端加密。
- 谁想要“默认安全、无需思考”。 这里不存在这种东西。你正在暴露一个带 shell 的 agent;该插件减少了攻击面并提供了 kill switch,但并没有消除这一类别。
- 公司机器。 trycloudflare.com 有已记录的恶意软件声誉,许多网络/EDR 会阻止或标记 cloudflared。

替代方案(诚实的比较)

没有任何替代方案被呈现为糟糕;其中一些在多个维度上更好。价值在于组合,而不是逐项取胜。

| 替代方案 | 它更擅长什么 | 代价是什么 | 何时选择它而不是这个插件 |
| --- | --- | --- | --- |
| Tailscale (+ Funnel) | 真正的私有网络(WireGuard),按设备身份 | 在手机上安装客户端和账户 | 几乎总是,如果你接受安装客户端 |
| ngrok | 即时的人体工学;免费计划中在边缘进行认证(quick tunnel 没有) | 免费限制;URL 会变化 | 当你今天想要边缘认证时 |
| SSH + tmux | 没有新的 HTTP 攻击面,真正的端到端加密 | 不是 Web UI;在手机上写代码是折磨 | 当你只需要看日志并杀掉进程时 |
| code-server / VS Code tunnels | 浏览器中的完整编辑器 | 不是 DSH;并行运行 | 当目标是编辑文件,而不是驱动 agent 时 |
| dsh-webui-auth | 在传输层对 WebUI 进行认证 | 只做认证;没有隧道、没有 bot、没有开关 | 如果你只想要认证,就用它 |
| Named tunnel + Cloudflare Access | 在到达你的机器之前进行认证 | 需要在 Cloudflare 上有 DNS 的域名 | 只要你有域名(更优路径) |
| 什么都不用(纯 loopback) | 暴露风险为零 | 无法从手机使用 | 只要你确实不需要时 |

总之:这不是“又一个隧道”——它是单所有者的完整流程(onboarding → 链接中的密钥 → 临时隧道 → 手机上的链接 → 关闭按钮),绑定锁定在 loopback,本地访问开放,无需登录。

兼容性

上游 @deepseek-ai/dsh 的支持范围:0.1.0-rc.7 .. 0.1.1-rc.1(N/N-1 策略)。完整表格——插件版本 × rc 范围 × 状态——位于 docs/COMPATIBILITY.md,它是从 dsh-compat.yml 生成的(绝不手动编辑)。

注意 registry:@deepseek-ai/dsh- 子包的 latest 标签指向最旧的发布,而不是最新的。请显式固定版本。

端到端验证(测试套件真正证明了什么)
从仓库中真实测试套件(test/e2e/、test/security/、test/integration/)出发的高层矩阵
——按文件引用。这些是 CI 实际运行的检查,而非承诺;每个层级的细节以及如何运行
见 docs/TESTING.md。

| 检查项 | 预期 | 验证位置 |
| --- | --- | --- |
| 本地访问(127.0.0.1)到 /、/api/state、升级 | 直接打开,200/101,无挑战(DSH 不保存在回环上) | test/integration/http/barreira.test.ts(第 1 波) |
| 通过隧道 URL 请求,无会话且无 ?key= | 401 纯文本,无挑战(无登录弹窗) | test/e2e/tunnel-cycle.test.ts、test/security/desafio-401.test.ts |
| 通过隧道 URL 使用有效的 ?key= | 302 重定向到干净 URL(+ 会话 Set-Cookie);token 不出现在日志中 | test/unit/http/gate.test.ts、test/unit/tunnel/proxy.test.ts |
| 通过隧道 URL 使用无效的 ?key= | 401 无挑战,无 302 | test/unit/http/gate.test.ts、test/security/desafio-401.test.ts |
| 通过隧道 URL 携带有效会话(cookie) | 200,响应来自原始分发 | test/e2e/tunnel-cycle.test.ts |
| 来自陌生源的 WebSocket 握手(例如 https://evil.com) | 拒绝——精确的 Origin 允许列表(CWE-1385) | test/security/websocket-origin.test.ts |
| 非已发布的 Host / DNS 重绑定 | 边界处 403,逐字节 | test/security/host-header.test.ts、test/e2e/tunnel-cycle.test.ts |
| 被绕过的路由(/..//api、%2e、重复斜杠、/__guard/API/login) | 统一 401/403/404,绝不透传 | test/security/path-bypass.test.ts(ADV-001..020) |
| 第 100 次暴力破解失败 | 受限模式点亮,重启后持续,通过隧道的密钥/会话被拒绝,回环通过 | test/security/nist-ceiling.test.ts |
| 机密/密钥泄漏(日志、响应、IPC 帧、Telegram 载荷、env、state) | 按值的金丝雀若泄漏则失败 | test/security/secret-leak-canary.test.ts(ADV-050..059) |
| 密钥比较是否泄漏时间? | 恒定时间的统计证明 | test/security/timing-constante.test.ts |
| 使用真实进程的完整隧道周期 | start → READY → 通过 URL 返回 401 → 带会话返回 200 → stop,无孤儿进程 | test/e2e/tunnel-cycle.test.ts(T6.1) |

关于此矩阵不是什么的诚实说明:e2e 使用 fake-cloudflared* 和伪造边界
——在 CI 中没有任何字节离开 127.0.0.1,这是设计使然。通过真实边界
和网络的再次确认是 test/live/** 套件(DSH_GUARD_LIVE_TESTS=1),选择性启用且在门禁之外——
见 docs/TESTING.md §5。

卸载与回滚

dsh plugin remove dsh-guard-messenger

留下零残留进程,Web UI 恢复原始行为。若要同时删除链接密钥、配对和本地状态:删除 ~/.dsh/guarded-bot。详情见 docs/INSTALL.md。

文档
- docs/INSTALL.md — 分步安装
- docs/ONBOARDING-TELEGRAM.md — 连接 Telegram 机器人并配对
- docs/ONBOARDING-DISCORD.md — 创建 Discord 机器人、邀请并配对
- docs/AGENTS.md — 代理调度器:配置、命令、安全与限制
- docs/EXPOSURE.md — 隧道启动后会发生什么变化
- docs/TUNNEL.md — quick 与 named、TTL、传输威胁模型
- docs/THREAT-MODEL.md — 攻击者、缓解措施、无法缓解的部分
- docs/TROUBLESHOOTING.md — 症状 → 原因 → 该怎么办
- docs/ARCHITECTURE.md — Cordis 接缝与模块地图
- docs/TESTING.md — 如何运行每一级测试

贡献与报告

- 发现了漏洞?不要开公开 issue。 请阅读 SECURITY.md 并使用其中描述的私密渠道(Private Vulnerability Reporting 或电子邮件)。
- 想贡献?CONTRIBUTING.md 提供了四条命令搭建环境、测试级别、PR 中绝不接受的内容,以及如何添加消息传递提供商。
- 行为准则:CODE_OF_CONDUCT.md。

MIT 许可证 — LICENSE。上游的 DeepSeek Harness 同样采用 MIT。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(frederico-kluser)的其他插件

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群