把本机网页界面通过子域名安全开放到公网
30.2/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add jsdvjx/dshn该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · ui
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 54 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dshn(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/7 10:40:12
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 39 处,展示前 37 条)
- 写入剪贴板packages/agent/client.js:347
navigator.clipboard.writeText(text).then(() => { setCopied(tag); setTimeout(() => setCopied(''), 1200) }).catch(() => {}) - 发起网络请求packages/agent/client.js:350
const disconnect = () => { fetch('/dshn/disconnect', { method: 'POST' }).catch(() => {}) } - 发起网络请求packages/agent/client.js:355
fetch('/dshn/e2e', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ e2ePassword: value }) }) - 发起网络请求packages/agent/client.js:375
fetch('/dshn/configure', { method: 'POST', headers: { 'content-type': 'application/json' }, - 发起网络请求packages/agent/client.js:384
try { await fetch('/dshn/e2e', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ e2ePassword: e2eVal }) }) } c - 发起网络请求packages/agent/client.js:644
const tick = () => fetch('/dshn/status', { cache: 'no-store' }) - 发起网络请求packages/agent/client.js:670
const tick = () => fetch('/__dshn/devices', { cache: 'no-store', credentials: 'include', headers: { accept: 'application/json' } }) - 发起网络请求packages/agent/src/dsh-auth.ts:226
const req = http.request( - 读取本地文件packages/agent/src/index.ts:168
const raw = JSON.parse(readFileSync(path, 'utf8')) as Partial<Credentials> - 写入本地文件packages/agent/src/index.ts:191
mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/agent/src/index.ts:192
writeFileSync(path, JSON.stringify(creds ?? {}), { mode: 0o600 }) - 删除本地文件packages/agent/src/index.ts:236
try { rmSync(path, { force: true }) } catch { } - 读取本地文件packages/agent/src/index.ts:584
return readFileSync(raw) - 发起网络请求packages/agent/src/index.ts:1213
const req = http.request( - 发起网络请求packages/agent/src/index.ts:1303
const req = http.request( - 读取本地文件packages/relay/src/claims.ts:152
if (!existsSync(path)) return new ClaimStore(path) - 读取本地文件packages/relay/src/claims.ts:155
raw = JSON.parse(readFileSync(path, 'utf8')) as { claims?: unknown; banned?: unknown } - 写入本地文件packages/relay/src/claims.ts:208
renameSync(tmp, this.path) - 读取本地文件packages/relay/src/index.ts:105
try { const s = readFileSync(path, 'utf8').trim(); if (s.length >= 32) return s } catch { } - 写入本地文件packages/relay/src/index.ts:107
mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/relay/src/index.ts:108
writeFileSync(path, secret + '\n', { mode: 0o600 }) - 读取本地文件packages/relay/src/index.ts:118
tls = { cert: readFileSync(tlsCert), key: readFileSync(tlsKey) } - 写入本地文件packages/relay/src/index.ts:125
mkdirSync(dirname(claimsPath), { recursive: true }) - 读取本地文件packages/relay/src/server.ts:1087
const mtimeMs = statSync(file).mtimeMs - 读取本地文件packages/relay/src/server.ts:1089
if (cached === undefined || cached.mtimeMs !== mtimeMs) this.site.set(m[1], { mtimeMs, body: readFileSync(file) }) - 发起网络请求scratchpad/cdp-e2e-gate.mjs:28
const status = await fetch('http://127.0.0.1:3080/dshn/status').then((r) => r.json()) - 读取本地文件scratchpad/cdp-e2e-gate.mjs:31
const sess = readFileSync(JAR, 'utf8').split('\n').find((l) => l.includes('dshn_sess'))?.trim().split(/ +/).pop() - 执行外部命令来自配置/变量scratchpad/cdp-e2e-gate.mjs:36
const chrome = spawn(CHROME, [ - 发起网络请求scratchpad/cdp-e2e-gate.mjs:50
const targets = await fetch(`http://127.0.0.1:${port}/json`).then((r) => r.json()) - 删除本地文件递归scratchpad/cdp-e2e-gate.mjs:142
rmSync(profile, { recursive: true, force: true }) - 发起网络请求scratchpad/cdp-multi-mock.mjs:26
const status = await fetch('http://127.0.0.1:3080/dshn/status').then((r) => r.json()) - 读取本地文件scratchpad/cdp-multi-mock.mjs:28
const sess = readFileSync(process.env.DSHN_JAR, 'utf8').split('\n').find((l) => l.includes('dshn_sess'))?.trim().split(/ +/).pop() - 执行外部命令来自配置/变量scratchpad/cdp-multi-mock.mjs:32
const chrome = spawn(CHROME, [ - 发起网络请求scratchpad/cdp-multi-mock.mjs:45
const targets = await fetch(`http://127.0.0.1:${port}/json`).then((r) => r.json()) - 删除本地文件递归scratchpad/cdp-multi-mock.mjs:141
rmSync(profile, { recursive: true, force: true }) - 发起网络请求scratchpad/e2e-multidevice.mjs:46
const req = http.request({ host: '127.0.0.1', port, path, method }, (res) => { - 删除本地文件递归scratchpad/e2e-multidevice.mjs:157
rmSync(dir, { recursive: true, force: true })
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 本机界面公网转发
- 子域名公开访问
- 可选端到端加密
README
由 DeepSeek 最新模型翻译生成dshn — DeepSeek Harness Network
English · 中文
awesome · DSH plugin npm license
把本机运行的 DeepSeek Harness(dsh)网页界面,通过 .ds.hn 子域名安全地开放到公网,并由登录门禁把守。安装插件、在本地打开 dsh,设置里的表单会让你填一个子域前缀和一个密码——这两项就是凭据。无需 token、无需环境变量、无需任何预置。还可选设置一个端到端密码加密流量,连中继运营者也只能看到密文。
⚠️ dsh 内置 bash 与文件系统工具,公网可达的 dsh 界面就是一个远程 Shell。 中继的登录门禁不是可选项,不要关掉它。请使用高强度密码,敏感场景优先启用端到端加密。
特性
- 零配置凭据。 在 dsh 设置里填一次 (子域, 密码) → 插件即认领子域并连接。凭据持久化到 dsh 自己的 ~/.dsh/settings.yaml,重启自动重连。
- 信任首次使用(TOFU)。 首个认领空闲子域的 agent 设定其密码(在中继上以 scrypt 哈希存储);此后的连接与每一次浏览器登录都必须匹配它——防抢占。
- 多设备。 多台机器可用同一凭据绑定同一个子域,各自显示为一台具名设备。
展开完整文档(README 剩余 1 节)
dshn — DeepSeek Harness Network English · 中文 awesome · DSH plugin npm license 把本机运行的 DeepSeek Harness(dsh)网页界面,通过 .ds.hn 子域名安全地开放到公网,并由登录门禁把守。安装插件、在本地打开 dsh,设置里的表单会让你填一个子域前缀和一个密码——这两项就是凭据。无需 token、无需环境变量、无需任何预置。还可选设置一个端到端密码加密流量,连中继运营者也只能看到密文。 ⚠️ dsh 内置 bash 与文件系统工具,公网可达的 dsh 界面就是一个远程 Shell。 中继的登录门禁不是可选项,不要关掉它。请使用高强度密码,敏感场景优先启用端到端加密。 特性 - 零配置凭据。 在 dsh 设置里填一次 (子域, 密码) → 插件即认领子域并连接。凭据持久化到 dsh 自己的 ~/.dsh/settings.yaml,重启自动重连。 - 信任首次使用(TOFU)。 首个认领空闲子域的 agent 设定其密码(在中继上以 scrypt 哈希存储);此后的连接与每一次浏览器登录都必须匹配它——防抢占。 - 多设备。 多台机器可用同一凭据绑定同一个子域,各自显示为一台具名设备。有 ≥2 台在线时,打开链接会出现设备选择页,页面侧栏底部也有切换器;选择按浏览器记住(路由 cookie),切换即对另一台机器做一次干净的重载。仅一台在线时行为与从前完全一致。 - 可选端到端加密(默认关闭)。一个独立的 e2e 密码(绝不发往中继)加密 /api 请求体与事件流:PBKDF2-SHA256(21 万次)→ AES-256-GCM。访客在浏览器里输入一次即可,可按设备记在 localStorage(永不传输)。 - 原生 UI。 配置就在 dsh 自己的设置里(「公网转发」),页脚一行实时显示延迟并可点入。 - 上行压缩。 响应体在进入隧道前先 gzip——agent→中继这一跳才是窄口,而 dsh 自己的 web 服务默认不做任何压缩。一次冷加载的线上字节数从约 12.5 MB 降到约 5.0 MB(2.5 倍);dsh 已经编码过的响应原样透传。 - 自持数据面。 流量经 Cloudflare 边缘回到你自己的服务器——无需每用户的 Cloudflare 账号,无需 NS 委派。 dsh 版本兼容 已对 dsh 0.1.5-rc.1 实测通过(同时保持对更早版本可用)。 从 dsh 0.1.2-rc.1 起,dsh 给应用外壳和每一次 /api 调用都加了一道签名的、与 Host 绑定的浏览器会话 cookie:浏览器要靠打开 dsh 打印的那个带 token 的启动 URL 才能换到它,其余一律 401 dsh web authentication required。公网访客不可能持有这个 cookie——他们浏览器里的 cookie 属于公网域名,而 agent 回放的每个请求 Host 都被改写成了 loopback,dsh 又是按请求到达时的 Host 校验 cookie 的。所以 agent 改为向 dsh 自己的 connection 服务取本进程的启动 token,在 loopback 上兑换一次,再把拿到的 cookie 盖在每一个回放请求和隧道内的 WebSocket 升级上。这个 cookie 始终不出本机:中继和访客浏览器都看不到它,访问控制仍然由中继的登录把关。 面对没有这道围栏的旧版 dsh,agent 会自动识别并保持原有行为。 dsh ≥ 0.1.2 必须搭配 agent 0.4.0。 更早的 agent 只会把一个 401 页面转发出去。 中继无需改动——修复完全在 agent 侧,已部署的中继同时服务两者。 架构 浏览器 alice.ds.hn │ HTTPS ▼ Cloudflare 边缘 (.ds.hn 代理 / 橙色云) 免费 DDoS、WAF、TLS、 │ 回源 Anycast、隐藏源站 ▼ 中继 relay (你的服务器, @dshn/relay) 登录门禁 + 子域认领表; │ 每设备一条多路复用 WSS 只搬运字节 ▼ dshn (dsh 插件, 在用户机器上) 把 HTTP + WS 重放给 dsh, │ http://127.0.0.1: Host/Origin 改写为环回 ▼ dsh (本地网页服务) 信任门禁看到的是一个环回请求 - 不改 trustedHosts。 agent 把每个转发请求的 Host/Origin 改写为环回,于是 dsh 的 /api 浏览器信任门禁把它当作任意运行时选定子域的本地同源请求接受——这正是「子域来自表单而非组合」得以成立的原因。访问由中继登录把守,而非该门禁。 - 端到端模式 在 agent 处密封请求/响应体、在浏览器里解开;中继始终是一个盲搬运者。应用外壳与插件包保持明文,以便浏览器自举并弹出解锁弹窗。它能防住被动/好奇的中继与静态数据泄露,但防不住一个主动作恶、篡改所投送 JS 的中继。 包结构 | 包 | 是什么 | 运行在哪 | | @dshn/protocol | 两端共同编译的 WSS 帧协议 | 共享 | | @dshn/agent | dsh 插件:设置表单 + 出站隧道 + 状态挂件 + e2e | 用户机器,dsh 之内 | | @dshn/relay | 登录门禁 + 认领表 + 子域路由 + HTTP/WS 桥接 | 你的服务器,Cloudflare 之后 | 认领表(packages/relay/src/claims.ts)目前是信任首次使用;账号化的控制面日后替换它。 安装 agent(用户机器) 从 npm 安装(推荐——一条命令,完全自包含): dsh plugin --profile web add @dshn/agent dsh --profile web 或从最新 GitHub Release 下载预构建 tarball: curl -L -o dshn.tgz \ https://github.com/jsdvjx/dshn/releases/latest/download/dshn.tgz dsh plugin --profile web add ./dshn.tgz 或从源码构建: pnpm install && node scripts/build-dist.mjs dsh plugin --profile web add ./dist/dshn dsh --profile web 随后在本地打开 dsh,进入 设置 → 公网转发,填写子域前缀与密码(可选端到端密码),点连接。用同一个访问密码即可从手机登录。每个子域最多跑一个 agent——相同凭据的两个 agent 会互相争抢。 agent 环境变量(全部可选,均有合理默认值): | 变量 | 默认值 | 用途 | | DSHN_ENABLED | 1 | 设为 0 则加载插件但不启用 | | DSHN_RELAY_HOST | relay.ds.hn | 中继地址;直连(绕开 Cloudflare)用 wss://origin.ds.hn:8787 | | DSHN_ORIGIN_CA | — | 钉扎自签名直连源站证书的 PEM | | DSHN_STATE | ~/.dsh/dshn-agent.json | 旧版状态文件(凭据现在存于 settings.yaml) | | DSH_HOME | ~/.dsh | dsh 主目录 | 自托管你自己的网络 你不必用 ds.hn——整套都能跑在你自己的域名上。中继以 @dshn/relay(npm)及 Docker 镜像发布;在设置表单里选 自托管、填入中继地址即可指过去(也可用 DSHN_RELAY_HOST)。完整指南(含 DNS 与 TLS 各选项):SELF-HOSTING.md。 你的服务器 —— 唯一必填的只有 apex;登录密钥自动生成并持久化, claims 与密钥都放在 --data-dir 里 npx @dshn/relay --apex tunnel.example.com --data-dir /var/lib/dshn 你的 dsh —— 或直接在 设置 → 公网转发 → 自托管 里填 DSHN_RELAY_HOST=wss://tunnel.example.com dsh --profile web Cloudflare:把 *.ds.hn(橙色云代理)指向中继源站。请把源站加固为仅接受 Cloudflare——按 Cloudflare IP 段做防火墙,并启用 Authenticated Origin Pulls(mTLS)。因为 Cloudflare 约 100 秒关闭空闲 WebSocket,两端每 25 秒心跳——已内置。若要承载持续大流量的直连隧道,加一条灰云(仅 DNS)origin.ds.hn A 记录,并让 agent 用 DSHN_RELAY_HOST + DSHN_ORIGIN_CA 指过去。 现状 对 dsh 0.1.5-rc.1 端到端可用。已知不足:偶发的隧道套接字断开会让该连接上的在途请求失败(尚无请求重放);持续大流量下 Cloudflare 可能重置隧道(改用直连源站方案);CF 免费版 100 MB 请求上限会截断较大的 dsh 图片上传;单个隧道帧上限 128 MB,低于 dsh 自己的 300 MB 请求体上限,因此超过该大小的端到端加密响应会失败;端到端加密的 /api 响应体不压缩(密文压不动);认领表仍是信任首次使用、无账号层;生产环境应把中继源站锁定到 Cloudflare IP 段并启用 Authenticated Origin Pulls。 许可 MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
jsdvjx/dshn
把本机网页界面通过子域名安全开放到公网
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,350已汉化DSH
71.5
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,506已汉化DSH
71.1
AI 矢量设计工具ZSeven-W/openpencil
全球首个 AI 原生开源矢量设计工具。
★ 7,027已汉化DSH
71.1
这是你的仓库?认领条目