开发者如何稳定使用 Claude Code / ChatGPT — Tailscale 全平台配置实战

MiaoDX

开发者如何稳定使用 Claude Code / ChatGPT — Tailscale 全平台配置实战 ​

作者:缪东旭(MiaoDX)| 直觉机器漫谈


这不是一篇理论文章。这是我在实际使用 Claude Code、ChatGPT API 过程中,踩坑后沉淀下来的配置手册。所有命令都经过验证,所有坑都是真实遇到的。

2026.05 更新:

  • 新增 AWS 部署方案(章节 三 BIS),现在主推 Tokyo 区域,比 Singapore 还要快 ~20ms 实测。GCP 章节保留。
  • 服务端配置改成 一组命令复制粘贴到底 的形态,重复跑也安全,包含已知最佳的性能优化。
  • 新增 附录(章节七):进阶选项与几条值得记下的排错。

一、问题是什么 ​

Claude Code、ChatGPT、GitHub Copilot、Cursor —— 这些 AI 开发工具已经是很多人的日常生产力。但在国内访问它们时,连接稳定性是个绕不开的问题:

  • 终端里 Claude Code 跑到一半断了
  • API 调用超时
  • 或者干脆连不上

我的解决方案是 Tailscale —— 一个基于 WireGuard 的 mesh 网络工具。它不需要你理解复杂的网络拓扑,装上就能用,全平台支持,让你的设备和海外的一台小服务器之间建立加密隧道。


二、整体架构 ​

架构图 ​

┌─────────────────────────────────────────────────────┐
│                 Tailscale Network                    │
│                                                     │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐      │
│  │ Mac 电脑  │    │ Linux    │    │ iPhone / │      │
│  │          │    │ 工作站   │    │ Android  │      │
│  └────┬─────┘    └────┬─────┘    └────┬─────┘      │
│       │               │               │             │
│       └───────────────┼───────────────┘             │
│                       │                             │
│               ┌───────▼────────┐                    │
│               │ Tokyo 或       │                    │
│               │ Singapore VPS  │                    │
│               │ (Exit Node)    │                    │
│               └───────┬────────┘                    │
│                       │                             │
└───────────────────────┼─────────────────────────────┘
                        │
                        ▼
              Claude / ChatGPT / GitHub

流量路径对比 ​

❌ 直连(不稳定)
你的设备 ──(可能超时)──▶ Claude API

✅ 通过海外节点
你的设备 ══WireGuard 加密隧道══▶ 海外 VPS ──▶ Claude API
                                  实测 65-85ms 延迟

核心概念 ​

概念说明
tailnet你的私有网络,所有装了 Tailscale 的设备自动组网
exit node流量出口节点,你海外的 VPS 充当这个角色
split tunneling让部分流量走 VPS、部分走本地网络

三、服务端配置:GCP Tokyo / Singapore VPS ​

为什么选 Tokyo 或 Singapore ​

  • 离中国大陆近,延迟相对低
  • Tokyo 实测约 65-70ms,Singapore 约 85ms(中国移动接入),Tokyo 更稳一点
  • 日常开发完全够用
  • GCP 对带宽比较慷慨,不会动不动限流

💡 怎么选:如果只用 AI 终端工具(Claude Code/ChatGPT API),两个都行;如果你也会跑视频会议或者 latency-sensitive 的场景,选 Tokyo(asia-northeast1)。

费用 ​

项目费用
GCP e2-micro(Tokyo / Singapore)~$7-8/月
GCP e2-micro(美国免费区)免费(延迟 150-200ms)
Tailscale 个人版免费(100 台设备 / 3 个用户)
GCP 新用户试用额度$300 / 90 天

💡 GCP Always Free 额度包含一台 e2-micro,但仅限美国区域(us-west1 / us-central1 / us-east1)。如果你不介意延迟稍高,选美国区可以零成本。

步骤 ​

1. 创建 VM ​

在 GCP Console → Compute Engine → Create Instance:

  • 区域: asia-northeast1 (Tokyo) 或 asia-southeast1 (Singapore)
  • 机型: e2-micro
  • 系统: Ubuntu 24.04 LTS
  • 磁盘: 12GB Standard persistent disk(默认 10GB 长期会被 apt cache + journal 撑爆,多 2GB 一年才几毛钱)
  • 防火墙: 允许 UDP 41641 from anywhere(Tailscale 直连端口)

怎么开这条防火墙规则(VM 创建页里没有 UDP 选项,需要单独建一条 VPC 防火墙规则):

Console 操作:GCP Console → VPC Network → Firewall → Create Firewall Rule

  • Name: allow-tailscale
  • Direction: Ingress / Action on match: Allow / Targets: All instances in the network
  • Source IPv4 ranges: 0.0.0.0/0 / Protocols and ports: 勾选 UDP, 填 41641

或者一行 gcloud 搞定:

bash
gcloud compute firewall-rules create allow-tailscale \
  --direction=INGRESS --action=ALLOW \
  --rules=udp:41641 --source-ranges=0.0.0.0/0

💡 为什么要开 UDP 41641:Tailscale 在建立直连(绕开 DERP 中继)时,客户端会向 VPS 的 UDP 41641 端口做 hole punching。多数家用网络下,云厂商 stateful firewall 的状态表会自动放行回包,不开这个端口也能直连。但某些客户端网络(部分企业网/教育网/光猫的 Symmetric NAT)的 NAT 行为会让 hole punching 失败,此时 VPS 端有显式 inbound 规则可以大幅提升成功率。一劳永逸:开 UDP 41641 inbound。如果不开,最坏情况是该客户端永久走 DERP(带宽和延迟会显著变差,但功能可用)。判断方法:客户端运行 tailscale netcheck,如果 MappingVariesByDestIP: true 就是 Symmetric NAT。

2. 一键服务端配置 ​

SSH 到你的 VPS 后,复制粘贴下面整段到终端。这一段做完所有事:开 IP 转发 → 装 Tailscale → 应用已知最佳的性能优化(GRO) → 启动并 advertise 为 exit node。重复执行也安全(重启后再跑、出问题再跑都没事):

bash
# === Tailscale 服务端一键配置(重复跑也安全)===

# 1. 开 IP 转发(让本机能转发别人的流量)
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

# 2. 装 Tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# 3. UDP GRO 优化(消除一会儿 tailscale up 时会出现的 warning,吞吐量显著提升)
NETDEV=$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")
sudo ethtool -K "$NETDEV" rx-udp-gro-forwarding on rx-gro-list off
sudo tee /etc/networkd-dispatcher/routable.d/50-tailscale-gro >/dev/null <<EOF
#!/bin/sh
ethtool -K $NETDEV rx-udp-gro-forwarding on rx-gro-list off
EOF
sudo chmod +x /etc/networkd-dispatcher/routable.d/50-tailscale-gro

# 4. 启动并注册为 exit node
sudo tailscale up --advertise-exit-node

最后一行执行后,终端会输出一个 URL,在浏览器里打开、登录你的 Tailscale 账号完成认证。

💡 关于 GRO 那一段:Tailscale 1.54+ 内核会建议你打开 rx-udp-gro-forwarding,官方 benchmark 显示能让转发吞吐量从 1.3 Gb/s 提到 10.7 Gb/s(接近 10 倍)。t4g.small/e2-micro 当然达不到这种数字,但能把"实例本身的带宽上限"打满。一行命令就做了,没理由不开。原理细节见附录 7.1。

3. 在 Admin Console 里批准 exit node ​

  1. 打开 https://login.tailscale.com/admin
  2. → Machines → 找到你的 VPS
  3. → 点击菜单 → Edit route settings
  4. → 勾选 "Use as exit node" → Save
  5. 顺手再做一件事:点该设备菜单 → Disable key expiry(避免 180 天后突然断网,下文 FAQ 详细说)

服务端就配完了。


三 BIS · 也可以用 AWS Tokyo / Singapore:差别只有两处 ​

GCP 用了一段时间,最近迁到了 AWS,趁机把两边的差别记清楚。结论是:整套流程几乎一致,AWS 真正需要单独处理的只有两件事。如果你已经有 AWS 账号、或者想薅 2026 年 t4g.small 免费额度的羊毛,可以选这条路。

谁该选哪个? ​

场景建议
想要永久免费、延迟 150-200ms 能接受GCP us-central1 e2-micro Always Free
中国访问、每月可接受 $7-8GCP asia-northeast1 (Tokyo) e2-micro
中国访问、想用 2026 年免费额度AWS ap-northeast-1 (Tokyo) t4g.small ←我现在用的
已有公司账号 / 团队偏好哪个都行,配置都不复杂

实测延迟对比(中国移动接入) ​

节点tailscale ping 直连延迟
AWS Tokyo (ap-northeast-1)64-67ms(最稳)
AWS Singapore (ap-southeast-1)84-87ms
GCP Singapore (asia-southeast1)84-89ms

Tokyo 比 Singapore 稳定快 ~20ms。如果你的目标 API(Anthropic / OpenAI)服务器在美国西岸,Tokyo 到 us-west 的国际段路由也通常比 Singapore 到 us-west 短。

费用对比 ​

项目GCPAWS
实例e2-micro ~$7-8/月t4g.small 2026 年内免费(每月 750h),之后 ~$13/月
静态 IP(绑定到运行中的实例)免费免费※
出站带宽(每月免费额度)1 GB100 GB
超出后单价~$0.12/GB~$0.09-0.12/GB
架构x86t4g 是 ARM Graviton(原生 ARM 编译省心)

⭐ 2026 重点优惠:AWS 把 t4g.small 的免费额度延长到了 2026 年 12 月 31 日(每个账号每月 750h 免费,新老账号都有,包含 Tokyo 和 Singapore 区域)。一手出处:AWS T4g 产品页 | re:Post 公告 | 覆盖区域列表(FAQ)。

※ Feb 2024 起 AWS 对所有 public IPv4 都收费 $0.005/h ≈ $3.6/月,但绑到运行中实例的 EIP 仍然免费。

带宽这点值得多说一句:纯 AI 工具用法两边都不会出账。但 AWS 的"100GB/月免费"额度让"全局模式"也敢放心用,不会担心一不小心 macOS 更新走通道把账单刷出来。

AWS 配置:和 GCP 差别就两件事 ​

下面这两件是 AWS 独有、GCP 没有的:

差别 1:必须关闭 Source/Destination Check ​

这是 AWS 上做 exit node 最容易踩的坑,文档藏得很深。

AWS 每个 EC2 实例的网卡(ENI)默认会丢弃任何"源 IP 或目标 IP 不是本机"的包。但 exit node 的本质就是转发别人的流量,所以必须把这个检查关掉。

操作:EC2 Console → Instances → 选实例 → Actions → Networking → Change source/destination check → 选 Stop。

GCP 那边不需要这个动作。这是从 GCP 迁过来的人最常忽略的点。

现象:如果忘了关,Tailscale 连得上、admin console 显示 exit node 已批准,但客户端切过去之后所有外网请求都超时。在 VPS 上 tcpdump -i tailscale0 能看到包进来,就是出不去。

差别 2:用 Elastic IP,否则 stop/start 后 IP 会变 ​

GCP 的 ephemeral IP 在某些情况下会保留;AWS 的 auto-assigned public IP stop 后再 start 一定会变(reboot 不会变,只有 stop+start 会)。我亲测过:

  • 第一次启动:13.228.77.99
  • Reboot:13.228.77.99(不变)
  • Stop + Start:13.212.71.145(变了)

如果你用 ChatGPT 或 OpenAI API,IP 频繁变会被风控盯上(即便不被封号,也会多触发验证码)。所以分配一个 Elastic IP 绑定到实例:

操作:EC2 Console → Network & Security → Elastic IPs → Allocate Elastic IP address → 分配后 Actions → Associate Elastic IP address → 选你的实例 → Associate。

AWS 完整配置流程 ​

bash
# === 0-2 步在 AWS Console 操作 ===

# 0. 创建实例
#    - Region: ap-northeast-1(Tokyo,更快)或 ap-southeast-1(Singapore)
#    - AMI: Ubuntu 24.04 LTS (ARM64),owner 099720109477(Canonical 官方)
#    - Instance type: t4g.small(2026 年内免费,2 GiB RAM)
#    - 根盘: 12 GB gp3
#    - Key pair (login): "Proceed without a key pair"
#      (不需要 SSH key —— 后面用 Tailscale + EC2 Instance Connect)
#    - Network settings: 默认安全组允许 SSH from anywhere 即可
#      (没 key pair 攻击者扫到 22 端口也无法登录)
#      ★ 在 "Network settings" 旁点 "Edit" 展开后,点 "Add security group rule",加一条:
#        Type: Custom UDP, Port range: 41641, Source type: Anywhere-IPv4 (0.0.0.0/0)
#      (Tailscale 直连端口,原因见上面 GCP 章节的 💡 说明)
#      如果实例已经建好忘了加,可以事后补:
#        EC2 Console → Security Groups → 选你实例的 SG →
#        Edit inbound rules → Add rule → Custom UDP, 41641, 0.0.0.0/0

# 1. ★ Disable Source/Destination Check ★
#    EC2 Console → Actions → Networking → Change source/destination check → Stop

# 2. ★ 分配并绑定 Elastic IP ★
#    EC2 Console → Elastic IPs → Allocate → Associate → 选刚创建的实例

# === 3 步用 EC2 Instance Connect 登录后,复制粘贴一段命令 ===

# 3. Console → 选实例 → Connect → "EC2 Instance Connect" tab → Connect
#    然后把下面这一整段复制粘贴到 SSH 终端(重复跑也安全):

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

curl -fsSL https://tailscale.com/install.sh | sh

NETDEV=$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")
sudo ethtool -K "$NETDEV" rx-udp-gro-forwarding on rx-gro-list off
sudo tee /etc/networkd-dispatcher/routable.d/50-tailscale-gro >/dev/null <<EOF
#!/bin/sh
ethtool -K $NETDEV rx-udp-gro-forwarding on rx-gro-list off
EOF
sudo chmod +x /etc/networkd-dispatcher/routable.d/50-tailscale-gro

sudo tailscale up --advertise-exit-node

# === 最后两步在 admin console ===

# 4. 浏览器打开上一步输出的 URL 完成认证
# 5. login.tailscale.com/admin → Machines → 你的 VPS:
#    - Edit route settings → 勾选 "Use as exit node"
#    - 菜单 → Disable key expiry(避免 180 天后掉线)

5 个动作搞定。Console 操作 3 个(创建实例 / 关 SrcDst Check / 分配 EIP),SSH 里复制一段命令,admin console 再点两下。

验证 ​

从客户端:

bash
# 看实际连接路径是直连还是走中继
tailscale ping <你的-aws-hostname>
# 期望:pong from ... via 52.x.x.x:41641 in 65ms(直连)

# 切到 AWS 作为 exit node 后看出口 IP
curl ifconfig.me
# 期望:你的 Elastic IP

我从中国移动接入到 AWS Tokyo 的 tailscale ping 实测:

pong from aws-tk-arm via 54.95.50.5:41641 in 67ms
pong from aws-tk-arm via 54.95.50.5:41641 in 64ms
pong from aws-tk-arm via 54.95.50.5:41641 in 64ms

稳定 ~65ms,比 Singapore 快约 20ms。

💡 想自己跑一遍验证?附录 7.5 里有个 bench-exit-node.sh 脚本,测 TTFB + 带宽,附我的实测对比表。

关于 tailscale ping 输出里的 DERP — 长期容易被误读的一点 ​

tailscale ping 偶尔会先输出几行 via DERP(xxx) 然后才看到 via <IP>:41641。这是 Tailscale 的设计行为,但不影响你实际跑 Claude Code 的体验。

Tailscale 官方文档明确写:

"All connections start as relayed through a DERP server, and Tailscale then tries to upgrade them to a direct connection."

但是——只要直连建立后,Tailscale 会用 keepalive 持续维护它:

  • WireGuard 协议层默认每 25 秒 发一个 keepalive 包,专门为穿越 NAT 而设计
  • Tailscale magicsock 在活跃 peer 之间默认每 2 秒 互发心跳
  • 这些 keepalive 比任何家用路由器/CGNAT 的 UDP 超时都要短,NAT mapping 不会过期

所以你实际跑 Claude Code 时:

  • 写代码、跑脚本、过 10 分钟才发下一个 API 请求 → 直连一直保持,下一个请求零重建
  • 出去吃午饭一小时再回来 → 直连大概率还在
  • 起 tmux 持续 ping exit node 这种 trick → 不需要,keepalive 已经在做

那为什么 tailscale ping 切换 peer 时还会看到 DERP?因为 tailscale ping 是探测命令,会去激活一个之前不活跃的 peer。如果你 tailnet 里有十几个设备,最近没用过的 peer 会被 magicsock 降级,新一次 tailscale ping 触发它重新激活,前几个包走 DERP 是预期的。

判断标准:看你实际通过 exit node 跑 API 时的体验,不用看 tailscale ping 的瞬时输出。


四、客户端配置:全平台 ​

macOS ​

从 Mac App Store 或 tailscale.com/download 下载安装。

  1. 点击菜单栏图标登录
  2. 菜单栏 → Tailscale 图标 → Exit Node → 选择你的 VPS
  3. 完成。所有流量现在通过海外节点出去。

Linux (Ubuntu / Debian) ​

这是开发主力机,也是坑最多的平台(经验之谈)。

bash
# 安装
curl -fsSL https://tailscale.com/install.sh | sh

# 启动并指定 exit node(替换为你 VPS 的 Tailscale IP)
sudo tailscale up --exit-node=<你的VPS的TailscaleIP> --exit-node-allow-lan-access=true

⚠️ --exit-node-allow-lan-access=true 很重要 —— 它让局域网流量不走 VPS,否则你连打印机都连不上。

查看你的 VPS Tailscale IP:在 admin console 的 Machines 页面可以看到,通常是 100.x.x.x 的地址。

可能遇到的坑 — DNS 报错 ​

Health check: Tailscale failed to set the DNS configuration:
running /usr/sbin/resolvconf ... Failed to resolve interface "tailscale"

解决方案:

bash
# 方案 A:如果用 systemd-resolved(大多数现代 Ubuntu)
sudo systemctl restart systemd-resolved
sudo systemctl restart tailscaled

# 方案 B:如果不需要 Tailscale 管 DNS(最省事)
sudo tailscale set --accept-dns=false

⚠️ --accept-dns=false 只在客户端用。绝对不要在服务端(exit node 那台 VPS)上设这个 flag —— 它会改变所有走该 exit node 的客户端的 DNS 行为,是个隐蔽的坑(Tailscale issue #5875)。VPS 那一侧保持默认就好。

iOS ​

App Store 搜 Tailscale → 安装 → 登录 → 设置 → Exit Node → 选你的 VPS。一步到位。

Android ​

Google Play 搜 Tailscale → 安装 → 登录 → 选择 Exit Node。Android 8.0 及以上支持。

💡 Android 有个额外能力:原生支持 app 级别的分流。在 Tailscale 设置里,你可以选择只让特定 app(比如 ChatGPT、浏览器)走 Tailscale,其他 app 走本地网络。这是 Android 独有的,其他平台目前做不到。


五、使用模式 ​

所有流量都走 exit node。配置最简单,一条命令搞定:

bash
sudo tailscale up --exit-node=<VPS_IP> --exit-node-allow-lan-access=true

手机和 Mac 上就是在 Tailscale 客户端 UI 里选一下 exit node。要切回去就关掉 exit node 选项。

适合所有场景:个人电脑、手机、笔记本。需要应用级分流的话用 Android 自带的 per-app routing,或者 Mac 的 Tailscale per-app 设置。


六、常见问题 ​

Q: 我在公司内网上班,开了 Tailscale 之后内网服务(Jira/GitLab)连不上怎么办?

最简单的办法:只在需要时打开 exit node,平时关掉。Mac 和手机的 Tailscale 客户端 UI 都支持一键切换 exit node 开关。如果你需要让特定 app(比如终端里的 Claude Code)走通道、其他不走,Android 上有原生 per-app VPN 设置,Mac 可以在终端用 HTTPS_PROXY 环境变量配合本地代理。

如果非要全局走通道又同时访问公司内网,去 admin console → DNS 配 Split DNS(Restrict to domain → 公司域名 → 内网 DNS server,记得勾选 "Use with exit node")。但实测这条路偶尔会出意外的 DNS 解析问题,不如按需切 exit node 省心。

Q: Key 过期了怎么办?

Tailscale 默认 node key 180 天过期(老文章说 90 天,已经更新了),到期后 exit node 会从 tailnet 上掉下来——更糟糕的是 Tailscale 是 "fail close" 模式:客户端仍然认为该 exit node 在用,结果是"突然外网全断"。两种解决方法:

  • (推荐) admin console → Machines → 你的 VPS → 菜单 → Disable key expiry——前面流程里第 5 步顺手做了的话就不用担心。
  • 或者给设备打 tag(比如 tag:exit-sg)——带 tag 的设备默认不会过期。这是生产环境的正确做法(详见附录 7.2)。

Q: 长时间不发 API 请求,下次会不会要重新建立连接?

不会。Tailscale 在后台会一直用 keepalive 维护直连:WireGuard 每 25 秒一个 keepalive 包,magicsock 活跃 peer 之间每 2 秒一次心跳。你写代码 10 分钟、跑个长脚本、出去吃午饭,路径都一直是热的。详见三 BIS 末尾的"DERP 行为说明"。

Q: 安全吗?

Tailscale 用的是 WireGuard 加密,端到端加密,Tailscale 服务器本身看不到你的流量内容。但你的 exit node VPS 能看到解密后的流量(跟所有代理方案一样),所以一定要用自己的 VPS,不要用别人提供的 exit node。


七、附录:进阶选项 & 排错指南 ​

主流程到这里就结束了。下面这些是给"想搞清楚为什么"或"出了奇怪问题"的玩家准备的,按需查阅。

7.1 为什么主流程里的那条 ethtool 命令是必要的 ​

主流程里那条:

bash
sudo ethtool -K "$NETDEV" rx-udp-gro-forwarding on rx-gro-list off

不做的话,tailscale up 每次启动会印一行 GRO warning。这是真实可观测的性能损失:Tailscale 自家 benchmark 显示打开 UDP GRO forwarding 后,转发吞吐量从 1.3 Gb/s 提升到 10.7 Gb/s(接近 10 倍)。t4g.small/e2-micro 当然达不到这种数字,但能"打满"实例本身的网络上限。

networkd-dispatcher 那段脚本是为了让重启后自动恢复(hook 在网卡 routable 时自动触发,Ubuntu 24.04 默认装了 networkd-dispatcher)。

⚠️ 注意 rx-gro-list 必须设为 off——它会和 GRO forwarding 冲突,开错了反而拖慢。

7.2 进阶:用 tag + autoApprovers 替代手动批准 ​

每次重装 VPS 都要去 admin console 手动点"Use as exit node"和"Disable key expiry"很烦。Tailscale 的标准做法是用 tag + autoApprovers:

admin console → Access controls 里加:

jsonc
{
  "tagOwners": {
    "tag:exit-sg": ["autogroup:admin"]
  },
  "autoApprovers": {
    "exitNode": ["tag:exit-sg"]
  },
  "acls": [
    { "action": "accept", "src": ["autogroup:member"], "dst": ["*:*"] }
  ]
}

然后 admin console 生成一个带 tag:exit-sg 的 auth key,VPS 上:

bash
sudo tailscale up --advertise-exit-node \
  --advertise-tags=tag:exit-sg \
  --auth-key=tskey-auth-xxxxx

这样 exit node 自动批准、key 默认不过期。如果将来想限制只有部分设备能用这个 exit node,改 ACL 即可。

7.3 tailscale ping 切换 peer 时看到 DERP ​

正常,不影响实际使用。详见三 BIS 末尾的解释。简单说:Tailscale 会把不活跃的 peer 降级,tailscale ping 一个最近没用过的 peer 会触发重新激活,前几个包走 DERP 是预期的。但你实际通过 exit node 跑 API 时,每次请求都让该 peer 保持活跃,根本不会经历这个过程。

7.4 排错命令速查 ​

bash
systemctl status tailscaled --no-pager
journalctl -u tailscaled -e --since '1 hour ago'
sudo tailscale status              # 看 peer 状态
sudo tailscale netcheck            # 看本机网络条件
sudo tailscale ping <peer>         # 看到具体 peer 的实际路径

实践上 tailscaled 非常稳,更常见的问题是实例本身被 stop/start 导致 IP 变了——这就是为什么强烈推荐绑 EIP。

7.5 想自己测一下哪个 exit node 更快? ​

下面这个脚本对每个目标 URL 跑 10 次 TTFB(首字节时间),对带宽跑 3 次 10MB 下载,然后给 min / median / max。多次取 median 才能滤掉单次 DNS 抖动、TLS 握手抖动这种噪声:

bash
#!/bin/bash
# bench-exit-node.sh <exit-node-hostname>
# Example: ./bench-exit-node.sh aws-tk-arm
# 单节点跑下来 ~25 秒,三个节点连跑 ~75 秒。

NODE=${1:?"Usage: $0 <exit-node-hostname>"}
TTFB_RUNS=10
BW_RUNS=3

echo "=== Switching to $NODE ==="
sudo tailscale up --exit-node="$NODE" --exit-node-allow-lan-access=true
sleep 2

echo
echo "=== Outbound IP ==="
curl -s --max-time 10 ifconfig.me
echo

echo
echo "=== TTFB ($TTFB_RUNS runs each, lower is better) ==="
printf "%-35s %8s %8s %8s\n" "target" "min(ms)" "median" "max"
for url in \
    https://api.anthropic.com/ \
    https://api.openai.com/ \
    https://github.com/ \
    https://www.google.com/ \
    ; do
    samples=$(for i in $(seq 1 $TTFB_RUNS); do
        curl -w "%{time_starttransfer}\n" -o /dev/null -s --max-time 10 "$url" 2>/dev/null
    done | sort -n)
    min=$(echo "$samples" | head -1)
    max=$(echo "$samples" | tail -1)
    median=$(echo "$samples" | awk -v n=$TTFB_RUNS 'NR==int((n+1)/2)')
    printf "%-35s %8.0f %8.0f %8.0f\n" "$url" \
        "$(echo "$min*1000" | bc -l)" \
        "$(echo "$median*1000" | bc -l)" \
        "$(echo "$max*1000" | bc -l)"
done

echo
echo "=== Throughput ($BW_RUNS runs of Cloudflare 10MB) ==="
bw_samples=$(for i in $(seq 1 $BW_RUNS); do
    curl -o /dev/null --max-time 30 -s -w "%{speed_download}\n" \
         "https://speed.cloudflare.com/__down?bytes=10000000"
done | sort -n)
echo "$bw_samples" | awk '{ printf "  run: %.1f Mbps\n", $1*8/1000000 }'
median_bw=$(echo "$bw_samples" | awk -v n=$BW_RUNS 'NR==int((n+1)/2)')
echo "  ---"
echo "$median_bw" | awk '{ printf "  median: %.1f Mbps\n", $1*8/1000000 }'

echo
echo "=== Tailscale path (should be 'via <ip>:41641', not DERP) ==="
tailscale ping "$NODE" | head -3

存成 bench-exit-node.sh,chmod +x,然后:

bash
./bench-exit-node.sh aws-tk-arm
./bench-exit-node.sh aws-sg-arm

我的实测结果(中国移动接入,2026.05,10 次 TTFB / 3 次带宽取 median) ​

指标AWS TokyoAWS SingaporeGCP Singapore
Tailscale ping (直连)64ms82ms111ms
Anthropic median TTFB333ms328ms381ms
OpenAI median TTFB279ms293ms312ms
GitHub median TTFB295ms332ms278ms
Google median TTFB326ms347ms340ms
Cloudflare 10MB median47 Mbps33 Mbps33 Mbps
TTFB max (噪声示例)1287ms1405ms1489ms

怎么读这张表:

  • Tailscale ping 是最稳定的信号——它就是你的 Mac 到 VPS 的物理 RTT,跟目标 API 无关。Tokyo 在这一项上稳定领先 18-47ms,物理距离决定的、不会反超。
  • 下载带宽也很稳定:Tokyo 47 Mbps 量级,比两个 Singapore 节点(33 Mbps)多 40%。物理距离 + 该路径的拥塞情况决定,多轮测都差不多。
  • TTFB median 比单次更可信,但区域差异已经不大:到 Anthropic 三家几乎打平(330ms 量级),Tokyo 在 OpenAI 和 Google 上微胜,GCP Singapore 在 GitHub 上反而最快——说明各家 CDN/边缘节点的部署策略不同,没有一个 region 是全场最优。
  • 看一下 max 列就知道为什么必须取 median:单次最坏情况能飙到 1.4 秒,是 median 的 4 倍。如果只跑 1 次就下结论,结论会被随机抖动主导。

结论:日常 Claude Code / ChatGPT 用 Tokyo——基线延迟(ping)和带宽这两个物理决定的、稳定的信号上 Tokyo 都明显胜。TTFB median 各家差距其实不大(30-50ms 量级),不是关键决策因素。如果你的工作负载有大流量传输(model checkpoint、视频会议),Tokyo 的 47 Mbps vs Singapore 的 33 Mbps 这个差距会更明显。

💡 不建议用国内"测速网站"测 exit node:那些站测的是"AWS → 国内服务器"的特定路径(比如教育网 CERNET 出口),跟你"本地 → AWS → Anthropic 美国"的实际链路完全无关。我用 USTC 测速测出来过 Tokyo 上传只有 1.94 Mbps 这种数字,但实际跑 API 完全没问题——纯粹是 USTC 那条 CERNET 链路当时拥塞,与你的使用场景没关系。

📌 关于带宽的现实情况:Claude Code / ChatGPT API 单次几十 KB,1 Mbps 都跑不到。带宽测试主要是 sanity check,确认你的隧道没出毛病。决策的两个最稳定信号是 Tailscale ping(基线延迟)和带宽(吞吐上限)——这两个物理决定,不随机抖动。TTFB 的单次值只是参考,多跑几次取 median 才有意义。


写在最后 ​

整套配置从零开始大概 30 分钟(GCP 或 AWS 都差不多)。之后就是一个 tailscale up 的事。

工具是为了让你专注于真正重要的事 —— 写代码、做项目、解决问题。网络不应该是阻碍你使用 AI 工具的瓶颈。

如果你在配置过程中遇到问题,欢迎在评论区交流。Tailscale 的文档 写得很好,遇到具体问题直接搜通常都能找到答案。


本文最初基于 2026 年 3 月在 GCP 的实际使用经验。2026 年 5 月增加了 AWS 路线、Tokyo 节点推荐、性能/排错附录。Tailscale、GCP、AWS 的产品可能会更新,请以官方文档为准。

M
MiaoDX × AI Agents
机器人研发工程师,OPC 实践者 — One Person, plus multi Claws。白天给机器人写 bug,其他时间和 AI Agents 一起做更多的事。