Fly.io の WireGuard 改善点
- Fly.io はコンテナを VM に変換し、Firecracker の力を活用して世界中のハードウェア上で実行している。
- WireGuard を多用しており、今では顧客向け API の一部になっている。
flyctl CLI を実行するたびに TCP/IP スタックを生成し、一意の IPv6 アドレスを使って Fly Machines と直接通信する。
- このアプローチには長所と短所があり、いくつかの改善点がある。
以前の状況
- 世界各地の「ゲートウェイ」サーバーが WireGuard 接続を受け付け、適切なプライベートネットワークに接続する役割を担っていた。
flyctl を実行するたびに、バックグラウンドエージェントプロセスを生成するか接続していた。
- エージェントは GraphQL API で新しい WireGuard ピア設定を生成していた。
- API は NATS メッセージングシステムを通じて、適切なゲートウェイにピア設定を送信していた。
- ゲートウェイでは
wggwd サービスが設定を受け取り、SQLite データベースに保存してカーネルに追加していた。
- API が GraphQL リクエストに応答して設定を返し、
flyctl が WireGuard ピアに接続していた。
- NATS は高速だが配信保証はなく、ゲートウェイに残っている古いピアを整理していなかった。
より良い方法
- WireGuard ピアの保存には複雑なデータベースは必要ない。
- ゲートウェイが必要なときに API から設定を取得するように変更した。
- クライアントが接続を望むときだけカーネルにピアを追加し、不要になれば削除できる。
JIT WireGuard ピアの実現
- Linux カーネルの WireGuard 設定インターフェースは Netlink を使う。
- WireGuard の接続要求パケットは、BPF フィルターとパケットソケットで識別して横取りできる。
- WireGuard には「クライアント」と「サーバー」という概念はなく、ポイントツーポイントのプロトコルである。
flyctl がゲートウェイに UDP パケットを送ると、それは handshake initiation である。
- BPF フィルターを使って受信接続を捕捉できる。
- Noise プロトコルフレームワークに基づいているため、リクエストを識別するには復号が必要になる。
- イベントフィードを作成して、ゲートウェイへの接続を試みるすべてのユーザーの公開鍵を取得できる。
- 新しいピアが見つかるたびに、内部 HTTP API リクエストを通じてそのピア情報を取得し、インストールする。
アプリを分単位でローンチ
- Fly.io ではアプリを迅速にデプロイし、独自の JIT WireGuard ピアを取得できる。
グラフを見てみる
- このシステムを数週間運用した結果、ゲートウェイに残っていた古い WireGuard ピアの数を大幅に減らした。
- ゲートウェイはより軽い状態を保ち、ピア設定も高速化された。
- Grafana チャートを通じて、切り替え当日の成功した結果を共有している。
GN⁺ の意見
- Fly.io の WireGuard 改善は、ネットワーク性能と安定性を大きく向上させる好例である。
- このアプローチは、特にクラウドベースのサービスにおいて、ネットワークトラフィック管理とセキュリティの強化に役立つ可能性がある。
- 類似機能を提供する他のプロジェクトとしては Tailscale や ZeroTier があり、これらも個人および企業ユーザー向けに VPN の代替手段を提供している。
- WireGuard を導入する際には、ネットワーク構成、セキュリティポリシー、互換性などを考慮する必要がある。
- この技術を選ぶことで得られる利点は高速な性能とシンプルな構成だが、既存インフラとの統合や管理の面では課題になる可能性がある。
1件のコメント
Hacker Newsのコメント
db製品で一貫性のない接続断が起きた問題に触れている。