DeepSeek Harness 插件

dsh-cftunnel

Cloudflare Tunnel plugin for DeepSeek Harness: expose the local web GUI through a quick / token / API tunnel behind a token-gated loopback proxy, with optional Cloudflare Access email OTP.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
weicy98/dsh-cftunnel
最近更新
2026年8月16日
分类
远程与移动
GitHub stars
1
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/weicy98/dsh-cftunnel
插件名:dsh-cftunnel
作者:weicy98

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh.md来源说明 · 只读预览
README 语言

dsh-cftunnel

English | 中文

DeepSeek Harness 的 bundle 插件:通过 Cloudflare Tunnel 把本地 web GUI(http://127.0.0.1:3080)暴露到公网。

装好插件,打开 Settings,填 Cloudflare 信息,点连接。 cloudflared 由插件自动下载管理——不用手动安装、不用包管理器、不用重启。

快速上手

1. 安装——一条命令:

``sh dsh plugin --profile web add git+https://github.com/weicy98/dsh-cftunnel ``

2. 重启 dsh web,打开 Settings → Cloudflare Tunnel。 3. 选模式、填信息、点连接。 复制带 token 的访问链接分享出去。

> 首次连接会下载一次 cloudflared(约 40MB),慢网络可能要几分钟——面板里有进度条显示下载进度;

模式

按你手头有什么选:

模式输入URL适合场景
快速隧道随机 https://<名字>.trycloudflare.com想立刻要个链接,不想配 Cloudflare 账号
隧道 Token隧道 token + 域名https://<域名>已经在 Zero Trust 仪表盘建好了隧道
API TokenAPI token + 隧道名 + 域名https://<域名>让插件自动建隧道、DNS,并可顺带开邮箱验证

端到端流程

1. Settings 面板里选模式(快速隧道 / 隧道 Token / API Token),点 连接。 2. 连接时插件先自动准备 cloudflared——$DSH_HOME/cloudflared/cloudflared 不存在就从 GitHub 官方 release 下载对应平台二进制并解压缓存。 3. 启动隧道: - 快速隧道cloudflared tunnel --url http://127.0.0.1:<proxyPort> → 随机 https://<名字>.trycloudflare.com。 - 隧道 Tokencloudflared tunnel run,用 Zero Trust 仪表盘生成的 token(路由/ingress 在仪表盘配置)。 - API Token:通过 Cloudflare HTTP API 自动创建隧道 + 配置 ingress + 建 DNS CNAME,再用返回的 token 运行(不需要 cert.pem,不需要本地 config.yml)。 4. 所有隧道流量经本地反向代理127.0.0.1:<proxyPort>):代理把 Host 改写为 loopback、删除 Origin,harness 信任围栏全放行(含特权方法)。代理前有访问 token 校验(默认开启)和可选的 Cloudflare Access 邮箱 OTP 两道门。 5. 秘密(API token、隧道 token、代理访问 token)存凭据存储(~/.dsh/.credentials.yaml);非秘密偏好(模式、域名、隧道名、账户/Zone ID、邮箱验证设置)存 settings 命名空间(~/.dsh/settings.yaml),下次打开自动预填。

安装

在本目录下:

dsh plugin --profile web add file:.

或从 git / npm 源安装:

dsh plugin --profile web add git+https://github.com/weicy98/dsh-cftunnel
dsh plugin --profile web add dsh-cftunnel

dsh plugin 在 profile 目录执行 pnpm 并同步 dsh.profile.bundles——本包声明了 dsh.bundle.patch,所以会自动加进 bundle 栈。重启 dsh web,打开 Settings → Cloudflare Tunnel

> 改代码后重新安装:先 dsh plugin --profile web remove dsh-cftunneladd file:.(pnpm 把 file: 依赖视为不可变,remove + add 是最可靠的刷新方式)。

配置

部署级选项写在 profile 自己的 cordis.patch.yml~/.dsh/profiles/web/cordis.patch.yml)或 --patch 覆盖层;其余都是 Settings 面板字段,持久化在 settings 命名空间。

- id: cloudflare-tunnel
  config:
    cloudflaredPath: 'cloudflared'   # 显式二进制路径(默认:自动下载到 $DSH_HOME/cloudflared)
    port: 3080                       # 要代理的本地 harness 端口
    downloadMirror: ''               # 可选 ghproxy 风格镜像前缀,如 'https://ghproxy.example/'
    proxyPort: 3091                  # 反向代理的 loopback 端口
    proxyAuth: 'token'               # 'token'(默认)| 'none'
    proxyToken: ''                   # 可选固定访问 token;留空 = 自动生成并持久化
    accessPolicy: 'none'             # 'none' | 'emailOtp'
    accessEmailDomains: []           # 如 ['yourcompany.com'] — 限制邮箱 OTP 发送域
    accessAccountId: ''              # 可选显式 Cloudflare 账户 ID
    accessZoneId: ''                 # 可选显式 Cloudflare Zone ID

说明:

  • downloadMirror 控制一次性下载方式。留空(默认)走 GitHub API → CDN——权威但在部分网络较慢(实测约 80 KB/s,40MB 约 8 分钟)。配镜像前缀可加速;镜像属于第三方,需信任其不篡改二进制。
  • accessAccountId / accessZoneId 也可以在设置面板里填,填了就不需要 API token 的 Account Settings:Read / Zone:Read 权限。
  • proxyAuth: 'none' 关闭访问 token 校验(UI 关闭前会二次确认)。

安全模型(重要)

所有隧道流量经本地反向代理127.0.0.1:<proxyPort>),代理把请求改写为 loopback(Host → 127.0.0.1:<port>、删除 Origin),因此 harness 信任围栏完全放行——包括特权方法,远程访客获得与本机一致的完整体验。

代理只绑定 127.0.0.1,唯一入口是 cloudflared(Cloudflare edge)。它前面有两道独立门:

  • 访问 token(默认开启,proxyAuth: 'token':每个请求必须带 token——首次以 ?token=… 带一次(代理随后种下 HttpOnly; Secure cookie),之后靠 cookie 自动携带。面板会显示可分享的带 token 链接,开关实时生效。
  • Cloudflare Access 邮箱 OTP(可选,accessPolicy: 'emailOtp':edge 层邮箱验证,请求到代理前就被拦截。

建议:公网暴露时两道门都开。两道都关意味着任何拿到 URL 的人都能完全控制 harness(设置、凭据、目录选择器)——只在可信网络才可接受。

本机使用(http://127.0.0.1:3080)不经过代理,完全不受影响。

邮箱验证(Email OTP)

accessPolicy 设为 'emailOtp'(或在面板里勾选)即可用 Cloudflare Access 一次性 PIN 拦住隧道。连接时插件用同一个 API token 创建绑定该域名的 self-hosted Access 应用和 allow 策略:

  • 不配白名单:任何访客输入邮箱 → 收 6 位 PIN → 输入正确才放行。
  • 白名单填完整邮箱user@example.com):精确邮箱规则(Access 里的 "Emails")。
  • 白名单填域名yourcompany.com):邮箱域名规则(Access 里的 "Emails ending in")。

要求:

  • 仅 API Token 模式(quick / token 隧道的域名不由本插件程序化管理,无法自动挂策略)。
  • API token 额外需要 Access: Organizations, Identity Providers, and Groups:Edit;未配 accessAccountId 时还需要 Account Settings:Read 来解析账户 ID。

API token 权限清单

API Token 模式需要(面板里也有提示):

资源权限用途
AccountCloudflare Tunnel — Write建隧道、配 ingress
ZoneDNS — Edit建 CNAME 记录
AccountAccount Settings — Read解析账户 ID(填了 Account ID 可省)
ZoneZone — Read解析 Zone ID(填了 Zone ID 可省)
AccountAccess: Organizations, Identity Providers, and Groups — Write仅邮箱验证需要

前置条件

  • 带 web 界面的 profile(dsh web / --profile web)。
  • 隧道 Token 模式:Zero Trust 仪表盘生成的隧道 token,且公共域名路由到 http://127.0.0.1:3091(loopback 代理端口——路由到 3080 会绕过访问 token 门)。
  • API Token 模式:具备上述权限的 API token,且域名的 DNS zone 在该账户上。
  • 首次连接需要能访问 github.com(只用于下载 cloudflared,之后缓存)。

开发

pnpm install   # dsh-settings(dev/peer)、schemastery
pnpm test      # node --test(cfapi、cloudflared、主机生命周期、proxy 四套)

架构

关注点位置机制
准备 cloudflaredlib/cloudflared.jsGitHub release 下载 + tar 解压 + 缓存到 $DSH_HOME/cloudflared
运行/管理隧道lib/index.jsnode:child_process spawn + ctx.effect 清理
Cloudflare APIlib/cfapi.jscfd_tunnel 创建 + configurations ingress + dns_records CNAME + Access 应用/策略
Loopback 代理lib/proxy.jsHost 改写 loopback + 删 Origin + 访问 token 门(cookie / ?token=)+ WS 转发——零依赖(node:http + node:net,不再依赖 http-proxy / DEP0060)
依赖package.jsonschemastery 作为叶子依赖;宿主 seam(dsh-settings)放 peerDependencies;engines.node >= 20.3
秘密lib/index.jsctx.credentialsCLOUDFLARE_API_TOKENCLOUDFLARE_TUNNEL_TOKENCLOUDFLARE_TUNNEL_PROXY_TOKEN
偏好lib/index.jsctx.settings 命名空间 cloudflare-tunnel
Client→Host RPC两端ctx.connection.rpc.handle('/cloudflare-tunnel', …) / ctx.get('connection').rpc.call(…)
设置 UIlib/client.jsctx.slots.inject('settings.section', …) + locale 字典
Bundle 接线cordis.patch.yml + package.json dsh单行 insert,自动加入 dsh.profile.bundles

/cloudflare-tunnel 通道的端点:statusstartstopsetProxyAuthstart 接受 AbortSignal,UI 取消会中止正在进行的下载与 API 配置。

已知限制

  • 仅 web profile(node 半等待 connectioncredentialssettingswebServer;headless/TUI 下保持休眠)。
  • 进程内有效:运行中的隧道不跨 harness 重启,但缓存的二进制、存储的秘密与偏好会保留;隧道、ingress、DNS 记录持久化在 Cloudflare 侧。
  • API token 只用于 Cloudflare API 配置调用(隧道/ingress/DNS/Access);运行中的 cloudflared 用隧道 token 认证,不用 API token。