このページの目次
Tailscale アーキテクチャ
WireGuard 上にゼロコンフィグメッシュ VPN を構築する——coordination server が公開鍵と ACL を交換し、NAT 穿透で直接トンネルを確立し、不可能な場合は自動的に DERP リレーにフォールバックする。コントロールプレーンは集中型だが、データプレーンは分散型:トラフィックは中央サーバーを経由しない。
概要
Tailscale(2019)は WireGuard 上にゼロコンフィグメッシュ VPN を構築しています。coordination server が公開鍵と ACL を交換し、ノード間は NAT 穿透(STUN/UPnP/ポート予測)によって直接の WireGuard トンネルを確立します。穿透が不可能な場合は自動的に DERP リレーにフォールバックします。中核的な革新は、WireGuard の静的設定を自動管理されたメッシュオーバーレイに変えつつ、データプレーンが中央サーバーを経由しないことを維持することです。オープンソースの代替実装である headscale を用いれば、完全に自前の環境で構築することも可能です。
コントロールプレーンとデータプレーンの分離
Tailscale はピアツーピアではありません。集中型コーディネーションを伴うメッシュオーバーレイです。
コントロールプレーン (Coordination Server):
- HTTPS (REST + long-poll): 公開鍵、エンドポイント、ACL の交換
- ユーザーデータは転送されない
- オープンソースの代替: headscale
データプレーン:
- WireGuard トンネル (ユーザー空間: wireguard-go または カーネル: wireguard.ko)
- ピア間: NAT 穿透が成功すれば直接 UDP、そうでなければ DERP リレー経由
coordination server が提供するのは、ピアリスト、公開鍵、エンドポイントのヒント、および ACL ルールです。接続が確立されると、ノード間は WireGuard を介して直接通信します。
DERP
DERP (Detoured Encrypted Routing Protocol) は、Tailscale のリレーネットワークであり、直接接続が失敗した場合に使用されます。
[ノード A] → TLS → DERP サーバー → TLS → [ノード B]
DERP プロトコル:
1. ノード → DERP: HTTPS(TLS) で :443 またはカスタムポートに接続
→ 認証: ノードは自身の tailscale 秘密鍵で署名する — DERP は tailnet へのログインを必要としない
2. DERP → ノード: サーバー情報(リージョン、バージョン)
3. 以降:
- DERP は WireGuard で暗号化されたパケットを転送する(復号は不可)
- ピア検出(Peer Present / Peer Gone メッセージ)
- ping/pong によるキープアライブ
自前 DERP の構築: TLS 証明書とパブリックポートが必要です。verify-clients オプションは、tailscaled が coordination server に接続してクライアントの身元を確認することに依存しています。もし中国でのデプロイメントにおいて coordination server への接続がブロックされている場合、このオプションは使用できません。
NAT 穿透
Tailscale は WireGuard トンネルを確立する前に、まず NAT 穿透を試みます。
戦略(優先度順):
1. 両ノードが同じ LAN にいる場合 → 直接 LAN IP(ホストファイアウォールが許可している必要がある)
2. 片方が Full Cone NAT の場合 → STUN で外部 IP:ポートを取得 → リモート側から接続
3. 両方が Symmetric NAT の場合 → ポート予測 + バースデー攻撃:
各ピアは同時に相手の推定ポートに向けて UDP パケットを送信(複数のポートをプローブ)
→ 何らかのペアが一致すれば直接接続可能
4. UPnP/NAT-PMP/PCP: ルーターがサポートしていれば → ポートマッピング → 公网 IP と同等
5. 上記すべてが失敗した場合 → DERP リレー(フォールバック)
ポート予測:
NAT のポート割り当てパターンを観察する(インクリメント、ハッシュ、ランダム):
インクリメント: port_N = base_port + N
ハッシュ: port_N = f(proto, src_ip, src_port, dst_ip, dst_port)
ランダム: 予測不可能 → 穴あけ不可能 → DERP のみ
参考
- tailscale blog: 「How NAT traversal works」
- headscale: github.com/juanfont/headscale
- DERP: tailscale.com/kb/1232/derp
キーワード: Tailscale, coordination server, DERP, NAT 穿透, ポート予測, wireguard-go, headscale, ACL