DeepSeek Harness plugin

dsh-admin-gateway

DeepSeek Harness 管理员验证网关插件 — 自起独立 HTTP 网关,密码登录 + 反向代理 + WebSocket/SSE 透传,防止未授权访问

Jump to install

Source facts

Repository
myfire2014/dsh-admin-gateway
Latest update
Aug 18, 2026
Category
Tools & Capabilities
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/myfire2014/dsh-admin-gateway
Plugin: dsh-admin-gateway
Author: myfire2014

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer2 files
README.mdSource · read only

dsh-admin-gateway

DeepSeek Harness (dsh) 管理员验证网关插件。

核心优势

  • 零成本公网暴露:只需一个绑定在 Cloudflare 的域名,无需公网 IP、无需开防火墙端口、无需购买服务器,一条 Cloudflare Tunnel 即可让 dsh web 安全上线公网(HTTPS / DDoS 防护全由 Cloudflare 提供)
  • 开箱即用的安全防线:管理员密码登录 + 会话 Cookie + 防暴力破解限速 + 防 DNS rebinding,未认证流量永远到不了 dsh 本体
  • 即插即用:npm 安装 → 配置密码 → 绑定域名,三步完成,无需改 dsh 一行代码

它解决什么问题

dsh 的 HTTP 服务器(ctx.webServer)没有请求级中间件钩子,host 默认绑定 127.0.0.1,无 TLS / 认证 / origin 策略。本插件自起一个独立的 node:http 网关,先做管理员验证,通过后反向代理到 dsh web 本体,并正确改写 Host / Origin / Referer 头以满足 dsh Connection 信任检查(isTrustedApiRequest)。

配合 Cloudflare Tunnel 使用时,隧道只把流量送到网关端口,未认证请求永远到不了 dsh 本体

功能特性

  • 管理员密码登录(scrypt 哈希 + timingSafeEqual 时序安全比较)
  • HttpOnly + SameSite=Strict 会话 Cookie,服务端内存会话,TTL 可配
  • 登录失败按 IP 限速锁定(防暴力破解)
  • Host 头白名单校验(防 DNS rebinding)
  • 请求体大小上限(防超大报文攻击)
  • 可选 per-IP 请求速率限制
  • 安全响应头(X-Frame-Options / X-Content-Type-Options / Referrer-Policy)
  • /api 未认证返回 401 JSON;浏览器页面未认证 302 跳转登录页
  • 反向代理时改写 Host / Origin / Referer,满足 dsh 信任检查
  • WebSocket / SSE 升级代理(dsh web UI 依赖事件流)

安装

npm install dsh-admin-gateway

作为 dsh 插件(bundle)安装到 profile:

# 在插件目录的父目录执行(不要在插件目录内写 ./dsh-admin-gateway)
cd /path/to/parent && dsh plugin --profile web add ./dsh-admin-gateway
# 或通过 npm 安装包名引用
dsh plugin --profile web add dsh-admin-gateway

确认插件已生效:

dsh --profile web --dump-config | grep -A3 'admin-gateway'
# 看到 "# == dsh-admin-gateway" 层 = 成功

配置

插件通过 cordis.patch.yml(或 profile 的配置层)注入,示例:

- insert:
    - id: admin-gateway
      name: dsh-admin-gateway
      config:
        port: 3081
        upstream: 'http://127.0.0.1:3080'
        allowedHosts:
          - dsh.example.com
        sessionTtlMs: 43200000
        maxBodyBytes: 5242880

配置项

字段默认值说明
port3081网关监听端口
host127.0.0.1网关监听地址,只应绑定回环(由 cloudflared 从本机连入)
upstreamhttp://127.0.0.1:3080上游 dsh web 地址
adminPassword''管理员密码;优先取环境变量 DSH_ADMIN_PASSWORD,其次取此值。两者都为空时插件启动报错
sessionTtlMs43200000 (12h)会话有效期(毫秒)
cookieNamedsh_admin_session会话 Cookie 名称
loginMaxAttempts5登录失败限速:窗口内允许的最大失败次数
loginWindowMs600000 (10min)登录失败限速窗口(毫秒)
loginLockMs600000 (10min)锁定时间(毫秒),超过 maxAttempts 后锁定该 IP
maxBodyBytes5242880 (5MB)请求体大小上限(字节)
reqLimitPerMin0可选:每 IP 每分钟最大请求数,0 表示不限制
allowedHosts[]Host 白名单(防 DNS rebinding);留空接受任意 Host
allowedIps[]可选:IP 白名单,留空不限制来源 IP

使用步骤

1. 设置管理员密码(推荐环境变量方式,避免明文进配置):

``sh # 写入 600 权限的 env 文件,例如 /etc/dsh/admin-gateway.env echo 'DSH_ADMIN_PASSWORD=你的强密码' > /etc/dsh/admin-gateway.env chmod 600 /etc/dsh/admin-gateway.env ``

2. 配置 dsh 启动(systemd 用户服务示例):

``ini # ~/.config/systemd/user/dsh.service [Service] Type=simple EnvironmentFile=/etc/dsh/admin-gateway.env Environment=PATH=/path/to/npm-global/bin:/usr/local/bin:/usr/bin:/bin ExecStart=/path/to/dsh web Restart=always RestartSec=3 ``

``sh loginctl enable-linger $USER # 关键!否则用户服务不随开机启动 systemctl --user daemon-reload && systemctl --user enable --now dsh.service ``

3. Cloudflare Tunnel 只指向网关端口(示例端口 3081),dsh 本体 3080 保持仅本机可访问。完整配置见下文「通过 Cloudflare Tunnel 暴露到公网」。

4. 访问:浏览器打开外网域名 → 未认证跳转登录页 → 输入管理员密码 → 获得 HttpOnly 会话 Cookie → 正常使用 dsh web UI 与 API。

5. 改密码:编辑 env 文件后重启 dsh 服务(systemctl --user restart dsh.service),旧会话 Cookie 到期前仍有效。

通过 Cloudflare Tunnel 暴露到公网

推荐用 Cloudflare Tunnel(cloudflared)把网关端口暴露到公网:不需要公网 IP、不用开防火墙端口,自带 HTTPS 和 DDoS 防护。关键原则:隧道只指向网关端口(如 3081),dsh 本体(3080)保持仅本机监听。

公网用户 → https://dsh.example.com → Cloudflare 边缘 → cloudflared 隧道 → 网关 127.0.0.1:3081 (鉴权) → dsh web 127.0.0.1:3080

1. 安装 cloudflared

# Ubuntu/Debian(apt 仓库)
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared focal main' | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared

2. 登录并授权域名

cloudflared tunnel login

会打印一个授权 URL,在任意浏览器打开(服务器无 GUI 时复制到本机浏览器打开),登录 Cloudflare 并选择要绑定的域名,授权完成后 ~/.cloudflared/cert.pem 生成即成功。cloudflared tunnel listCannot determine default origin certificate path 说明登录没完成,重新执行。

3. 创建隧道

cloudflared tunnel create dsh-tunnel
# 输出:Tunnel credentials written to /home/<user>/.cloudflared/<UUID>.json

4. 编写 config.yml(指向网关端口!)

# /etc/cloudflared/config.yml
tunnel: <UUID>                          # 上一步输出的 UUID
credentials-file: /etc/cloudflared/<UUID>.json
ingress:
  - hostname: dsh.example.com           # 你的外网域名
    service: http://localhost:3081      # ⚠️ 指向网关端口,不是 3080!
  - service: http_status:404            # catch-all 兜底规则,必须最后一行

注意:写文件不要用 heredoc 管道过 sudo(sudo 会吞掉 stdin 当密码导致文件没写成)。先写到 /tmp 再复制:echo '<密码>' | sudo -S cp /tmp/config /etc/cloudflared/config.yml

5. 绑定 DNS

cloudflared tunnel route dns dsh-tunnel dsh.example.com
# 创建 CNAME:dsh.example.com → <UUID>.cfargotunnel.com

若报 code: 1003 An A, AAAA, or CNAME record with that host already exists,说明该域名已有 DNS 记录,需要先在 Cloudflare 控制台删除旧记录或用 API 更新。

6. 安装为 systemd 服务(开机自启)

sudo cloudflared service install
sudo systemctl enable --now cloudflared

若提示 service is already installed at cloudflared-update.service(旧版本残留),先 cloudflared service uninstall 并删除 /etc/systemd/system/cloudflared*.service 再重装。建议确认 unit 里是 --config /etc/cloudflared/config.yml 的 config 模式(token 模式会忽略你的 config.yml)。

7. 验证

cloudflared tunnel info dsh-tunnel      # 看到 ≥1 条 active edge connection 即正常
sudo systemctl status cloudflared       # active (running)
sudo journalctl -u cloudflared -n 50    # 出现 INF Registered tunnel connection ... protocol=quic 即成功

外网测试(浏览器 UA,否则可能被 Cloudflare Bot 防护拦 403):

curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0' -I https://dsh.example.com/
# 返回 302 跳转登录页 = 隧道 + 网关都正常

Cloudflare Tunnel 常见坑

症状原因修复
curl 返回 403 Attention RequiredCloudflare Bot 防护拦截 curl 默认 UA加浏览器 UA 头重试
隧道起了但外网访问旧站点本地 DNS 缓存了旧解析(CDN 泛解析影子)sudo resolvectl flush-caches,用 dig @1.1.1.1 dsh.example.com 验证返回 CF 边缘 IP(104.21.x / 172.67.x)
服务重启后隧道不回来原 unit 是 Restart=on-failure,干净退出不重启sudo sed -i 's/Restart=on-failure/Restart=always/' /etc/systemd/system/cloudflared.servicedaemon-reload
route dns 报 code 1003域名已有 DNS 记录,route 只创建不覆盖Cloudflare 控制台删除旧记录后重试,或用 API 更新 CNAME
隧道指到 3080 后 API 403请求绕过了网关直连 dsh,触发信任检查确保 ingress 指向网关端口 3081

测试

项目自带无依赖 smoke test(mock ctx 加载插件 + 真实 HTTP 断言):

node smoke-test.mjs

覆盖:未认证页面 302、未认证 /api 401 JSON、错误密码 401、正确密码 302+Set-Cookie(HttpOnly/SameSite=Strict)、伪造 Cookie 拒绝、恶意 Host 403(DNS rebinding)、登录限速 429、安全头、WebSocket upgrade 101(未认证 401)、SSE 长连接透传。

注意事项 / 已知坑

  • dsh 信任检查:dsh 对 /api 请求有 isTrustedApiRequest() 检查——Host 必须为 loopback;带 Origin 头时 origin.host 必须 === host.host,否则 403 "forbidden"。本插件已自动改写 Host/Origin/Referer(普通请求 + WebSocket upgrade 都处理),无需额外配置;若自行实现反代请务必同步改写这三个头。
  • WebSocket 事件流:dsh web UI 依赖 /api/events.mux/api/events.host。这两个路径 GET 返回 426 upgrade required正常现象(信任检查已通过,要求升级 WebSocket);返回 403 才是信任检查失败。
  • RPC 调用格式POST /api/<namespace>/<method>,body 需带完整 client-request 结构({"type":"client-request","rpcId":"...","method":"<namespace>/<method>","payload":{}}),method 字段必须与 endpoint 用斜杠形式一致。
  • 密码来源优先级DSH_ADMIN_PASSWORD 环境变量 > config.adminPassword;两者都未设置时插件启动直接抛错。
  • 会话存储:会话表在内存中,重启 dsh 后所有会话失效(需重新登录)。
  • 多实例:网关无共享状态,多个 dsh 实例各自起网关时注意端口冲突。
  • 上游地址upstream 只能指向本机或可信内网地址(网关本身不校验上游,配错会代理到意外目标)。

License

MIT