用「Tailscale + 自建 DERP」把本地 DeepSeek Harness Web 远程访问从皱眉提速到 25ms

其他杂项32字数 6982阅读23分16秒阅读模式

LocalSync2026-09-08

用「Tailscale + 自建 DERP」把本地 DeepSeek Harness Web 远程访问从皱眉提速到 25ms

起因是一条慢到让人皱眉的 Cloudflare 隧道,经过一波三折的排障与两台云服务器的折腾,最终把远程访问延迟从 350~475ms 压到 23~42ms。本文按「起因 → 方案 → 实施 → 踩坑 → 结果」完整复盘,所有真实域名、IP、账号、密钥均已脱敏为占位符。


一、起因:人在外面,要访问办公室电脑上的 DSH

真正想做这件事的原因很简单:DSH(DeepSeek Harness)Web 跑在办公室一台常开机的 Windows 电脑上(HTTP 监听 127.0.0.1:3080),但我人经常不在办公室——在家里、在路上、用手机或另一台电脑,都需要随时打开它:看看运行中的任务、继续未完成的会话、取结果、发指令。

对远程访问的要求就三条:

  1. 在外面任何设备都能打开(不一定跟办公室同网);
  2. 体验接近本地,不能卡成幻灯片;
  3. 不能裸奔公网(DSH 能执行命令,还有人机会话数据,等闲之辈碰不得)。

第一版方案是「Cloudflare Tunnel + Worker Basic Auth」:公网域名(如 dsh.example.com)+ 固定密码,任何地方输密码就能进。可用,但慢

  • CF 边缘绕行:公网请求落到的 Cloudflare 边缘节点可能离你很远(实测曾落到欧洲节点,跨了大半个地球);
  • 家宽上行带宽:所有数据都从办公室家宽上传出去,上传带宽通常只有 10~30Mbps,这是硬上限。

既然该机器上本来就装着 Tailscale(基于 WireGuard 的私有组网,默认点对点直连、流量不经过任何厂家服务器),于是决定研究用它实现"又快又安全的外出访问"。本文就是这条路上从起因、踩坑到结果的完整复盘。


二、方案对比

方案 公网可达 认证方式 实测延迟
Cloudflare Tunnel + 密码 ✅ 是 用户名 + 密码 慢(边缘绕行 + 上行带宽)
Tailscale 直连(同网/打洞成功) ❌ 仅 tailnet 设备身份(登录同一账号) 28ms(NAS 实测)
Tailscale + 官方海外中继 ❌ 仅 tailnet 设备身份 350~475ms(美西中继)
Tailscale + 自建国内 DERP ❌ 仅 tailnet 设备身份 23~42ms(北京中继)

三、环境

  • 本机:Windows,DSH Web 监听 127.0.0.1:3080(pm2 托管),已装 Tailscale(tailnet 内有 NAS、另一台办公室电脑等多台设备)
  • 客户端:另一台 Windows 电脑(同一 tailnet),需要访问本机 DSH
  • 云服务器(可选,用于自建 DERP):新加坡一台、北京一台

四、第一步:Tailscale 直连

4.1 先搞懂 DSH 的 /api 信任围栏

DSH Web 对 /api 请求有一个防 DNS 重绑定的信任围栏trustedHosts):只有 Host 头命中回环或白名单的请求才放行,否则一律 403。这个名单不是认证,只是告诉 DSH"这些主机名是我自己的"。

所以用任何非回环域名访问 DSH,都必须先把主机名加进白名单。DSH 的 Web profile 补丁文件(cordis.patch.yml)里这样写:

- id: connection
  config:
    trustedHosts: ['<你的公网域名>', '<你的ts.net主机名>', ...ctx.webRuntime.trustedHosts]

改完重启 DSH Web 生效。效果验证:请求 /api/xxx403 forbidden 变成 404 not found(说明已越过围栏、进入正常路由)。

4.2 一条命令拿到 HTTPS:tailscale serve

tailscale serve --bg http://127.0.0.1:3080
  • 自动签发证书,得到 https://<主机名>.<tailnet>.ts.net(443 端口、无需带端口号)
  • 仅 tailnet 内设备可访问(这就是"不需要密码"的原因,见第七节)
  • --bg 后台常驻,配置存在 tailscaled 状态里,重启自动恢复

⚠️ 首次使用会提示 "Serve is not enabled on your tailnet":需要 tailnet 管理员在后台(https://login.tailscale.com/f/serve)点一次开关,之后才能用。

4.3 webserver 保持回环绑定

serve 是在本机完成的 TLS 终结 + 反代,它连的是 127.0.0.1:3080,所以 DSH 的 webserver 保持 127.0.0.1 绑定即可,不要开 0.0.0.0

  • 好处:不向局域网暴露一个带命令执行能力的服务
  • 如果开了 0.0.0.0,DSH 会自动把本机各网卡 IPv4(含 Tailscale 100.x)加入 /api 信任名单,裸 IP 也能访问——但整个局域网都可达,风险自担

五、为什么还是慢?——直连与中继

Tailscale 数据面默认点对点直连(WireGuard 加密,不经服务器);只有 NAT 打洞失败才退回 DERP 中继

定位工具:

tailscale ping <对端主机名>   # via DERP(xxx)=中继;via IP:port=直连
tailscale netcheck            # 看 UDP、NAT 类型、所有中继延迟

实测结果:

对端 路径 延迟
NAS 直连(IPv6 直连) 28ms ✅
另一台办公室电脑 DERP(sea/sfo) 美西中继 350~475ms ❌

两台电脑之间:netcheck 显示两端 UDP 都通、NAT 映射都稳定,却打不出直连——中国跨运营商 UDP 报文被丢弃 + 客户端无 IPv6,打洞数据包到不了对端,只能走中继。而官方中继全在海外(美西 ~170ms、新加坡 ~300ms),这就是慢的根。

结论:要么打通直连(路由器端口转发),要么把中继搬近一点(自建 DERP)。


六、自建 DERP(核心提速手段)

6.1 为什么选北京

官方中继都在海外;自建一个国内节点,延迟直接从 170~300ms 掉到几十毫秒。实测北京节点(腾讯云)延迟 39.8ms,成为全网最近中继。

6.2 部署 derper(北京节点为例)

① 编译 derper 二进制

服务器装 Go(注意:系统源里的 Go 版本可能不够新,derper 要求更高的 Go 版本;直接用官方 tarball 最稳):

cd /tmp && curl -O https://go.dev/dl/go1.26.8.linux-amd64.tar.gz \
  && mkdir -p /opt/go1.26.8 && tar -C /opt/go1.26.8 --strip-components=1 -xzf go1.26.8.tgz
export PATH=/opt/go1.26.8/bin:$PATH GOTOOLCHAIN=local GOSUMDB=sum.golang.org
go install tailscale.com/cmd/derper@latest

② 证书(DNS-01,不需要占用 80 端口)

用 acme.sh + Cloudflare DNS API 签发,务必装 fullchain(只装叶子证书会因缺中间 CA 被客户端拒绝):

export CF_Email=<你的CF邮箱> CF_Key=<你的CF API Key>
acme.sh --issue --dns dns_cf -d derp-bj.example.com --keylength ec-256 --server letsencrypt
acme.sh --install-cert -d derp-bj.example.com --ecc \
  --fullchain-file /etc/derper/certs/<域名>.crt \
  --key-file /etc/derper/certs/<域名>.key \
  --reloadcmd "systemctl restart derper"

③ systemd 常驻

[Unit]
Description=Tailscale DERP relay server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/root/go/bin/derper -hostname derp-bj.example.com -certmode manual -certdir /etc/derper/certs -a :8443 -http-port 8088 -stun-port 3478
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

④ 放行端口(两层!)

  • 服务器 OS 防火墙(firewalld):
    bash
    firewall-cmd --permanent --add-port=8443/tcp --add-port=8088/tcp --add-port=3478/udp && firewall-cmd --reload
  • 云服务商安全组(控制台层,SSH 管不到):入站 TCP 8443、UDP 3478。戴轻量云/腾讯云都容易在这层被挡——OS 防火墙开了但公网还是不通,先查安全组。

⑤ DNSderp-bj.example.com 的 A 记录指向服务器公网 IP,必须灰云(不代理),DERP 走原始 TLS 不能被中间层接管。

6.3 把节点登记进 tailnet:derpMap

Tailscale 管理后台 → Access Controls(ACL 策略),在 JSON 顶层加 derpMap

"derpMap": {
  "OmitDefaultRegions": false,
  "Regions": {
    "901": {
      "RegionID": 901,
      "RegionCode": "bj",
      "RegionName": "Beijing",
      "Nodes": [
        {
          "Name": "901a",
          "RegionID": 901,
          "HostName": "derp-bj.example.com",
          "IPv4": "<公网IP>",
          "DERPPort": 8443,
          "STUNPort": 3478
        }
      ]
    }
  }
}

⚠️ 踩坑:RegionCode 只能放在 Region 这一层,Node 里不能有,否则保存报 json: unknown field "RegionCode"

6.4 让节点真正被用上

保存 derpMap 后,两端的 Tailscale 服务都要重启,让"家区域"重新评估:

# Windows:管理员 PowerShell
Restart-Service Tailscale

关键规律:中继路径按"接收方的家区域"决定——这台机器切到北京没用,对端设备也得切(实测对端还锁在旧金山时,ping 依旧 via DERP(sea);对端重启后立刻变 via DERP(bj))。

6.5 验证

tailscale netcheck          # 看自定义区域延迟是否出现(通常 10~40ms)
tailscale debug derp 901    # 直连 DERP 节点做握手+STUN 测试
tailscale ping <对端>       # 看实际路径:via DERP(bj) in ~25ms

七、治本可选:路由器端口转发(彻底不用中继)

中继再好也是中继。直接打通 NAT 就能把中继整个省掉:

  1. tailscaled 默认监听 UDP 41641netstat 可确认);
  2. 办公室路由器加一条:UDP 41641 → 本机内网 IP
  3. 给本机做 DHCP 固定 IP(按 MAC 绑定)——不然 IP 一变规则就失效,这才是"要重加"的真正原因;
  4. 完成后 tailscale pingvia DERP(bj) 变成 via <IP>:41641,直连 10~30ms。

八、为什么 ts.net 链接不需要 Token?——私网访问的四层机制

第一次见到 https://<主机名>.<tailnet>.ts.net/ 直接就能打开、连密码都不要,很多人会心里一紧:"这样安全吗?"其实这条链接的公网暴露面为零,它把"认证"前移到了设备身份层——能打开,恰恰是因为你已经是"自己人"。四层机制层层封死:

① 域名解析层(DNS)*.ts.net 下的机器名只由 Tailscale 的 MagicDNS 提供给同一 tailnet 的登录设备。公网 DNS 服务器查不到该机器的记录——外人拿到完整链接也解析不出 IP

② 路由层(不可达私网段):即使解析成功,得到的也是 100.64.0.0/10(CGNAT)段内的 Tailscale 专有地址(如 100.83.x.x)。该地址段在公网路由器上不可路由——数据包既发不出、也进不来。

③ 传输层(WireGuard 加密):tailnet 设备之间是端到端 WireGuard 隧道;即使报文经由公网中转(如 DERP 中继),内容对任何中间者都是密文。

④ 身份层(登录即钥匙):要"拥有"那个 100.x 地址,设备必须先通过你账号的登录认证(SSO + 设备授权)加入 tailnet。能打开这个链接 = 已经证明"这台设备是你账号里的设备"。想让某人失效?后台把设备移除/吊销密钥即可,不用改任何密码。

对比一下公网入口:CF 隧道 https://dsh.example.com真·公网可达——世界上任何人敲这个域名都能触达 Cloudflare 边缘,所以门口必须挂密码锁;而 ts.net 入口的"门"在你登录 Tailscale 那一刻就锁好了,公网上根本无门可敲。

安全要点

  • 安全重心 = Tailscale 账号本身:登录用的身份提供商(如 Google)务必开启两步验证(2FA)与强密码;
  • 想更严可以加 ACL:限制只有特定设备/标签能访问本机的 443 端口;
  • DSH 内部的配置/凭据类特权 API 仍锁定回环(trustedHosts 只是"信任域名名单",不是认证)——即使 tailnet 设备也调不到,纵深防御多一层。

九、成功结果

延迟对比

阶段 路径 实测延迟
① Cloudflare 隧道 公网 + 密码 慢(边缘绕行、欧洲节点)
② Tailscale 官方美西中继 DERP(sea/sfo) 350~475ms
自建北京 DERP DERP(bj) 23~42ms(约 10 倍提升)
④ 路由器转发(待做) 直连 ~10~30ms

最终入口清单

  • https://<主机名>.<tailnet>.ts.net:tailnet 私网 HTTPS,日常主力(无需密码,设备身份即钥匙)——在外面任何登录同一 tailnet 的设备(手机/Mac/笔记本)打开即是秒开,等于把办公室的 DSH 揣进了兜里
  • https://dsh.example.com:CF 隧道公网入口(带密码),异地无 Tailscale 时的兜底

安全说明

为什么 ts.net 链接不需要密码?因为:

  • *.ts.net 域名只由 MagicDNS 提供给同一账号的登录设备,公网解析不到;
  • 解析结果是 100.x 的 Tailscale 私网段,公网不可路由;
  • 全程 WireGuard 加密;"身份鉴权"发生在登录 Tailscale 那一步——不是你的设备,链接就是死的

建议:给登录用的身份提供商(如 Google)开启两步验证;DSH 本身的配置/凭据类特权 API 仍锁定回环(私网访问也调不到),属于第三方服务的纵深防御设计。


十、踩坑汇总(一图流)

# 现象 解法
1 DSH webserver host 校验严格 CLI 传具体 IP/0.0.0.0 被拒 只允许 127.0.0.1/0.0.0.0;走补丁文件改
2 不声明 trustedHosts 非回环域名 /api 全 403 把 ts.net 域名/公网域名加进白名单
3 tailscale serve 未开启 提示"not enabled on your tailnet" 管理员后台点一次性开关
4 官方中继全在海外 国内互访 170~480ms 自建国内节点
5 跨运营商 UDP 被丢 双方 UDP 通却打不直连 接受中继 或 路由器端口转发
6 系统源 Go 版本旧 编译报 require go >= x.x.x 官方 tarball + GOTOOLCHAIN=local
7 服务端 GOSUMDB=off 工具链下载校验失败 显式 GOSUMDB=sum.golang.org
8 Windows 远程 ssh 环境污染 远端 PATH 是 Windows 路径、引号被剥 命令改写成脚本文件 scp 上去执行
9 derper http 端口冲突 bind address already in use nginx 占 80/8080,改用 8088
10 证书只装叶子 客户端报证书链错误 acme.sh 装 fullchain
11 云安全组 OS 防火墙开了公网仍不通 控制台安全组放行 8443/3478
12 derpMap 字段位置 保存报 unknown field RegionCode 只能放 Region 层
13 中继按接收方家区域 只切一端没效果 两端都重启 Tailscale 重评估
14 acme.sh 安装超时 国内服务器 github 拉不动 从已装好的服务器把脚本转传过去
15 Windows schannel 不认新 LE 根 curl 报 "Failed extracting certificate chain" 用 openssl s_client 验证;tailscaled(Go) 不受影响

十一、工具清单

  • tailscale serve / status / netcheck / ping / debug derp:链路诊断全家桶
  • acme.sh(DNS-01 签发证书)
  • derper(Tailscale 官方中继程序,go install tailscale.com/cmd/derper@latest
  • cloudflared(CF 隧道,公网兜底入口)

 
  • 本文由 asdfasd 发表于 2026-09-0817:08:32
  • 转载请务必保留本文链接:http://wp.fangfa.me/other-note/8ccb0501346e.html