DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

laoin114514 /

laoin114514/dsh-gateway

Verified

This plugin has no description yet.

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@1a536863

dsh-gateway-plugin

DeepSeek Harness Web 的访问密码网关插件:网关端口上不存在任何未认证可达的内容面——除登录/首次设置页外,一切请求(页面、静态资源、/api、WebSocket 升级)必须先通过验证;首次使用在登录页直接设置密码;密码可在设置页独立的"安全"页中修改。

为什么要用网关,而不是改 harness

DeepSeek Harness 的 Web 应用有意不提供鉴权(webserver 与 client-connection 包的已知限制里明确写出):官方 web 启动器甚至拒绝 --host 0.0.0.0,/api 的 browser-trust fence 只是防 DNS 重绑(注释白纸黑字:explicitly not authentication)。官方推荐的加固方式就是在前方放置真正的反向代理。

本插件把这道"反向代理"以 harness 插件形式实现,直接装进 profile:

浏览器 ──> dsh-gateway(自己的监听端口,唯一对外入口)── 反代 ──> harness webserver(保持 127.0.0.1 回环绑定)
            ├─ 未认证的任何请求(页面/静态/API/WS)──> 拒绝:页面 302 到 /gateway/login,/api 401
            ├─ /gateway/login GET ──> 唯一未认证放行面:已配置密码 → 登录页;未配置 → 首次设置密码页
            ├─ /gateway/login POST ──> 密码校验(常量时间)→ 签发 HttpOnly 签名会话 cookie
            ├─ /api/* + /api/events.* WebSocket ──> 会话 cookie 或 Authorization: Bearer <密码>
            └─ 认证后全部反代到 harness(改写 Host/Origin 使内部信任围栏放行)

安全要点:

  • 绝对门禁:网关监听端口上只有 /gateway/login(GET 页面 + POST 登录/设密)是未认证可达的;没有 health 端点、没有其他例外。未通过验证的请求什么内容都拿不到(页面与静态资源 302 到登录页,/api 直接 401,WebSocket 升级拒绝)。
  • 首次设置密码:部署还没有密码时,登录页呈现"设置访问密码"表单(两次输入),首个访问者设置成功后立即获得会话——这是唯一的引导信任路径。之后所有人用该密码登录。
  • 修改密码:设置 → 安全(独立页面,不在"插件配置"里)→ 当前密码 + 新密码 ×2;旧密码在 Host 侧校验。修改成功后所有已登录会话立即失效(会话签名密钥轮换)。
  • 防爆破:密码比对为 SHA-256 后 timingSafeEqual(恒定时间);登录失败按来源地址限流(默认连续 5 次失败冷却 30 秒)。
  • 会话令牌:HMAC-SHA256 签名的无状态 cookie(HttpOnly、SameSite=Lax),签名密钥每次进程启动随机生成——重启即全员重新登录,有意 fail-closed。
  • 信任边界:代理改写 Host/Origin 为回环上游,harness 内部围栏与其回环受限特权方法(settings.*、credentials.* 等)接受请求;harness 本身应保持绑 127.0.0.1(默认如此,且官方禁止 0.0.0.0)。边界说明:dsh 本机回环端口上的直连等同于本机管理员(他们本就能读磁盘、改配置),不属于远程攻击面。

从 GitHub 安装

前提:dsh CLI 已安装(或用源码检出,从仓库根执行 pnpm dsh ...)。


dsh plugin --profile web add github:laoin114514/dsh-gateway

推荐固定到具体 commit(防止仓库后续推送悄悄改变安装时拿到的代码):

dsh plugin --profile web add github:laoin114514/dsh-gateway#<commit-sha>

构建产物已经随仓库提交(lib/ 目录),git 安装拉取后无需运行任何构建脚本、无需放行 build 权限,安装即用。首次安装/升级后启动 dsh web:

dsh-gateway: http://127.0.0.1:3088 (gateway, password required) -> harness http://127.0.0.1:3080

打开网关地址(而不是 harness 地址)使用。首次访问时登录页会引导你设置访问密码;之后每次访问输入该密码。

安装失败排查

如果 dsh plugin add github:... 报 ERR_PNPM_ENOENT ... importPackage ..._tmp_...(常见于之前失败安装留下的半装目录),先清理再重装:

dsh plugin --profile web remove dsh-gateway-plugin   # 或手动删除
#   删除 $DSH_HOME/profiles/web/node_modules/dsh-gateway-plugin 后:
rm -rf "$DSH_HOME/profiles/web/node_modules/dsh-gateway-plugin"
dsh plugin --profile web add github:laoin114514/dsh-gateway

暴露到网络

默认网关只绑本机(gatewayHost: '127.0.0.1')。在 profile 的 cordis.patch.yml($DSH_HOME/profiles/web/cordis.patch.yml)里覆盖:

- id: dsh-gateway
  config:
    gatewayHost: '0.0.0.0'

源码检出下的本地开发

依赖本仓库源码联动时(改 harness 本地包),在仓库根执行 pnpm dsh web --patch <dsh-gateway>/cordis.dev.yml --no-open --port 3082(注意:该 overlay 方式下浏览器侧的"安全"页不会加载——只有 profile 行才能被客户端模块系统发现)。

配置(cordis.patch.yml 中 dsh-gateway 行)

字段 默认 说明
gatewayHost '127.0.0.1' 网关监听地址;对外暴露设为 '0.0.0.0'(harness 本体仍保持回环)
gatewayPort 0 网关监听端口;0 由系统分配(启动日志打印实际地址)
sessionTtlHours 24 会话 cookie 有效期(小时);密码修改或进程重启也会使所有会话失效
minKeyLength 8 密码最短长度
maxLoginFailures 5 连续失败多少次后进入冷却
loginCooldownSeconds 30 冷却窗口(秒)
accessKey (空) 初始密码;为空即进入"首次设置"模式(此时配置此字段等价于预先指定密码)。设置服务就绪时该值作为组合 base 层,可被安全页覆盖

密码本身存放在设置命名空间 dsh-gateway(字段 accessKey,用户设置文件),声明为 role('secret'),任何 wire 响应都不会携带它。

已知取舍

  • 不提供 TLS:如需公网/跨网段传输,请在网关前再放一个终结 TLS 的反向代理,或把网络限制在内网。
  • 密码以明文存于用户设置文件(与 harness 其他 role('secret') 字段一致);请按机密文件的权限管理该文件。
  • 会话在进程重启后全部失效(签名密钥随机生成),属有意行为。

开发

pnpm install && pnpm run build   # esbuild 打包 + 两个 tsc 声明产物
pnpm test                        # node:test 集成冒烟(真实 Cordis Context + 假上游)
pnpm run typecheck

产物:

  • lib/index.js — Host 侧网关插件(ESM,仅 @deepseek-ai/* 保持外部解析)
  • lib/client.js — 浏览器侧"安全"设置页(dsh 客户端模块系统的 lazy-CJS factory 格式)
  • lib/types/ — 两侧的声明文件

结构

文件 职责
src/index.ts 网关插件本体:独立监听、反代、WebSocket 隧道、登录/设密/改密端点、设置命名空间接线
src/session.ts 签名会话 cookie(签发/校验/轮换签名密钥)
src/key.ts 恒定时间密码比对
src/lockout.ts 登录失败的按地址限流
src/pages.ts 登录/首次设置页 HTML(零外部资源、内联 CSS/JS)
src/client/ "安全"设置页(settings.section 槽位,id security)
cordis.patch.yml bundle 层:插入 dsh-gateway 行(Host 插件 + dsh.client 浏览器贡献)
cordis.dev.yml 本地开发 overlay(file:// 行,直接 --patch 使用)
tests/gateway.smoke.mjs 集成冒烟:首次设密、无认证面断言、302/401、cookie 会话、Bearer、限流、密码轮换
—/ 5

No ratings yet

Verified DSH bundle

Commit 1a53686324bd

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout