前言¶
DSH 的 web 进程默认只绑定 127.0.0.1,并且其 /api 的 Host 信任栅栏会把非 loopback 来源的请求全部 403(防 DNS-rebinding / cross-origin)。通过 frp 隧道暴露的访问因此被拦下。DSH 本身没有面向公网访问者的登录/密码层。直接开启 --trusted-host 只是“给公网 IP 开栅栏缝”,不等于认证。
dsh-web-auth 插件把栅栏和认证合并成一个正确架构:它是一个跑在 DSH web 进程里的 loopback 反向代理,给经 frp/隧道暴露的 DSH Web 提供 token 登录和会话管理。
插件介绍¶
dsh-web-auth 是 DSH Web 的公网鉴权门。插件运行在 DSH 进程内部,通过反向代理将请求转发至本地 DSH Web,并处理 Token 登录与 HttpOnly 会话 Cookie。
核心功能¶
- 反向代理到 DSH Web
- Token 登录认证
- HttpOnly 会话 Cookie(默认 12 小时,支持滑动续期)
- 支持
X-DSH-Auth头,供脚本或工具免 Cookie 访问 - WebSocket 透传
- 同源 IP 连续失败限速(10 次触发 10 分钟)
安装与启用¶
通过插件命令将仓库安装进指定 profile:
dsh plugin --profile web add <git 仓库地址>
安装后,需要在 profile 的 package.json 中将 dsh-web-auth 追加进 dsh.profile.bundles:
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-web-auth"
]
}
}
随后生成 token 文件:
openssl rand -hex 32 > ~/.dsh/web-auth-token
配置与行为¶
插件提供了丰富的行配置项,所有配置均为可选:
| key | 默认 | 说明 |
|---|---|---|
gateHost |
127.0.0.1 |
gate 绑定地址 |
gatePort |
3081 |
gate 监听端口 (frpc 应指向这里) |
targetHost |
127.0.0.1 |
DSH web 地址 |
targetPort |
3080 |
DSH web 端口兜底值 (运行时优先取 webServer.port) |
token |
— | 直接内联 token |
tokenFile |
web-auth-token |
token 文件名 (相对 $DSH_HOME) 或绝对路径 |
sessionTtlMinutes |
720 |
会话 cookie 有效期 (分钟, 滑动续期) |
maxFails |
10 |
同 IP 连续失败多少次触发限速 |
failWindowMs |
600000 |
限速窗口 (毫秒) |
请求流程如下:
公网 → frp 隧道 → 127.0.0.1:3081 (gate, token 登录) → 127.0.0.1:3080 (DSH web, Host=loopback → 栅栏放行)
具体行为如下:
- 未登录浏览器 GET 页面:302 重定向到
/__dsh-auth__/login登录页。 - 未登录访问
/api、静态资源、WebSocket upgrade:返回 401。 - 登录页 POST
/__dsh-auth__/login(携带token字段,JSON 或 urlencoded):成功后签发 HttpOnly 会话 Cookie,302 回原路径。 - 请求携带
X-DSH-Auth: <token>头:免 Cookie 访问。 - POST
/__dsh-auth__/logout:清 Cookie。 - 同源 IP 连续失败 10 次:触发 10 分钟限速。
适用场景与注意¶
- 零外部依赖:仅使用 Node.js 内置模块,要求 Node.js >= 18。
- Fail Closed 机制:如果找不到 token,gate 不启动,公网入口不可用,但 DSH 本体不受影响。
- 部署依赖:需配合 frpc 将 dsh-web 的
localPort指向 gatePort (3081)。
生态背景¶
DeepSeek Harness (DSH) 理念是「一切皆插件」。本插件由 ChinaBoy0618 维护,开源协议为 MIT。更多详情可访问 插件目录 或 GitHub 仓库。