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

场景:目标服务器在学校内网,人在校外访问。原有方案 frp + 公网 VPS 中转,本文记录迁移到 Tailscale 的完整过程:怎么装、怎么判断打洞成败、打洞失败后如何用 Peer Relay 兜底,以及最后拿到直连的全过程。所有数据均为实测。

一、frp 的结构性问题

frp 的原理是把内网端口逐条映射到公网 VPS 上:

复制代码
Mac ──→ VPS(frps) ──frp隧道──→ 校内服务器(frpc)

这个架构有两个绕不开的代价:

  1. 所有流量过 VPS。带宽上限 = VPS 带宽,传文件、跑 Jupyter 全被卡死;VPS 流量费也跟着涨。
  2. 每个服务一条规则 。想 SSH 加一条,想 Web 再加一条,端口开多了维护成本直线上升。

frp 适合的场景是"临时对外暴露一两个端口"。要的是组网------设备之间任意互访------就该换思路。

二、方案选型

方案 原理 需要公网IP 速度 维护成本
frp 端口转发 需要 VPS 受限于 VPS 每服务一条规则
WireGuard 自建 加密隧道 需要 VPS 配置文件手写
Tailscale WireGuard + 自动打洞 不需要 直连=裸链路 几乎为零
ZeroTier P2P 虚拟局域网 不需要 同上 略高于 TS

选 Tailscale:底层就是 WireGuard,控制面托管,装上登录即用。它的核心逻辑是:能 P2P 直连就直连(流量不过任何第三方),打洞失败才回落到官方 DERP 中继

关键认知:DERP 节点大多在境外(离我最近的是香港),中继模式下速度和延迟都可能不如国内 VPS 中转。所以用 Tailscale 的成败,完全取决于能不能打通直连。下文的重心就在这。

三、安装与登录

校内服务器(Ubuntu)

bash 复制代码
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

tailscale up 会打印一个 https://login.tailscale.com/a/xxxx 授权链接,复制到本地浏览器打开,用 GitHub/Google 账号登录。登录后拿到虚拟 IP:

bash 复制代码
$ tailscale ip -4
100.80.171.73

确认开机自启(官方脚本默认已注册 systemd 服务):

bash 复制代码
systemctl is-enabled tailscaled   # 期望 enabled

顺手到管理后台(login.tailscale.com → Machines)把这台服务器 Disable key expiry。否则约 180 天后节点密钥过期,无头服务器会掉线且需要重新浏览器认证,很烦。

Mac

App Store 装 Tailscale,或 brew install --cask tailscale,菜单栏登录同一账号。

注意 Mac 版命令行路径特殊(后面反复用到,建议加 alias):

bash 复制代码
echo "alias tsping='/Applications/Tailscale.app/Contents/MacOS/Tailscale ping'" >> ~/.zshrc && source ~/.zshrc

四、核心技能:怎么判断 Tailscale 能不能成

这是本文最重要的部分。很多人装完发现慢就弃坑,其实慢的原因 99% 是在走 DERP 中继,而这是可以提前诊断的。

1. netcheck:网络体检

两端各跑一次:

bash 复制代码
tailscale netcheck

只看三个字段:

复制代码
* UDP: true                        ← false = 出站UDP被封,直接判死
* MappingVariesByDestIP: false     ← true = 对称NAT,打洞基本没戏
* Nearest DERP: Hong Kong          ← 中继兜底位置,顺带看延迟

MappingVariesByDestIP 是重点:false 表示 NAT 对不同目标使用相同的外部映射(cone 型),对端可以预测你的端口洞在哪,打洞希望大。

2. tailscale ping:看流量实际走哪条路

普通 ping 走 ICMP,看不出路径。必须用 tailscale ping

bash 复制代码
tsping 100.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 established

20 发全走香港中继,延迟稳定在 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 上三条命令)

bash 复制代码
# 1. 安装并登录同一账号
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

# 2. 指定为 relay 节点,监听 UDP 40000
sudo tailscale set --relay-server-port=40000

# 3. 云厂商安全组放行 UDP 40000 入站(控制台操作)

ACL 授权

管理后台 → Access controls,JSON 里加一条 grant(dst 必须填完整的 MagicDNS 域名或 Tailscale IP,裸短主机名会报 invalid address):

json 复制代码
{
  "grants": [
    {
      "src": ["autogroup:member"],
      "dst": ["100.127.83.114"],
      "app": { "tailscale.com/cap/relay": [] }
    }
  ]
}
  • src: ["autogroup:member"] = 我名下所有设备都可使用 relay。官方不建议写 "*"(会把 tailnet 里所有设备包括未来新加入的都压到这台 VPS 上);
  • dst 填 VPS 的 Tailscale IP(VPS 上 tailscale whoami 查看);
  • 保存即生效,客户端几十秒内拉取新策略,不用重启。

验证

bash 复制代码
$ tsping 100.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)铺好,多给几次协商机会。

最终形态:

指标 frp Tailscale (DERP) Tailscale (直连)
SSH RTT 两跳国内 ~410ms 29ms
带宽上限 VPS带宽 共享限速 两端裸带宽
新增服务 加规则 无需配置 无需配置

iperf3 实测方法(服务器起 iperf3 -s,Mac 上):

bash 复制代码
iperf3 -c 100.80.171.73 -t 10 -P 4      # 上行
iperf3 -c 100.80.171.73 -t 10 -P 4 -R   # 下行

测速时务必另开终端跑 tsping 确认当前是 via IP:port 还是 via DERP------前者才是有效数据。

八、避坑清单

  1. Mac 没有 tailscale 裸命令 ,CLI 在 /Applications/Tailscale.app/Contents/MacOS/Tailscale,先加 alias。
  2. tailscale pingping。判断路径只能用前者。
  3. 服务器记得 Disable key expiry,否则 180 天后掉线。
  4. Peer Relay 要求三端 Tailscale ≥ 1.86 ,老版本先 sudo tailscale update
  5. ACL 里 dst 不认短主机名 ,报 invalid address 就换成完整 MagicDNS 名或 100.x IP。
  6. netcheck 参数好≠打洞必成,CGNAT 过滤入站是 netcheck 看不见的。失败时别急着换工具。
  7. /var/lib/tailscale/ 别删 ,登录凭据都在 tailscaled.state 里,删了要重新认证。
  8. iOS/Android 不能当 relay 节点,但可以作为使用者。

九、总结

  • frp 解决的是"暴露端口",异地组网该用的是"虚拟局域网",两者不是竞品而是不同抽象层。
  • Tailscale 的体验取决于打洞是否成功,netcheck + tailscale ping 两个命令即可完成全链路诊断。
  • 打洞失败时的正确姿势不是退回 frp,而是自建中继:Peer Relay 把境外 DERP 换成自己的国内 VPS,速度下限追平 frp,上限是直连裸带宽。
  • 我的案例最终以 29ms 直连收尾,frp 退役。

环境备注:Ubuntu 22.04(校内 Dell 机架服务器)/ macOS + Tailscale App / 华为云北京轻量服务器作 relay / 三端版本 1.86+。

相关推荐
志栋智能1 小时前
从安全超自动化到超自动化安全的认知飞跃
运维·安全·自动化
当代红领巾1 小时前
VMware 里装好 Linux 系统没有 ipv4 地址?
linux·运维·服务器
ailsa_hui1 小时前
给50人的电子厂上数智云平台,大概要多少预算?
大数据·运维·人工智能
wzq11_6662 小时前
HDFS集群的高可用集群一遍过!!!
运维·debian
Vcaker2 小时前
Linux学习22-openstack部署与使用
linux·运维·学习
小周学学学3 小时前
vmware-horizon第四章:事件数据库配置(docker)
运维·docker·容器
姓刘的哦3 小时前
STM32的启动流分析
linux·运维·arm开发
2601_949499943 小时前
芯瑞科技 DT‑1414完全兼容HFBR‑1414TZ光模块国产化优选方案深度解析(工程师视角)
运维·网络·人工智能·科技·光模块
一路向北finish3 小时前
《CentOS7 OpenStack Mitaka 全栈部署实战:双节点搭建全流程与典型故障排坑指南》
运维·mysql·serverless·云计算·openstack