dsh-totp-proxy:为 DSH 增加 TOTP 与可吊销会话的反向代理

前言

DeepSeek Harness(DSH)在浏览器侧通常会持有核心签发的 dsh-auth-* 自包含 bearer cookie。一旦 cookie 泄露,在过期前调用方仍可能直接访问 API,且难以在服务端「立刻作废」浏览器里的凭据。若要把 Web 界面放到 Nginx 后面、又希望多一层登录校验,常见做法是再套一层网关或改核心认证流程,运维和安全边界都要自己捋清楚。

下面介绍社区插件 dsh-totp-proxy(维护者 realjhen123):它既是 DSH/Cordis 插件,也是面向 DSH 上游的反向代理,内置 TOTP 与固定 token 登录,浏览器只持有可吊销的 dsg_session,原始 dsh-auth-* 留在代理服务端。

这是什么

dsh-totp-proxy 定位是:独立 DSH/Cordis 插件 + 反向代理;零额外运行时依赖,要求 Node.js 22+(实现仅使用 node:http / node:https)。当前 package 版本为 0.2.0,许可证 MIT。

典型链路如下(摘自 README 架构说明):

浏览器 --dsg_session--> Nginx :80/:443 --> dsh-totp-proxy 127.0.0.1:3090 --dsh-auth cookie--> DSH 127.0.0.1:3080

代理自行校验 TOTP / 固定 token,读取 DSH 的 browser-session 签名密钥,签发 DSH 核心认可的 cookie;每个 HTTP 请求与 WebSocket upgrade 均经代理校验,删除服务端 session 即可立即吊销。

核心功能

认证方式

通过 authMode(或环境变量 DSH_TOTP_PROXY_AUTH_MODE)控制:

authMode 行为
totp 只接受 6 位验证码
token 只接受固定 token
both 两者任一(默认)

凭据在首次运行时自动生成,保存在 ~/.dsh/dsh-totp-proxy/:

  • totp.json — Base32 TOTP secret
  • token.json — 固定访问 token

连续失败达到上限(默认 10 次)会按 IP 锁定(默认 60 秒)。TOTP 可配合 Apple Passwords、1Password 等常见验证器使用。

DSH 核心的 dsh-auth-* 是自包含 bearer cookie;浏览器若已持有,即使再弹验证码也可能在过期前直接调 API。本代理把原始 cookie 留在服务端,浏览器只拿到随机 session(默认 cookie 名 dsg_session),从架构上缩小浏览器可见的高权限凭据面。

安全边界(作者说明)

能做到: 浏览器看不到 dsh-auth-*;删除服务端 session 立即吊销;所有 API / WebSocket 统一校验。

仍须注意: dsg_session 仍是 bearer credential,被窃取后可在 TTL 内重放;需 HTTPS、HttpOnly、SameSite=Strict 与较短 TTL;session 在内存中,代理重启后需重新登录。

项目 NOTICE 还强调:面向公网环境的设计思路,但不要把本方案直接部署在真实公网;若使用插件,应确保 Nginx(或任意反代)只能代理到 3090,3080 不得对外可达。

安装与启用

作为 DSH 插件

README 给出的示例命令(路径需换成你本机克隆或下载后的插件目录):

dsh plugin --profile web add /home/coder/project/dsh-totp-proxy -w

可用 cordis.patch.yml 覆盖配置,例如:

- id: dsh-totp-proxy
  config:
    host: 127.0.0.1
    port: 3090
    target: http://127.0.0.1:3080
    cookieSecure: true
    authMode: both

独立运行

不通过 Cordis 挂载时,可直接启动入口脚本:

node totp-proxy.mjs

本地校验

npm run check   # 语法检查 + node --test

典型用法与配置

常用环境变量

完整默认值见仓库 src/server.mjs 中的 DEFAULTS。常用项如下:

变量 默认 说明
DSH_TOTP_PROXY_HOST 127.0.0.1 监听地址
DSH_TOTP_PROXY_PORT 3090 监听端口
DSH_TOTP_PROXY_TARGET http://127.0.0.1:3080 DSH 上游
DSH_TOTP_PROXY_AUTH_MODE both totp / token / both
DSH_TOTP_PROXY_TOTP_SECRET 空 直接指定 Base32 secret
DSH_TOTP_PROXY_TOKEN 空 直接指定固定 token
DSH_TOTP_PROXY_SESSION_TTL_MS 1800000 代理 session TTL
DSH_TOTP_PROXY_COOKIE_NAME dsg_session 浏览器 cookie 名
DSH_TOTP_PROXY_COOKIE_SECURE false HTTPS 后置 1
DSH_TOTP_PROXY_BROWSER_SESSION_SECRET 空 DSH cookie 签名密钥
DSH_TOTP_PROXY_CREDENTIALS_FILE ~/.dsh/.credentials.yaml 读取签名密钥的文件
DSH_TOTP_PROXY_UPSTREAM_SESSION_PATH /api 上游会话校验路径

设置 DSH_TOTP_PROXY_COOKIE_SECURE=1 时必须配合 HTTPS;DSH 的 3080 与代理的 3090 都不应直接暴露到公网。

无 GUI 环境下绑定 TOTP

配置页要求经本机访问。若 DSH 跑在没有图形界面的虚拟机里,首次或忘记 TOTP 时,README 建议用 SSH 本地端口转发:

ssh dsh@dsh -NL 3080:127.0.0.1:3080

随后在本地浏览器打开 127.0.0.1:3080 查看二维码并完成 TOTP 绑定。

修改代理相关配置时:

ssh dsh@dsh -NL 3090:127.0.0.1:3090

在 127.0.0.1:3090 管理 dsh-totp-proxy 的配置。

部署要点

  1. 只对外暴露 Nginx(:80 / :443),反代到 127.0.0.1:3090,并转发 Upgrade / Connection 以支持 WebSocket。
  2. DSH 仅监听 127.0.0.1:3080。
  3. 生产环境设置 DSH_TOTP_PROXY_COOKIE_SECURE=1。
  4. ~/.dsh/.credentials.yaml(含 client-connection / browser-session 密钥)权限保持 0600。

适用场景与注意

适合: 已在内网或受控边界内用 Nginx 暴露 DSH Web,希望增加 TOTP 或固定 token 一层、且需要服务端可吊销的浏览器会话,而不是把完整 dsh-auth-* 交给浏览器。

安装前: 插件随当前 DSH 进程权限运行;安装前应自行审阅源码与 MIT 许可证。DSH 生态强调「一切皆插件」;社区目录 SkillHub 插件页 为独立站点,与 DeepSeek / 幻方无官方从属关系。

经过上面的步骤,你可以在反代之后统一做 TOTP/token 校验,并用 dsg_session 控制吊销面;细节与更新以仓库 README 为准。

  • 目录页:https://www.skillhub.cn/plugins/realjhen123/dsh-totp-proxy
  • GitHub:https://github.com/realjhen123/dsh-totp-proxy
羽毛球分组比赛记分
小程序二维码

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

Xiaoye