JochenYang/dsh-plugins--packages-relay-server0

dsh-remote-relay

Self-hosted relay server for the dsh-remote mobile tunnel: pairing, challenge-response auth, HTTP reverse proxy and WebSocket frame bridging between a phone browser and the dsh desktop host.

AI 分析

该插件暂无 AI 分析内容。

包名
dsh-remote-relay
版本
0.1.3
许可证
MIT
最近更新
2026年9月12日

安装

此插件尚未提供可验证的 bundle,或兼容性检查未通过。请先阅读仓库说明。 阅读完整 README ↗

relay-server(dsh-remote-relay)— 自托管手机中继

License: MIT CI TypeScript Node pnpm Protocol Version PRs Welcome

简体中文 | English

dsh-remote 手机隧道的自托管中继:配对认证、HTTP 反向代理与 WebSocket 帧桥接。 单进程、零数据库(JSONL 追加存储),落盘只存 sha256 摘要。

架构

手机浏览器 ──HTTPS──> relay-server(本服务)──WS 帧──> dsh-remote 插件 ──> 本地 dsh web server
    │                     │  └───────── 下行事件流透传 ─────────┘
    ├── /pair        配对:6 位配对码 + 挑战-响应(HMAC-SHA256)
    ├── /d//*    HTTP 反向代理(流式保序)
    ├── /admin       管理台(--admin-token 启用)
    └── /ws          host 注册 / 手机握手 控制面

功能特性

  • 配对认证:6 位配对码(10 分钟 TTL、设备+IP 限速 5 次/分钟)换一次性挑战 (60s),WebSocket 完成挑战-响应;支持持令牌静默重连。
  • HTTP 反向代理:请求/响应按 ≤64KiB 帧搬运,帧序即流序(SSE / blob 不受影响); host 离线立即 409;10s 无进度防悬挂。
  • WebSocket 透传/events/* upgrade 透传为 ws-open/ws-frame/ws-close 帧。
  • 管理台:设备总览、配对码与有效期、令牌指纹、断开手机 / 吊销设备 / 删除设备、 全部/在线/离线筛选;单活跃令牌策略(重新配对自动替换旧令牌)。
  • 令牌卫生:单设备仅一个活跃令牌;孤儿与 30 天前已吊销的令牌加载时自动清理; 删除设备写入真墓碑,重启不复活。
  • PWA manifest:无鉴权静态 /manifest.webmanifest(浏览器拉取 manifest 不带 cookie,无法走代理)。

前置要求

  • Node.js ≥ 22、pnpm 11.x。
  • 公网 VPS + TLS 反代(caddy / nginx;安全上下文顺带解决手机端 crypto.randomUUID 等 Secure Context API 限制)。
  • 桌面端安装 dsh-remote 插件。

快速开始(本地联调)

pnpm install && pnpm build
node dist/cli.js --host-token devtoken-0123456789abcdef --port 8787
# 桌面端 dsh-remote 设置内连接 http://127.0.0.1:8787

生产部署(VPS)

CentOS / Rocky / Alma 一键部署:构建产物自带 deploy/install.sh (npm tarball 内),上传解包后 sudo bash install.sh 即可—— 自动装 Node 22、依赖、systemd 服务、caddy TLS 反代与防火墙放行,并生成 HOST_TOKEN / ADMIN_TOKEN 到 /etc/dsh-remote-relay.env

1. 环境与代码

sudo apt update && sudo apt install -y nodejs npm curl
node -v   # ≥ 22
sudo npm install -g pnpm

git clone  ~/dsh-configure
cd ~/dsh-configure/packages/relay-server
pnpm install && pnpm build

2. 生成令牌

HOST_TOKEN=$(openssl rand -hex 32)    # 桌面端 host 注册用
ADMIN_TOKEN=$(openssl rand -hex 16)   # 管理台登录用

3. systemd 服务

# /etc/systemd/system/dsh-remote-relay.service
[Unit]
Description=dsh-remote relay server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/root/dsh-configure/packages/relay-server
ExecStart=/usr/bin/env pnpm start -- --host-token  --admin-token  --host 127.0.0.1 --port 8787 --data-dir /var/lib/dsh-remote-relay
Restart=always
RestartSec=3
NoNewPrivileges=true
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
sudo install -o www-data -d /var/lib/dsh-remote-relay
sudo systemctl daemon-reload && sudo systemctl enable --now dsh-remote-relay
journalctl -u dsh-remote-relay -f

systemd 内仅监听 127.0.0.1,公网流量由 caddy 终结 TLS 后转发——不要裸跑 0.0.0.0。

4. TLS 反代(caddy,自动证书)

relay.example.com {
    encode gzip
    reverse_proxy 127.0.0.1:8787
}

反代排障(WebSocket 升级头)

/events/*/ws 依赖 WebSocket upgrade。caddy 原生支持、无需配置;nginx 与 EdgeOne 等 CDN 必须显式放行 Upgrade/Connection 头,否则手机端事件流会静默失败(无实时输出、状态不刷新):

location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:8787;
}

EdgeOne:在规则引擎为该域名开启 WebSocket 支持(或源站组配置 Upgrade 头透传),保存后清缓存重试。

5. 防火墙与桌面端

sudo ufw allow 80/tcp && sudo ufw allow 443/tcp

桌面端 dsh-remote「设置 → 手机连接」填入中继地址与 HOST_TOKEN, 显示"在线"后即可获取配对码。

CLI 参数

参数必填说明
--host-token host 注册共享令牌(≥16 字符)
--admin-token 管理台口令(≥8 字符);缺省禁用 /admin
--port 监听端口(默认 8787)
--host 监听地址(生产建议 127.0.0.1 + TLS 反代)
--data-dir JSONL 存储目录(默认 ~/.dsh-remote-relay
--quiet静默模式

路由总览

路由作用
/首页(配对入口)
/pair手机配对(GET 表单页 / POST {code} 换挑战+令牌)
/manifest.webmanifest静态 PWA manifest(无鉴权)
/d//*主代理入口:静态资源与 API 一律转发,WS upgrade 透传
/admin管理台(需 --admin-token
/ws?role=host|phonehost 注册 / 手机握手 控制面

管理台(/admin)

  • 启用--admin-token登录:浏览器访问 /admin,登录态 24h (HttpOnly + SameSite=Strict,独立限速 5 次/分钟)。
能力说明
设备总览hostName、完整 deviceId、在线状态、最后心跳、注册时间;全部/在线/离线筛选
配对码当前有效 6 位配对码及剩余有效期(在线主机才有)
令牌指纹每设备令牌 sha256 前缀 + 签发/吊销时间;活跃优先、超出 6 条折叠
断开手机只断当前手机会话,令牌保留
吊销设备作废全部令牌 + 断开手机 + 清配对码,并通知在线 host
删除设备仅离线设备可删:清除注册信息、全部令牌与配对记录(不可恢复)
  • 重新连接:断开手机(轻)→ 手机刷新用仍有效的配对码重配;吊销设备(重)→ 桌面端刷新配对码后重新扫码;删除设备 → 桌面端重连后以新设备身份重新注册。
  • 令牌策略:单设备仅一个活跃令牌,重新配对自动替换旧令牌(旧手机需重配)。

安全

  • 挑战-响应防重放(challenge 60s 一次性);配对码 10 分钟 TTL + 限速。
  • 落盘仅存 sha256(code) / sha256(token);日志永不打印 challenge/response/token/code。
  • HOST_TOKEN 即信任边界:谁持有它谁可注册/接管该 relay 上的 host 身份。
  • 手机 cookie 会话 HttpOnly + SameSite=Strict;管理台独立会话与限速。
  • 部署必须置于 TLS 之后(文档示例 caddy/nginx)。

协议帧格式、握手流程与安全参数见 docs/PROTOCOL.md (独立发布时请随仓库携带该文件)。

开发

pnpm build        # esbuild 产出 dist/
pnpm typecheck    # tsc --noEmit
pnpm pack         # 打包 tgz

License

MIT © 2026 JochenYang