异地组网实战:从 frp 中转到 Tailscale 直连,SSH 延迟 410ms → 29ms

📅 2026/8/25 10:12:54
异地组网实战:从 frp 中转到 Tailscale 直连,SSH 延迟 410ms → 29ms
场景目标服务器在学校内网人在校外访问。原有方案 frp 公网 VPS 中转本文记录迁移到 Tailscale 的完整过程怎么装、怎么判断打洞成败、打洞失败后如何用 Peer Relay 兜底以及最后拿到直连的全过程。所有数据均为实测。一、frp 的结构性问题frp 的原理是把内网端口逐条映射到公网 VPS 上Mac ──→ VPS(frps) ──frp隧道──→ 校内服务器(frpc)这个架构有两个绕不开的代价所有流量过 VPS。带宽上限 VPS 带宽传文件、跑 Jupyter 全被卡死VPS 流量费也跟着涨。每个服务一条规则。想 SSH 加一条想 Web 再加一条端口开多了维护成本直线上升。frp 适合的场景是临时对外暴露一两个端口。要的是组网——设备之间任意互访——就该换思路。二、方案选型方案原理需要公网IP速度维护成本frp端口转发需要 VPS受限于 VPS每服务一条规则WireGuard 自建加密隧道需要 VPS好配置文件手写TailscaleWireGuard 自动打洞不需要直连裸链路几乎为零ZeroTierP2P 虚拟局域网不需要同上略高于 TS选 Tailscale底层就是 WireGuard控制面托管装上登录即用。它的核心逻辑是能 P2P 直连就直连流量不过任何第三方打洞失败才回落到官方 DERP 中继。关键认知DERP 节点大多在境外离我最近的是香港中继模式下速度和延迟都可能不如国内 VPS 中转。所以用 Tailscale 的成败完全取决于能不能打通直连。下文的重心就在这。三、安装与登录校内服务器Ubuntucurl-fsSLhttps://tailscale.com/install.sh|shsudotailscale uptailscale up会打印一个https://login.tailscale.com/a/xxxx授权链接复制到本地浏览器打开用 GitHub/Google 账号登录。登录后拿到虚拟 IP$ tailscaleip-4100.80.171.73确认开机自启官方脚本默认已注册 systemd 服务systemctl is-enabled tailscaled# 期望 enabled顺手到管理后台login.tailscale.com → Machines把这台服务器Disable key expiry。否则约 180 天后节点密钥过期无头服务器会掉线且需要重新浏览器认证很烦。MacApp Store 装 Tailscale或brew install --cask tailscale菜单栏登录同一账号。注意 Mac 版命令行路径特殊后面反复用到建议加 aliasechoalias tsping/Applications/Tailscale.app/Contents/MacOS/Tailscale ping~/.zshrcsource~/.zshrc四、核心技能怎么判断 Tailscale 能不能成这是本文最重要的部分。很多人装完发现慢就弃坑其实慢的原因 99% 是在走 DERP 中继而这是可以提前诊断的。1. netcheck网络体检两端各跑一次tailscale netcheck只看三个字段* UDP: true ← false 出站UDP被封直接判死 * MappingVariesByDestIP: false ← true 对称NAT打洞基本没戏 * Nearest DERP: Hong Kong ← 中继兜底位置顺带看延迟MappingVariesByDestIP是重点false表示 NAT 对不同目标使用相同的外部映射cone 型对端可以预测你的端口洞在哪打洞希望大。2. tailscale ping看流量实际走哪条路普通ping走 ICMP看不出路径。必须用tailscale pingtsping100.80.171.73两种输出天壤之别pong from ... via DERP(hkg) in 424ms ← 走香港中继慢 pong from ... via 223.100.xxx.xxx:41641 in 29ms ← 直连快判读规则前 1~2 发走 DERP 是正常的——那是协商阶段打洞完成后会升级成via 公网IP:端口连续多发全是via DERP(xxx)且末尾出现direct connection not established才是真的打洞失败tailscale ping --c 20 IP多打几发再下结论有些 NAT 组合要几十秒才完成协商。五、实战记录打洞失败与排查装好后的第一次测试就不顺利。校内端 netcheck 很健康* UDP: true * IPv4: yes, 223.100.xxx.xxx:xxxxx ← 学校出口NAT * MappingVariesByDestIP: false ← cone型理想情况Mac 端同样健康北京家宽出口 222.130.x.x* UDP: true * MappingVariesByDestIP: false * Nearest DERP: Hong Kong (124.2ms)两端都是教科书级的好 NAT理论上必通。实际结果$ tsping --c 20 100.80.171.73 pong from titan (100.80.171.73) via DERP(hkg) in 414ms pong from titan (100.80.171.73) via DERP(hkg) in 413ms ...20发全部如此 2026/08/24 03:10:08 direct connection not established20 发全走香港中继延迟稳定在 410ms 左右SSH 卡得没法用。此时体感对比frp 反而更快我的 VPS 在国内链路是两段短程DERP 绕香港还叠加共享限速。诊断结论netcheck 只测出站映射的规律性测不出入站包能否到达你。家宽运营商 CGNAT 会过滤入站 UDP校园网防火墙也可能拦入站方向——两边都拦STUN 打洞的双向探测就永远碰不上。纸面参数全好但打洞失败基本就是这个原因。六、解法Peer Relay把中继搬回国内打洞失败不等于放弃。Tailscale 从 1.86 开始支持Peer Relay把自己 tailnet 里的某台机器指定为中继节点打洞失败时流量优先走它而不是境外 DERP。我的 frp VPS华为云北京正好是现成的中继位。配完后链路变成Mac ──→ 国内VPS(peer relay) ──→ 校内服务器 ← 与frp同路径但全端口通用 Mac ══════════════════════════→ 校内服务器 ← 哪天能直连则自动升级优先级自动排序直连 peer relay DERP无需手动切换。配置步骤VPS 上三条命令# 1. 安装并登录同一账号curl-fsSLhttps://tailscale.com/install.sh|shsudotailscale up# 2. 指定为 relay 节点监听 UDP 40000sudotailscaleset--relay-server-port40000# 3. 云厂商安全组放行 UDP 40000 入站控制台操作ACL 授权管理后台 → Access controlsJSON 里加一条 grantdst必须填完整的 MagicDNS 域名或 Tailscale IP裸短主机名会报 invalid address{grants:[{src:[autogroup:member],dst:[100.127.83.114],app:{tailscale.com/cap/relay:[]}}]}src: [autogroup:member] 我名下所有设备都可使用 relay。官方不建议写*会把 tailnet 里所有设备包括未来新加入的都压到这台 VPS 上dst填 VPS 的 Tailscale IPVPS 上tailscale whoami查看保存即生效客户端几十秒内拉取新策略不用重启。验证$ tsping100.80.171.73 pong from... via peer-relay(100.127.83.114:40000:vni:619)in~xx ms ← 生效也可以tailscale status | grep peer-relay检查连接类型。七、结果意外之喜直连成功ACL 保存后再测惊喜来了$ tsping 100.80.171.73 pong from school-244 (100.80.171.73) via 223.100.xxx.xxx:41641 in 29ms直接打到学校出口的公网端口——直连29ms。比 DERP 的 410ms 快了 14 倍。推测是 VPS 加入 tailnet 后触发两端重新交换端点信息凑齐了此前缺失的打洞条件也可能是时间差让某端 NAT 映射刚好可用。不管具体机制如何结论是别在第一次打洞失败时就弃坑把基础设施relay 节点、ACL铺好多给几次协商机会。最终形态指标frpTailscale (DERP)Tailscale (直连)SSH RTT两跳国内~410ms29ms带宽上限VPS带宽共享限速两端裸带宽新增服务加规则无需配置无需配置iperf3 实测方法服务器起iperf3 -sMac 上iperf3-c100.80.171.73-t10-P4# 上行iperf3-c100.80.171.73-t10-P4-R# 下行测速时务必另开终端跑tsping确认当前是via IP:port还是via DERP——前者才是有效数据。八、避坑清单Mac 没有tailscale裸命令CLI 在/Applications/Tailscale.app/Contents/MacOS/Tailscale先加 alias。tailscale ping≠ping。判断路径只能用前者。服务器记得 Disable key expiry否则 180 天后掉线。Peer Relay 要求三端 Tailscale ≥ 1.86老版本先sudo tailscale update。ACL 里dst不认短主机名报invalid address就换成完整 MagicDNS 名或 100.x IP。netcheck 参数好≠打洞必成CGNAT 过滤入站是 netcheck 看不见的。失败时别急着换工具。/var/lib/tailscale/别删登录凭据都在tailscaled.state里删了要重新认证。iOS/Android 不能当 relay 节点但可以作为使用者。九、总结frp 解决的是暴露端口异地组网该用的是虚拟局域网两者不是竞品而是不同抽象层。Tailscale 的体验取决于打洞是否成功netchecktailscale ping两个命令即可完成全链路诊断。打洞失败时的正确姿势不是退回 frp而是自建中继Peer Relay 把境外 DERP 换成自己的国内 VPS速度下限追平 frp上限是直连裸带宽。我的案例最终以 29ms 直连收尾frp 退役。环境备注Ubuntu 22.04校内 Dell 机架服务器/ macOS Tailscale App / 华为云北京轻量服务器作 relay / 三端版本 1.86。