dsh-trusted-proxy-auth:在反向代理 OIDC 与 DSH 原生浏览器认证之间做边界适配

前言

把 DeepSeek Harness(DSH)放在 Traefik、Keycloak 等反向代理后面时,身份校验往往已经在代理层完成;若仍只依赖 DSH 自带的浏览器 launch-token / cookie 流程,远程访问体验和本地 loopback、SSH 隧道访问会不一致。直接在 DSH 里重写 OIDC/JWT,又会动到核心安装与传输层。

下面介绍社区插件 dsh-trusted-proxy-auth(维护者 lukepoo101,分类 admin-security):在代理已认证的前提下,通过私有请求头建立第二条独立认证路径;头缺失或错误时,原生 DSH 认证行为不变。

这是什么

dsh-trusted-proxy-auth 是一个仅面向宿主机部署的小型 DSH 插件(MIT 许可证,当前发布版本 v0.2.3)。它不替换 DSH 传输、不 patch DSH 安装目录内的文件、也不实现 OIDC/JWT 逻辑,只是在认证边界上适配「代理已登录 + 注入共享密钥」与「DSH 原生 401/403 语义」。

典型链路示意:

External browser
      │
      ▼
   Traefik ───────────► Keycloak OIDC
      │  (identity, login, roles, sessions)
      │
      │  injects:  X-DSH-Proxy-Auth: <private secret>
      ▼
     DSH ─────────────► trusted-proxy-auth
      │                  401 native browser auth + valid secret ──► permit
      │                  403 Host/Origin fence                   ──► still 403
      ▼
  native DSH transport, unchanged

无 X-DSH-Proxy-Auth 时(例如 SSH 隧道或直接访问),仍走原生 ?token=… / cookie 流程。

核心功能

双路径认证且不改写 403

插件挂钩 DSH Web 服务的 requestRejection()(用于 /api 与 WebSocket mux)和首页 authorizeIndex()。要点如下:

场景 共享密钥 结果
上游已是 403(Host/Origin/DNS-rebinding 围栏) 有效 仍为 403
上游 401(需原生浏览器认证) 有效 放行
密钥缺失或错误 — 保持原生 401 或委托原流程

启动时会用 invariant 重新验证 DSH 的 403/401 语义,避免插件在 DSH 升级后静默变成 bypass。资料记载:在 DSH 0.1.5-rc.2、Node v24.21.0 上测试通过(Node 20/22 由 CI 覆盖);86 个单元测试与 37 项 live-DSH 集成检查通过。运行时无 npm 依赖,仅使用 node:crypto,纯 ESM、无构建步骤。

远程域名下的设置持久化(ownsHost)

经反向代理以公网 hostname 访问时,客户端可能因 isLoopback 判定走内存持久化,Models、Plugins 配置出现「settings are unavailable in this browser」。对携带有效代理认证头的请求,插件通过 webServer.tapIndex 等扩展点在 index HTML 的 <head> 注入经服务端校验的 bootstrap,使 connection 包将 ownsHost 视为 true,从而启用 'host' 持久化,且不改动 Node ServerResponse 流水线。

第三方插件路由与 loopback 归一化

部分插件(README 以 dshmarket@1.65.1 为例)对变更类 HTTP 路由做严格 loopback 检查。公网 Host 下若简单在代理层改写 Origin,会削弱 CSRF 防护。插件在有效 X-DSH-Proxy-Auth 时,先对真实入站头调用未装饰的 connection.requestRejection(req);未过 Host/Origin 围栏则立即 403;通过后才对 match/handle 路由做安全的 loopback 归一化,便于 Marketplace 等插件在代理后可用。

安装与启用

1、生成并写入共享密钥

密钥至少 32 字节可打印 ASCII(不含逗号),不要写入 YAML,只放在 DSH 服务已读取的环境文件中(示例路径 /etc/dsh/env,属主 root:dsh,模式 0640):

openssl rand -hex 48
SECRET="$(openssl rand -hex 48)"
printf 'DSH_PROXY_AUTH_SECRET=%s\n' "$SECRET" | sudo tee -a /etc/dsh/env >/dev/null
sudo chown root:dsh /etc/dsh/env
sudo chmod 0640 /etc/dsh/env

反向代理侧需配置同名逻辑:仅在内网、且已完成 OIDC 等身份校验的请求上注入请求头 X-DSH-Proxy-Auth(值与环境变量中的 secret 一致)。该头不应下发给浏览器。

2、安装插件并重启服务

在 Web profile 安装 bundle 后重启 DSH(认证边界插件建议 pin 到已审查的 tag 或 commit,不要跟踪 main):

# from a Git checkout
dsh plugin --profile web add /path/to/dsh-trusted-proxy-auth

# or directly from this repository, pinned to the released tag
dsh plugin --profile web add git+https://github.com/lukepoo101/dsh-trusted-proxy-auth.git#v0.2.3

# an exact commit is equally acceptable for an authentication-boundary plugin
dsh plugin --profile web add git+https://github.com/lukepoo101/dsh-trusted-proxy-auth.git#<40-char-commit>

sudo systemctl restart deepseek-harness

3、校验 profile 与公网 hostname

确认合成 profile 中除 Connection 传输外还包含本插件:

dsh web --dump-config | grep -E -A1 "connection|trusted-proxy-auth"

期望片段类似:

- id: connection
  name: '@deepseek-ai/dsh-client-connection'
...
- id: trusted-proxy-auth
  name: dsh-trusted-proxy-auth

将最终对外 hostname 写入 DSH 启动参数:

dsh web --trusted-host dsh.example.com

Traefik + Keycloak OIDC 的具体路由、中间件与 header 注入需与你的基础设施一致;README 只约定 DSH 侧环境变量与头名称,不在此展开代理配置模板。

配置说明

项 位置 说明
DSH_PROXY_AUTH_SECRET 环境变量 必填。缺失、为空、过短或格式非法会导致插件激活失败,profile 无法半开半关地启动。
X-DSH-Proxy-Auth 请求头 仅由反向代理注入,勿暴露给客户端。

插件本身 没有 YAML 配置项。openssl rand -hex 48 或 openssl rand -base64 48 均可满足字符集要求。

适用场景与注意

适合:已在 Traefik(或其他可信反向代理)后接入 Keycloak OIDC,希望远程浏览器会话被 DSH 视为已认证,同时保留 SSH 隧道、本机 loopback 的原生 token/cookie 回退;并需要在公网 hostname 下正常使用 Models、Plugins 持久化及 Marketplace 类插件。

务必注意:

  • 插件与当前 dsh 进程同权限 运行;安装前请自行审阅源码与 MIT 许可证,secret 泄露等同于伪造已认证请求(仍受 Host/Origin 403 约束,但不能替代代理层 OIDC 加固)。
  • 共享 secret 只应存在于服务端环境与代理配置,不要进入前端或公开仓库。
  • 认证边界插件应固定版本(如 v0.2.3 或指定 commit),升级时 deliberately bump 并复跑验证(见仓库 docs/VALIDATION.md)。

DSH 生态强调「一切皆插件」;社区目录 SkillHub 插件页 与 GitHub 仓库由社区维护,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-trusted-proxy-auth 把「代理已完成 OIDC」与「DSH 原生浏览器认证」拆成两条独立路径:有效 X-DSH-Proxy-Auth 时在遵守 403 围栏的前提下放行 401;否则行为与未装插件一致,并兼顾远程 settings 与 strict loopback 插件的兼容性。

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

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

小夜