从自建DERP到Peer Relay:用阿里云ECS稳定访问内网服务
我认为 Peer Relay 解决的不是“能不能连上”,是“已经能连上,但中继链路还不够稳定”。
2024 年我在阿里云 ECS 上搭过一套自建 Tailscale DERP,当时是为了在外网访问 NAS。现在的需求变了:我需要在另一台电脑上访问家里 WSL 中的 GAG(Game Assets Generator)服务,传输图片、音频和模型资产。原来的 DERP 可以用,但延迟会从 45–53 ms 突然跳到 260 ms、287 ms,甚至 773 ms。
带宽不是完全不够。是抖。
先说结果
我没有删除原来的自建 DERP,而是在同一台阿里云 ECS 上增加了 Tailscale Peer Relay:
直连
↓ 失败
Peer Relay(UDP 40000)
↓ 不可用
自建 DERP(TCP 33445)
切换后,连续 10 次 tailscale ping 全部走 Peer
Relay,延迟稳定在 38–48 ms;ECS 服务端能看到 2 个活跃
session。实际下载一个 4.81 MB 的 GAG 资产,三次用时 1.42–1.74 秒,大约
22–27 Mbps。
Peer Relay 不是新的 DERP 配置项,它是另一条 UDP 数据路径。
Peer Relay 和 DERP 到底是什么关系
Tailscale 官方现在把连接分成三类:直连、Peer Relay 中继和 DERP 中继。三种路径的业务数据都使用 WireGuard 端到端加密,差别主要是性能,不是“用了自建中继就变成明文”。
DERP 通过 HTTPS/TCP 提供连接协商和最终兜底,穿透性很强,但大文件传输和交互性服务可能受 TCP 队头阻塞、线路抖动等问题影响。Peer Relay 是同一个 tailnet 内的一台设备用 UDP 替其他节点转发已加密流量,通常更适合高吞吐、低抖动的场景。
但这里有一个容易说错的细节:Tailscale 建立连接时仍会用 DERP 交换连接信息,然后尝试升级为直连或 Peer Relay。 Peer Relay 的数据面不经过 DERP,但 DERP 仍有协商和兜底价值。
所以我的选择不是“用 Peer Relay 替换 DERP”,是两条路径并存。
我的部署结构
外部笔记本
│
│ Tailscale / WireGuard
▼
阿里云 ECS
├─ Peer Relay: UDP 40000
└─ Custom DERP: TCP 33445 + STUN UDP 3478
│
▼
家中 WSL
└─ GAG HTTPS / MCP 服务
ECS 入站只保留三个与 Tailscale 中继相关的端口:
40000/UDP:Peer Relay。33445/TCP:自建 DERP。3478/UDP:自建 DERP 的 STUN。
SSH 通过 Tailscale SSH 进入,不需要向公网开放
22/TCP。80、443 也不是这套结构的必需入站端口。
在 ECS 上启动 Peer Relay
Peer Relay 内置在 tailscaled 里,不需要安装另一个 relay
daemon。服务端和使用 Peer Relay 的节点都需要 Tailscale 1.86
或更高版本。
先安装 Tailscale,加入自己的 tailnet:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
sudo systemctl enable --now tailscaled
再把 ECS 设为 Peer Relay:
sudo tailscale set \
--relay-server-port=40000 \
--relay-server-static-endpoints="<ECS_PUBLIC_IP>:40000"
我的 ECS 有固定公网 IPv4,所以显式声明 static endpoint。阿里云安全组同时需要允许:
Protocol: UDP
Port: 40000/40000
Source: 0.0.0.0/0
Direction: Inbound
0.0.0.0/0 看上去很宽,但 Peer Relay
不是一个任意公网用户都能调用的通用 UDP 代理。它只为同一 tailnet 且获得
grant 授权的节点分配中继绑定,转发的也是端到端加密数据。
Access Controls 里的 grant 才是真正的开关
我一开始已经在 ECS 上看到 UDP 40000 监听,从外部发 UDP 数据包,ECS
也确实抓到了。但客户端仍然走 DERP(MyDerps)。
这是因为安全组只解决“包能不能到 ECS”,grant 才决定“这个节点有没有资格使用 Peer Relay”。
在 Tailscale Admin Console 的 Access Controls 中,可以在旧的
ACLs 之外新增一个顶层 grants 字段:
"grants": [
{
"src": ["<GAG_WSL_TAILSCALE_IP>"],
"dst": ["<ECS_TAILSCALE_IP>"],
"app": {
"tailscale.com/cap/relay": []
}
}
]
这里最反直觉的是 src。
src
不是“谁发起了访问”,是“哪些稳定资源允许别人通过这个 Peer Relay
访问”。
在我的场景里,src 是家中运行 GAG 的
WSL,dst 是运行 Peer Relay 的 ECS。外部笔记本不需要填进
src,除非我还需要从其他设备反向访问这台笔记本。
我最后使用了 Tailscale IP,因为当时的策略编辑器没有接受我直接填入的
MagicDNS 短名。如果要增强可读性,可以用 policy 中的 Hosts
为 IP 定义显式别名。
不建议为了省事写:
"src": ["*"]
官方文档也明确警告过宽的 src 可能让不必要的设备尝试使用
Peer Relay,反而增加绕路和流量。我只把
NAS、WSL、家庭服务器这类“稳定位置且需要被访问”的设备放进去。
怎么确认真的走了 Peer Relay
不能只看端口有没有监听。我现在用三层验收。
1. 客户端是否收到 Relay 候选
tailscale debug peer-relay-servers
未授权时我看到的是:
[]
grant 保存生效后,列表中出现 ECS 的 Tailscale IP。
2. 实际路径是否从 DERP 切换
tailscale ping --c 10 <PROTECTED_DEVICE>
成功时的关键输出是:
pong from <device> via peer-relay(<ECS_PUBLIC_IP>:40000:vni:1) in 41ms
如果显示:
via DERP(<region>)
说明还在走 DERP。direct connection not established
不代表 Peer Relay 失败,它只表示没能升级成直连;只要前面显示
peer-relay(...),Peer Relay 就已经承载这条连接。
3. ECS 是否真的在转发
sudo tailscale debug peer-relay-sessions
我的验收结果是:
Server port: 40000
Sessions count: 2
这三层分别回答三个问题:控制面是否授权,客户端是否选中,服务端是否转发。三个都对,才算真的部署完成。
这次遇到的两个假象
端口通了,不等于 Peer Relay 生效
我曾经在 ECS 上用 tcpdump 抓到外部主机发到 UDP 40000
的数据包,但 peer-relay-servers 仍然是空数组,服务端
session 也是 0。原因不在阿里云安全组,在 Access Controls 还没有
grant。
健康检查很快,不等于真实资产传输很稳
GAG 的 /health
只有很小的响应,它可以证明服务存活,不能代表几 MB
的图片或模型传输不抖。所以我另外用带签名的真实资产 URL
做了三次下载测试。
可观测性不是一个 ping。是控制面、路径、服务端 session
和业务流量四层证据。
BBR + fq 要不要开
我最后在 ECS 上启用了 BBR + fq:
sudo modprobe tcp_bbr
sudo tee /etc/sysctl.d/99-bbr.conf >/dev/null <<'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF
sudo sysctl -p /etc/sysctl.d/99-bbr.conf
但要说清楚:BBR 是 TCP 拥塞控制,它主要影响原来的 TCP DERP,不是 Peer Relay 生效的必要条件。Peer Relay 走 UDP 40000,真正决定它能否工作的是 Tailscale 版本、UDP 可达性和 grant。
要不要删掉自建 DERP
我的结论是:暂时不删。
Peer Relay 的数据传输不依赖自建
DERP,但酒店、校园网、公司网可能阻断陌生 UDP 端口,而 HTTPS/TCP 形式的
DERP 穿透性更强。我的 tailnet policy 还设置了
OmitDefaultRegions: true,如果再关闭自建 DERP,Peer Relay
不可用时就失去了最后兜底。
所以现在这台 ECS 上有两个职责:
tailscaled提供 UDP Peer Relay,承担日常高性能中继。derper提供 TCP DERP,承担最终兜底。
这不是重复建设,是两种不同失败条件的保险。
如果之后换 ECS
我把部署动作收进了一个独立的网络配置目录,里面包含:
- Peer Relay 部署脚本。
- 验收脚本。
- Access Controls grant 模板。
- BBR + fq 持久化配置。
- 迁移和回滚说明。
新 ECS 的迁移顺序应该是:新旧节点并行,先验证新 Peer Relay,再迁移 DERP,最后释放旧机。不要把“换服务器”变成一次不可回滚的网络切换。