跳到正文

目录

Tailscale 深度拆解:基于 WireGuard 的零配置 mesh VPN

Tailscale 深度拆解:基于 WireGuard 的零配置 mesh VPN

核心判断

Tailscale 的本质是把"VPN 配置管理"从命令行、IPSec PSK、证书系统升级为身份层。它把 WireGuard 当作"传输层",自己构建"控制面"(coordination server / login server)和身份层(Google / Microsoft / GitHub OAuth)。结果是:开发者不需要管理 PSK 和 CA,不需要懂 NAT 穿透原理,不需要暴露公网端口。这正是它能在 2020 年主仓库开源后迅速获得大量 DevOps、SRE 和远程办公用户的原因。

项目坐标

维度数据
仓库tailscale/tailscale
Stars约 3.6 万(2026-09)
主语言Go
LicenseBSD-3-Clause(客户端与服务端大部分代码开源)
商业关系Tailscale 公司维护;开源社区另有 Headscale 兼容控制面
核心依赖WireGuard(Linux 内核模块或用户态实现)+ 用户态 tun 设备

Tailscale 不是传统 VPN

传统 VPN(IPSec、OpenVPN、手动配置的 WireGuard)有几个痛点:

  1. 公网 IP / 端口暴露:必须有一台有公网 IP 的机器做接入点
  2. NAT 穿透困难:家用宽带、移动网络几乎都在 CGNAT 之后,没有公网 IP
  3. 证书 / PSK 管理:每加一台设备都要同步密钥
  4. 拓扑僵硬:星型拓扑(所有流量绕中心),不适合分布式团队
  5. 配置复杂:IPSec IKEv2 的配置语法复杂到"配置 1 天,能用 1 小时"

Tailscale 用三个手段解决这些问题:

  • DERP 中继:自研的中继协议(DERP,全称 Detoured Encrypted Routing Protocol),所有节点通过 HTTPS 与 DERP 服务器通信,作为 NAT 穿透失败时的兜底路径
  • 控制面与数据面分离:节点身份由控制面(OAuth 登录)管理,节点之间不信任 IP,而是信任"经过认证的设备 ID"
  • 节点间直连优先:能直连时建立 WireGuard 直连(类 STUN 的 NAT 探测),不能直连时降级到 DERP 中继

架构:控制面 / 数据面分离

Tailscale 是典型的 “control plane + data plane” 分离架构:

                Control Plane (Tailscale coordination server)
                - 设备身份(OAuth → node key)
                - ACL 规则(基于 tag、user、group)
                - 网络拓扑(netmap)分发
                            ▲
                            │ TCP 443(Noise 协议封装)
                            │
        ┌───────────────────┴───────────────────┐
        │                                       │
    Node A                              Node B
    tailscaled daemon                   tailscaled daemon
    - WireGuard interface               - WireGuard interface
    - 与对端建立 WG 隧道                - 接收来自 A 的握手
    - 直连失败 → DERP 中继               - 直连失败 → DERP 中继
  • 控制面:每个节点定期与 coordination server 同步网络映射(netmap)、ACL 策略、节点密钥轮换等信息
  • 数据面:节点之间直接用 WireGuard 协议通信(默认 UDP 51820),控制面只负责密钥协商与策略下发

这个分离让"策略"与"流量"解耦:修改 ACL 不需要重启连接,新节点加入立即生效。所有设备组成一个私有网络,Tailscale 称之为 tailnet

WireGuard 是数据面

WireGuard 是 Jason Donenfeld 设计的现代 VPN 协议,加密套件固定:

  • Curve25519 密钥交换
  • ChaCha20 对称加密
  • BLAKE2s 哈希
  • Keyed BLAKE2s 消息认证

WireGuard 的特点是:

  • 代码量极少(官方称 Linux 内核实现约 4000 行),攻击面小
  • 加密套件固定,没有"算法协商"环节,避免配置错误
  • Linux 上运行在内核态,性能接近物理网络

Tailscale 直接复用 WireGuard 作为加密层,自己不做加密协议,只在其上做身份编排。注意:WireGuard 本身的密钥是静态的(每个节点一对长期密钥),Tailscale 的核心增量是把这些密钥的生成、分发、轮换交给控制面自动完成——这也是它区别于"手动配置 WireGuard"的根本所在。

NAT 穿透:STUN 式探测 + DERP 中继

Tailscale 的 NAT 穿透流程:

  1. 节点 A、B 上线后,向控制面注册自己的公网端点(IP:port,由类 STUN 的探测获得)
  2. A 想访问 B 的 Tailscale IP(100.64.0.0/10 网段内的地址)
  3. A 先尝试与 B 的公网端点建立 WireGuard 直连
  4. 直连成功 → 流量永远走直连(低延迟、不经过第三方)
  5. 直连失败(双方都在 NAT 后)→ 通过 DERP 服务器中继

DERP 不只是兜底:Tailscale 在全球运行 28 个区域的 DERP 中继集群(共 88 个节点,2026-09),客户端会自动选择延迟最低的节点。组织也可以自建 DERP 以满足合规与数据主权要求。

当双方都在 CGNAT 之后时,直连通常无法建立,DERP 中继就成为实际路径——所以中继的吞吐与两地距离直接决定这类场景下的体验。

快速起步

# 1. 安装
# macOS: brew install tailscale
# Linux: curl -fsSL https://tailscale.com/install.sh | sh
# Windows / iOS / Android:直接安装官方客户端

# 2. 登录(OAuth 身份认证)
sudo tailscale up
# 浏览器跳转到 Google / Microsoft / GitHub 登录
# 登录后自动获得 100.64.0.0/10 网段内的 Tailscale IP

# 3. 在另一台机器重复上述步骤
# 两台机器现在可以互访

跨平台覆盖:

  • Linux:优先用内核 WireGuard,也支持用户态实现(wireguard-go)
  • macOS / Windows:用户态 tun(utun / wintun)
  • iOS / Android:原生 SDK,系统层提供 VPN 配置
  • NAS / 路由器 / 云主机:Synology、OpenWrt、AWS、GCP、Azure 等都有官方或社区安装方式

ACL:身份驱动的策略

Tailscale 的 ACL 是 JSON 格式:

{
  "acls": [
    {"action": "accept", "src": ["group:dev"], "dst": ["tag:web:80,443"]},
    {"action": "accept", "src": ["autogroup:members"], "dst": ["*:*"]},
    {"action": "accept", "src": ["autogroup:internet"], "dst": ["*:*"]}
  ],
  "groups": {
    "group:dev": ["user1@example.com", "user2@example.com"]
  },
  "tagOwners": {
    "tag:web": ["autogroup:admin"]
  }
}

策略关键概念:

  • users / groups:来自 OAuth 身份,不是用户自己声明
  • tags:节点标签(如 tag:prod-db),用于识别节点角色,并配合 tagOwners 限制谁能打标签
  • autogroup:预定义组(autogroup:members = 所有 tailnet 成员;autogroup:internet = 有公网出口能力的节点)

策略由控制面推送到所有节点,客户端本地执行——不需要中心网关。新加入的节点默认继承 autogroup:members 权限,管理员可以收紧默认 ACL。

MagicDNS:内置内网 DNS

装好 Tailscale 后,不仅能用 IP 访问对端,还能直接用 hostname:

# 默认配置
ping my-macbook              # 解析到对端的 Tailscale IP

# 自定义 hostname
ssh pi4                       # 你的 Raspberry Pi 的 hostname
curl http://nas.local:8080    # 局域网服务

MagicDNS 把"设备 hostname → Tailscale IP"的映射自动同步,不需要维护 /etc/hosts。它还支持 split DNS:让特定域名走指定 DNS 服务器(比如公司内网域名走内网 DNS)。

共享节点 / 出口节点 / 子网路由

三个容易被忽略但很实用的能力:

  1. 共享节点:把节点 A 共享给用户 B,B 可以访问 A 上的服务,但看不到 A 的其它流量
  2. 出口节点(Exit Node):把节点 A 设为出口节点,其它节点通过 A 转发流量——相当于"借用 A 的网络出口",公共 Wi-Fi 场景很常用
  3. 子网路由(Subnet Router):节点 A 暴露它背后的局域网段(如 192.168.1.0/24),让其它 Tailscale 节点能访问 A 背后的 LAN,无需每台设备都装客户端

这也让 Tailscale 不只是"个人 VPN":把 AWS VPC 和办公网络通过一台子网路由器接通,就能实现跨云内网互通。

Tailscale SSH 与 Serve / Funnel

Tailscale 的价值不止于网络层,还提供两个开箱即用的应用层能力:

Tailscale SSH:基于身份的 SSH,免去公钥分发与管理。

sudo tailscale up --ssh
ssh pi4   # 使用 tailnet 身份认证,无需配置 authorized_keys

谁可以 SSH 由 ACL 决定,日志与审计在控制台集中可见,服务器端不需要再维护 SSH 公钥。

Tailscale Serve / Funnel:把本地服务暴露出去。

tailscale serve http://localhost:3000   # 在 tailnet 内提供 HTTPS 访问
tailscale funnel 8080                   # 暴露到公网(*.ts.net 域名)

Tailscale 自动申请并续期 HTTPS 证书(*.ts.net 通配域名),省掉自己管理证书的负担。Funnel 需要付费套餐,Serve 免费版即可使用。

与 ZeroTier、Cloudflare Tunnel 的取舍

维度TailscaleZeroTierCloudflare Tunnel
加密层WireGuard自研加密协议TLS / QUIC
控制面Tailscale 公司(可自建 Headscale)ZeroTier 公司(可自建 controller)Cloudflare
身份层OAuth邮箱 + 邀请Cloudflare Access
NAT 穿透DERP + STUN 式探测自研协议仅出站(无需穿透)
拓扑meshmesh / hub-spoke单向(公网到内网)
自托管能力Headscale(协议兼容)自建 controller不支持
免费额度设备不限 / 6 用户25 设备不限

决策建议

  • 开发者 / SRE、个人 / 小团队 → Tailscale(上手最快)
  • 需要控制面自托管、数据主权 → Headscale
  • 只把内网服务暴露给公网,不做 mesh → Cloudflare Tunnel
  • 已有 ZeroTier 节点、需要协议兼容 → 保留 ZeroTier

自托管 Headscale

Tailscale 客户端代码大部分开源,但控制面是闭源的。如果控制面必须自托管(合规、数据主权):

docker run -d --name headscale \
  -v ./data:/etc/headscale \
  -p 8080:8080 \
  headscale/headscale:latest headscale serve

客户端指向自建控制面:

sudo tailscale up --login-server=https://headscale.example.com

Headscale 是社区维护的 Tailscale 兼容控制面,API 完整,但没有官方 Web 控制台(依赖第三方 UI 或纯 CLI 操作)。功能跟进滞后于官方控制面,大规模使用前需要评估。

常见坑

1. DERP 中继的吞吐与延迟

DERP 是共享中继基础设施,跨区域大流量会受限于中继节点吞吐与两地距离。免费版不承诺带宽,关键业务请自建 DERP 或尽量走直连。

2. ACL 配置错误导致全员锁死

{"action": "drop", "src": ["*"], "dst": ["*"]}

如果手抖写了这条并推送,所有节点立刻无法互通。好在控制台的"Test ACL"功能会在推送前模拟规则,让你先看到影响范围。

3. MagicDNS 与内网 DNS 冲突

MagicDNS 默认接管 100.100.100.100 作为 DNS 服务器。如果内网已有 DNS,要配置 split DNS:

{
  "dns": {
    "routes": {
      "internal.corp": ["10.0.0.53"]
    },
    "magicDNS": true
  }
}

4. 客户端身份的吊销

节点被吊销后,已建立的 WireGuard 隧道不会立刻断开,需要等待下一次 netmap 同步(通常几分钟内)。敏感环境应配合 tailscale ping 与审计日志监控。

何时用 / 何时不用

适合

  • 远程办公 / 分布式团队
  • 跨云 VPC 互通(AWS + GCP + Azure + 自建机房)
  • 调试时让"家里电脑 / 公司电脑 / 服务器"互通
  • IoT 设备远程接入(Raspberry Pi + Tailscale)
  • 给客户共享测试环境(共享节点)

不适合

  • 对带宽与延迟要求极高、又必须长路径走 DERP 的大流量场景——建议评估自建 WireGuard 或企业级方案
  • 需要客户端在用户设备上无感安装——Tailscale 需要显式安装
  • 已深度绑定 ZeroTier / WireGuard 自建的场景——迁移成本需要评估

阅读路径

  1. 官方文档 tailscale.com/kb——先看 “How Tailscale works”
  2. 源码 cmd/tailscaled/——理解 daemon 启动流程
  3. DERP 协议实现在仓库 derp/ 目录,WireGuard 是外部依赖
  4. Headscale 文档 headscale.net——如果要自托管控制面

参考资源

参与讨论

使用 GitHub 登录。欢迎补充事实、异议与实践。