用手机随时随地连回家中电脑上的 DSH 界面
29.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/8 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add wdl2055867434/dsh-tailscale-relay该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 手机远程访问电脑界面
- Tailscale组网
- VPS中继节点
在手机上随时随地访问你 PC 上的 DeepSeek Harness。Tailscale + tailscale serve + 自建 VPS 中继节点。附踩坑实录(中继端口必须是 443)。
README
由 DeepSeek 最新模型翻译生成dsh-tailscale-relay
用手机随时随地访问家里电脑上的 DeepSeek Harness(DSH) —— 不需要公网 IP、不需要路由器端口映射、不受 CGNAT / 运营商 NAT 影响。
在家走局域网直连(1ms),出门走自建香港中继(约 60ms),不依赖 Tailscale 的公共 DERP 节点。
手机 ──┐ ├── Tailscale (WireGuard) ──► PC 上的 DSH (127.0.0.1:19387) PC ──┘ │ └── 打不通直连时,改走自建 peer relay(VPS:UDP 443)
目录
- 它解决什么问题
- 为什么值得自己搭
- 快速开始
- 第 0 步:前置
- 第 1 步:让 DSH 接受 tailnet 主机名
- 第 2 步:用 tailscale serve 暴露 DSH
- 第 3 步:给手机造一个长期有效的登录 cookie
- 第 4 步(可选):出门也要快 —— 自建 peer relay
- 第 5 步(可选):小内存 VPS 加固
- 三个反直觉的坑
- 排查速查表
- 安全说明
- License
它解决什么问题
DSH 的 Web 界面默认只监听 127.0.0.1,这是对的 —— 但它意味着你人不在电脑前就用不了。
展开完整文档(README 剩余 1 节)
dsh-tailscale-relay
用手机随时随地访问家里电脑上的 DeepSeek Harness(DSH) —— 不需要公网 IP、不需要路由器端口映射、不受 CGNAT / 运营商 NAT 影响。
在家走局域网直连(1ms),出门走自建香港中继(约 60ms),不依赖 Tailscale 的公共 DERP 节点。
手机 ──┐ ├── Tailscale (WireGuard) ──► PC 上的 DSH (127.0.0.1:19387) PC ──┘ │ └── 打不通直连时,改走自建 peer relay(VPS:UDP 443)
目录
- 它解决什么问题
- 为什么值得自己搭
- 快速开始
- 第 0 步:前置
- 第 1 步:让 DSH 接受 tailnet 主机名
- 第 2 步:用 tailscale serve 暴露 DSH
- 第 3 步:给手机造一个长期有效的登录 cookie
- 第 4 步(可选):出门也要快 —— 自建 peer relay
- 第 5 步(可选):小内存 VPS 加固
- 三个反直觉的坑
- 排查速查表
- 安全说明
- License
它解决什么问题
DSH 的 Web 界面默认只监听 127.0.0.1,这是对的 —— 但它意味着你人不在电脑前就用不了。
常见的替代方案都有硬伤:
| 方案 | 问题 |
| 端口映射 / 公网 IP | 家里大多是 CGNAT,根本没有公网 IP;即使有,把 DSH 暴露到公网风险太高 |
| Cloudflare Tunnel / frp | 需要域名、需要第三方中转,延迟和稳定性不可控 |
| Tailscale 直连 | 可用,但手机侧常年打不通直连(运营商对称 NAT),会一直退回公共 DERP,延迟 400–600ms 且丢包 |
| 在 VPS 上做反向代理 | 流量绕一大圈,且 DSH 的 Host 栅栏会把请求拒掉 |
本方案 = Tailscale 组网 + tailscale serve + 自建 peer relay,三件事各解决一个问题:
1. Tailscale 解决「怎么找到对方的机器」,不用公网 IP
2. tailscale serve 解决「怎么安全地暴露 HTTPS」,证书自动签发,不占公网端口
3. 自建 peer relay 解决「两边都连不上直连怎么办」—— 双方各自主动连到公网固定端点,绕开对称 NAT
为什么值得自己搭
Tailscale 官方的 peer relay 文档只讲了怎么做中继,但几乎所有教程都漏掉了这条:
中继端口必须用 443。
实测数据(同一台机器、同一个中继,只改端口):
| 中继端口 | 结果 |
| UDP 40000 | 20 次里 6 次超时(30% 丢包),成功的那 14 次也退回公共 DERP,469–3035ms |
| UDP 443 | 20/20 全部走 peer relay,59–164ms,0 超时 |
原因是运营商对非标准 UDP 端口会做 QoS / 干扰,而 UDP 443 和 HTTPS/QUIC 混在一起,很难被区别对待。
另外还有几个只有自己踩过才知道的坑,都写在下面的三个反直觉的坑。
快速开始
约定:下文用 <HOST> 表示你电脑在 tailnet 里的主机名(如 my-desktop), <TAILNET> 表示你的 tailnet 名(如 example.ts.net), <RELAY_PUBLIC_IP> 表示你 VPS 的公网 IP。
替换成你自己的值再用。
第 0 步:前置
1. 电脑和手机都装好 Tailscale 并登录同一个 tailnet
2. 电脑上 DSH 正常运行,记录它监听的端口(默认 19387):
Get-NetTCPConnection -State Listen -LocalPort 19387 |
ForEach-Object { Get-Process -Id $_.OwningProcess }
3. 确认 MagicDNS 开启,电脑的 tailnet 域名能解析:
& "$env:ProgramFiles\Tailscale\tailscale.exe" status --json |
ConvertFrom-Json | Select-Object -ExpandProperty Self |
Select-Object -ExpandProperty DNSName
应输出 <HOST>.<TAILNET>.
第 1 步:让 DSH 接受 tailnet 主机名
DSH 有一个 Host 栅栏:只接受来自回环地址的请求,其它 Host 一律 403。
必须显式把你的 tailnet 主机名加进白名单。
编辑 %USERPROFILE%\.dsh\profiles\<你的 profile>\cordis.patch.yml(profile 通常是 desktop),追加:
- id: web-runtime
name: "@deepseek-ai/dsh-web-app"
inject: [webStartup]
config:
openBrowser: false
printUrl: true
surfaceContext: true
trustedHosts:
- <HOST>.<TAILNET>
DSH 会热重载这个文件,改完不用重启。
⚠️ 两个坑
1. 这个文件里可能有中文注释,必须用 UTF-8 无 BOM 写回。PowerShell 5.1 的 Set-Content -Encoding utf8NoBOM 会报枚举错误(那是 PS7 才有的), Get-Content 默认还会按 ANSI 读,把中文读成乱码。用 .NET: $p = "$env:USERPROFILE\.dsh\profiles\desktop\cordis.patch.yml" $enc = New-Object System.Text.UTF8Encoding($false)
$text = [System.IO.File]::ReadAllText($p, $enc)
[System.IO.File]::WriteAllText($p, $text, $enc)
2. 如果这个 - id: web-runtime 条目已经存在,不要追加第二个,直接改现有条目里的 trustedHosts 列表。
第 2 步:用 tailscale serve 暴露 DSH
$ts = "$env:ProgramFiles\Tailscale\tailscale.exe"
& $ts serve --bg --https=8443 http://127.0.0.1:19387
& $ts serve status
期望输出:
https://<HOST>.<TAILNET>:8443 (tailnet only)
|-- / proxy http://127.0.0.1:19387
(tailnet only) 表示只有 tailnet 内的设备能访问,不会暴露到公网。
验证栅栏是否放行(这是关键的一步):
curl.exe -sk -o NUL -w "%{http_code}n" https://<HOST>.<TAILNET>:8443/
必须返回 401。
- 401 = 栅栏通过,只是没登录 ✅
- 403 = Host 被拒,第 1 步没生效 ❌
第 3 步:给手机造一个长期有效的登录 cookie
DSH 的登录机制是「进程 token 换 cookie」,而那个 token 每次启动随机、且只在回环可达 ——所以你没法在手机上登录。正确做法是用 DSH 自己的持久 secret 直接签一个 cookie。
secret 位置:%USERPROFILE%\.dsh\.credentials.yaml
version: 1
records:
client-connection/browser-session:
kind: grant
payload:
version: 1
secret: <43 字符 base64url,解码后 32 字节>
签名算法(与 DSH 内部的 browser-auth 一致):
authority = "<HOST>.<TAILNET>:8443" # 必须带端口、全小写
name = "dsh-auth-" + base64url( sha256(authority) )
body = base64url( JSON({"version":1,"authority":authority,
"issuedAt":<ms>,"expiresAt":<ms>}) )
value = "v1." + body + "." + base64url( hmac_sha256(secret, body) )
- base64url:标准 base64 去掉末尾 =,+→-,/→_
- HMAC 的输入是 body 这个字符串的 UTF-8 字节,不是原始 JSON
- issuedAt / expiresAt 是毫秒时间戳
仓库里的 scripts/mint-cookie.ps1 已经实现了这个算法:
生成 cookie & .\scripts\mint-cookie.ps1 -Authority "<HOST>.<TAILNET>:8443" -Days 30
立刻自测(必须 200) curl.exe -sk -o NUL -w "%{http_code}n" -H "Host: <HOST>.<TAILNET>:8443" -H "Cookie: <name>=<value>" http://127.0.0.1:19387/
这一步不通过就别往下做。 401 说明 authority 或 secret 不对,换几个 authority 变体试试(不带端口、127.0.0.1:19387、tailnet IP 等)。
然后把 cookie 送到手机上。 最简单可靠的做法:起一个登录页,让手机浏览器访问一次,由 JS 写入 cookie。
见 scripts/login-page.html —— 把里面的占位符替换掉,用任意静态服务器托管在 127.0.0.1:8799,再:
& $ts serve --bg --https=8444 http://127.0.0.1:8799
💡 登录页里的 cookie 必须带 domain=<TAILNET>,这样手机从 :8444 拿到的 cookie 才会被带到 :8443。(同一个登录页也因此可以顺便给 tailnet 里其它机器用。)
⚠️ 起静态服务器时在 Windows 上不要用 System.Net.HttpListener ——非管理员会被 http.sys 的 URL ACL 拒绝。用 TcpListener 自己写,不需要管理员权限。
手机上的使用方式:
先开一次(写入 cookie):https://<HOST>.<TAILNET>:8444/ 以后直接用: https://<HOST>.<TAILNET>:8443/
cookie 有效期按你生成时指定(建议 30 天),到期后再开一次登录页即可。
第 4 步(可选):出门也要快 —— 自建 peer relay
如果你只在家里用,可以跳过这一步。但手机在移动网络下通常打不通直连,会一直退回公共 DERP(400–600ms)。
准备一台有公网 IP 的 VPS(1 核 1G 足够,香港/新加坡延迟更低)。
在 VPS 上
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --hostname=<RELAY_HOSTNAME> --accept-dns=false
关键:显式声明公网端点。云服务器大多是 1:1 NAT,网卡上只有内网 IP, Tailscale 自己探测不到公网地址。
tailscale set --relay-server-port=443 \
--relay-server-static-endpoints=<RELAY_PUBLIC_IP>:443
然后在 Tailscale 后台的 Access controls 里加一条 grant:
{
"grants": [
// ... 你原有的规则 ... { // ⚠️ src 不接受主机名!只能用 Tailscale IP / CIDR / tag
"src": ["<TAILSCALE_IP_1>", "<TAILSCALE_IP_2>", "<RELAY_TAILSCALE_IP>"],
"dst": ["<RELAY_TAILSCALE_IP>"],
"app": {"tailscale.com/cap/relay": []}
}
]
}
改之前先把原文件备份出来。Tailscale 后台的编辑器支持 Preview changes,改动应该是纯新增、零删除。
验证:
应该列出你的中继 Tailscale IP,而不是 [] & $ts debug peer-relay-servers
应该看到 via peer-relay(...) & $ts ping -c 20 <手机或另一台的 Tailscale IP>
完整脚本见 scripts/relay-setup.sh。
第 5 步(可选):小内存 VPS 加固
1 核 1G 的机器跑 relay 够用,但会被 Ubuntu 的自动更新打爆。 典型症状:延迟突然涨到秒级、丢包、中继整个消失退回 DERP、 SSH 能建 TCP 连接但握手超时(网络栈应答 SYN,用户态进程饿死)。
排查:
free -m # 看有没有 swap uptime # 看 load average dmesg | grep -i oom
如果看到 Out of memory: Killed process ... (unattended-upgr),scripts/vps-harden.sh 一条命令搞定:
- 建 2G swapfile 并写进 /etc/fstab
- vm.swappiness=10
- 关掉 unattended-upgrades / apt-daily.timer / fwupd / snapd / multipathd
实测效果:内存占用 380MB → 213MB,负载 37.9 → 1.73,链路恢复到 30/30 中继、0 超时。
⚠️ 如果你也在 VPS 上装了 Tailscale,注意它默认会插入一条规则: -A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP 这会误伤云厂商的内部服务网段(很多云用 100.100.0.0/16 做元数据和内网 DNS),导致「云助手」「文件备份」之类的服务报「实例网络环境异常」。
修法是在它之前插一条放行(Tailscale 只用 -A 追加,所以 -I 插队有效): iptables -I INPUT 1 -s 100.100.0.0/16 -j ACCEPT
并写一个开机自愈的 systemd oneshot 单元持久化。
三个反直觉的坑
1. tailscale serve 保留原始 Host,DSH 会 403
tailscale serve 不会把 Host 改写成 127.0.0.1,而是原样转发 <HOST>.<TAILNET>:8443,并附带 X-Forwarded-Proto: https。
而 DSH 的 Host 栅栏只认回环 —— 所以必须配 trustedHosts(第 1 步)。
记住这个判定口诀:
| 返回码 | 含义 |
| 403 | Host 被栅栏拒了 → trustedHosts 没生效 |
| 401 | 栅栏通过,只是没认证 → 配置正确,去搞 cookie |
这条口诀能帮你在一秒内区分「配置问题」和「认证问题」,排查时极其省事。
2. ACL 的 src 不接受主机名
Tailscale 的 peer relay 文档说 dst 可以用主机名、tag、IP,但没说 src 不行。
实际写 "src": ["my-desktop"] 会得到:
Error: src="my-desktop": invalid address
src 只接受用户 / 组 / autogroup / tag / IP 或 CIDR。
所以老老实实用 Tailscale IP。
3. 中继端口必须用 443
见上文为什么值得自己搭。
一句话:非标准 UDP 端口会被运营商干扰,30% 丢包;换成 UDP 443 后 0 丢包。
排查速查表
| 症状 | 大概率原因 | 怎么查 |
| 浏览器打不开,ERR_CONNECTION_TIMED_OUT | 设备不在线 / 不在同一 tailnet | tailscale status |
| 403 | trustedHosts 没配或没生效 | 检查 cordis.patch.yml;DSH 会热重载,但新条目有时要重启 |
| 401 | 正常,只是没 cookie | 走第 3 步 |
| 带 cookie 仍 401 | authority 字符串不对 / secret 不对 | 见第 3 步,换 authority 变体;确认 .credentials.yaml 里只有一个文件 |
| tailscale debug peer-relay-servers 返回 [] | ACL grant 没配 / 没生效 | 检查 grant 的 src/dst/app |
| ping 一直 via DERP(...) 几百毫秒 | 中继没生效,或用了非 443 端口 | 换 443;检查安全组放行 UDP 443 |
| 延迟突然变秒级 + 丢包 + SSH 握手超时 | VPS 内存打爆 | 第 5 步 |
| 手机「文字发得出去、图片传不完」 | 链路丢包,上传是 100KB–3MB 的整块 POST | 换 443 修链路;大图比文字对丢包敏感得多 |
安全说明
- DSH 始终只监听 127.0.0.1。本方案没有把它暴露到公网。
- tailscale serve 用的是 (tailnet only),只有你 tailnet 内的设备能访问。
- 登录 cookie 是 HMAC 签名的,它的安全性完全取决于 .credentials.yaml 里的 secret —— 不要把这个文件提交到任何仓库。
- cookie 建议设 30 天,并用 domain=<TAILNET> 限制作用域(不要用 domain= 留空)。
- 如果担心手机丢失:Tailscale 后台可以随时移除该设备,cookie 也就一起失效了。
- .gitignore 里已包含 .credentials.yaml、.key、id_ 等。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
wdl2055867434/dsh-tailscale-relay
用手机随时随地连回家中电脑上的 DSH 界面
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,270已汉化DSH
70.8
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。