dsh-web-gate:为桌面端 DSH 提供带密码的局域网网关

前言

DeepSeek Harness(DSH)桌面版内置 Web 能力,但 dsh --profile web 默认只监听 loopback,手机或平板很难在同一 WiFi 下用浏览器连上本机实例。官方通过 --public-url 与 --trusted-host 做反代,对 Electron 拉起的 Host 并不适用:无法追加启动参数、端口每次动态分配、根路径还需要进程内存里的 ?token= 才能换会话 Cookie。

dsh-web-gate(npm 包名 @realoiyo/dsh-web-gate)由 REALOIYO 维护,作为 DSH 客户端类插件,在 Host 进程内实现局域网网关:不改 DSH 页面,同网段设备浏览器输入密码即可访问本机 DSH。下文介绍其定位、安装步骤与使用时的安全边界。

这是什么

一句话:在桌面 DSH 外挂一层 HTTP 网关,用密码保护,让局域网内的浏览器访问本机 Harness。

插件在网关进程内读取 ctx.webServer.port 与 ctx.connection.authenticatedUrl(),完成 token 握手与请求转发;对经局域网 IP 访问的页面注入少量 polyfill,以弥补非安全上下文下 crypto.randomUUID 等 API 缺失、以及非回环 hostname 导致设置无法持久化的问题。许可证为 MIT,当前 npm 版本为 0.2.1,依赖 Node >=22。

背景:为何不直接反代

README 归纳了桌面版与 CLI Web profile 的差异:

  1. Host 由 Electron 启动,不能像在命令行里那样追加 --public-url。
  2. Web 端口每次启动变化,无法预先写死反代 upstream。
  3. 首次访问依赖仅存在于内存中的 launch token,外部反代难以自行完成 Cookie 会话建立。

因此网关实现在插件侧,在 Host 生命周期内与 DSH Web Server 协同。

核心功能

密码与会话

  • 监听可配置地址与端口(默认 0.0.0.0:3082),访问需输入网关密码(默认随机 10 位,最少 8 位)。
  • 会话 Cookie 名为 dsh_gate_session,由 HMAC(secret, password) 派生;修改密码等同于注销全部已登录设备。
  • 登录失败限速:单 IP 每分钟 5 次失败锁定 60 秒;全局每分钟 50 次失败锁定 30 秒。

网关先用内部 launch token 请求 / 取得 DSH 会话 Cookie,再转发外部请求,客户端不看到 303 跳转。

DSH 认证 Cookie 名含 host:port 的 sha256,桌面版端口变化且旧 Cookie 不清理,条目累积过多时请求头可触发 Node 约 16 KB 上限(HTTP 431,界面表现为 Web authentication failed)。网关拦截上游全部 Set-Cookie,内存中只保留当前一条,客户端侧主要维护网关会话 Cookie。

polyfill 注入

经 http://<局域网 IP> 访问时,浏览器可能缺少 crypto.randomUUID 或 AbortSignal.any,表现为可读不可写;非回环 hostname 还会让 DSH 把设置存到 memory 而非 host。插件仅在 API 缺失时注入,不覆盖原生实现;对 HTML 文档移除 accept-encoding 以便插入脚本,JS/CSS 仍保持压缩。

设置界面

安装并在 DSH 中启用后,监听地址与密码会写入日志,并出现在 设置 → 手机网关(可复制、可改密)。

安装与启用

DSH 插件以当前 dsh 进程权限运行,安装前建议在 GitHub 仓库 查看源码与 MIT 许可证。

从 npm 安装:

dsh plugin --profile desktop add @realoiyo/dsh-web-gate

从 GitHub 安装(会走源码构建):

dsh plugin --profile desktop add github:REALOIYO/dsh-web-gate

安装后重启 DSH。配置文件位于 $DSH_HOME/dsh-web-gate/settings.json,修改后需重启生效。配置优先级为:profile patch 中的 config > settings.json > 随机生成。

键 默认值 说明
port 3082 监听端口
host "0.0.0.0" 监听地址
password 随机 10 位 访问密码,最少 8 位
secret 随机 32 字节 会话签名密钥,修改将使全部会话失效

典型用法

  1. 在桌面端按上文命令安装插件并重启 DSH。
  2. 在 设置 → 手机网关 查看本机局域网访问地址与密码(或查启动日志)。
  3. 确保手机/平板与电脑处于同一网段。
  4. 浏览器打开 http://<主机局域网 IP>:3082(端口以 settings.json 中 port 为准),输入网关密码后使用 DSH Web 界面。

网关不提供公网隧道与专门移动端适配;可选安装 qrcode-terminal 时在终端输出二维码(README 说明默认不生成二维码)。

安全与限制

  • 密码为唯一凭证;网关可在主机上代表 DSH 执行代码,不应把密码传到不可信环境。
  • 流量为明文 HTTP,同网段内可被嗅探,仅适合可信局域网;跨网段应叠加 WireGuard、Tailscale 等隧道,不要直接暴露公网。
  • password 以明文存于 settings.json(权限 0600),同机其他管理员账户可读。
  • 不提供官方公网穿透;WebSocket 仅在握手阶段校验一次;Host / Origin / Referer / Sec-Fetch-Site 会改写为 loopback,若部署依赖真实 Host 需自行调整。

社区插件目录 SkillHub 上的 dsh-web-gate 页 与 GitHub 仓库 可查阅更新与 Issue;目录为社区站点,与 DeepSeek / 幻方无官方从属关系。DSH 生态奉行「一切皆插件」,本插件适合需要在同一 WiFi 下用手机浏览器临时操作本机 Harness、又不愿改 DSH 本体界面的开发者。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye