1 ポイント 投稿者 GN⁺ 2024-03-14 | 1件のコメント | WhatsAppで共有

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件のコメント

 
GN⁺ 2024-03-14
Hacker Newsのコメント
  • LinuxカーネルのWireGuardには、要求時にピアをインストールする機能がなく、そのため設計上の問題が生じるとのことです。

    • Linuxカーネル版WireGuardには、要求に応じてピアをインストールする機能がないため、設計が難しくなっている。
    • 実行時にピアを追加することはできるが、不要なエントリを防ぐため、インターフェースに追加する前にピアを認証したいようだ。
    • eBPFフィルタを使って、認証済みの相手との暗号鍵ルーティングベースの接続を直接管理し、検証が完了したらピアをインターフェースに追加し、タイムアウト後に削除する。
  • HTTPリクエストのほうがメッセージキュー経由のルーティングより信頼性が高いという点には同意しますが、NATSによって失われたメッセージがサービスに大きな影響を与えたというのは驚きでした。

    • 直接のHTTPリクエストのほうがメッセージキューより信頼性が高いという意見には同意するが、NATSでのメッセージ損失がサービスにかなりの影響を与えた点は意外だとしている。
    • メッセージが失われた場合、NATSは再送を試みるはずだと考えられるが、なぜ目立つ信頼性の問題が発生したのか疑問を示している。
  • 最近の実験的なプロジェクトを紹介したいです。ユーザー空間のWireGuardピアとして動作するGoアプリの構築に興味があるなら、見てみてください。

    • ユーザー空間のWireGuardピアとして動作するGoアプリを作りたい人向けに、自身のプロジェクトを紹介している。
    • wireguard-goの優れた成果を土台にしつつ、ライブラリ利用により適した形へ単純化したいとしている。
    • サービスメッシュの構築に関心があり、多言語対応は難しいかもしれないが、ソケットAPIは実装できるだろうと考えている。
    • WireGuardの暗号化に対するハードウェアアクセラレーションはまだ見当たらず、mTLSと競争するのは難しいかもしれないと述べている。
    • 高速・安全なネットワーキング分野でフリーランスとして活動しており、興味があれば連絡してほしいとしている(メールはプロフィール参照)。
  • WireGuardをWebSockets上にトンネリングするのがデフォルト設定だというのは興味深いです。性能面では良くないですが、flyctlが使われるDevOps作業には適しているでしょう。

    • WireGuardをWebSockets経由でトンネリングするのがデフォルト設定である点に注目している。
    • 性能面では最適ではないものの、flyctlが使われるDevOps作業では問題ないだろうと見ている。
    • QUIC/HTTP3の今後が気になるとして、ネットワーク事業者がUDPの443番ポートを遮断する代わりに、きちんと扱うようになるのか疑問を呈している。
  • 私たちは送信側としてピアをインストールでき、flyctlが応答側です。Linuxカーネルはflyctlに対してWireGuard接続を開始します。この方法は機能し、プロトコルはサーバーとクライアントのどちらがどちらかをあまり気にしません。新しい接続はできるだけ速くインストールされます。

    • 送信側としてピアをインストールし、flyctlが応答側となってLinuxカーネルがWireGuard接続を開始する仕組みを説明している。
    • プロトコルはサーバーとクライアントの役割にそれほど縛られず、新しい接続は非常に素早く確立できると述べている。
  • 私のスタートアップはほぼ1年間Flyを使っていました。コードをデプロイ済みのコードに1分以内で切り替えられる中核機能は見事です。数秒で新しいノードをスピンアップ/ダウンできます。

    • スタートアップで約1年間Flyを使った経験を共有している。
    • コードを素早くデプロイできる機能は高く評価している一方で、会社としてはやや未成熟だと感じている。
    • APIサーバーがFly上で48時間アクセス不能だった経験や、db製品で一貫性のない接続断が起きた問題に触れている。
    • FlyのAPIアクセスが頻繁に落ち、新しいサービス修正のデプロイに支障があったと指摘している。
    • デプロイ体験は恋しいが、GCPのCloud Runを使うほうがより満足していると述べている。
  • 「flyctlを実行するたびに、私たちの愛すべき巨大なCLIは空中からTCP/IPスタックを作り出し、固有のIPv6アドレスを持ってFly Machinesと直接通信します。」

    • flyctl実行時にTCP/IPスタックをその場で生成し、固有のIPv6アドレスを通じてFly Machinesと直接通信するという説明に興味を示している。
  • 初期ハンドシェイクパケットがネットワークスタックへ再送されるのを防いでいるのは何ですか? そうすればパケット損失はなくなるように思えます。また、eBPFフィルタで udp[8] = 1 を確認する目的は何ですか?

    • 初期ハンドシェイクパケットがネットワークスタックへ再送されるのを防ぐ仕組みと、eBPFフィルタで特定のUDPパケット値を確認する理由について質問している。
  • 任意のDocker化されたアプリケーションをFly.ioにデプロイするにはどうすればいいですか? 私のお金を受け取ってください

    • Docker化されたアプリケーションをFly.ioにデプロイする方法への関心と意欲を示している。
  • みんなのために、Netmakerを遠慮なく宣伝しておきます。

    • Netmakerを使って満足した経験を共有し、AWS VPCへの個人的なアクセス需要に触れつつ、Netmakerがもっと広く採用されることを願っている。