ノードディスカバリーと暗号化マルチホップリレー

AeroNyx約14分で読めます

AeroNyx ノードが署名付き記述子で互いを発見し、ミラーされたディレクトリチェーンを保持し、多層に暗号化されたペイロードをホップごとに転送する仕組み。実際のチャットはデフォルトで中央リレーを使い、2 ホップのオニオンルートはオプトインです。

AeroNyx ノードは、署名付きで有効期限のある記述子を通じて互いを発見し、エンドツーエンドで暗号化されたペイロードをホップごとに転送できます。各リレーは自分の暗号化層だけを外します。現時点では、実際のユーザーのチャットはデフォルトで中央の AeroNyx リレー(RelayWS)を経由します。ノードを経由したチャットのルーティングは、アプリ内のオプトイン設定です。

現在稼働しているもの

機能状況
署名付きノードディスカバリーとピアゴシップ本番ノードで稼働中
ディレクトリチェーン(ノードごとの署名付き記述子履歴。ノード間でミラーされます)本番ノードで稼働中
ノード間の 2 ホップのオニオンリレー本番ノードで稼働中。アプリではオプトインで、デフォルトはオフ
オニオンリレー経由で到達する匿名メールボックス本番ノードで動作中。通常のチャットでは使われません。アプリには別のベータ版メールボックスドロップがあります
リレーホップが 3 つのルートポリシーとプローブはノードのソースに存在します。アプリでは使用していません
ゲートウェイの背後にあるノード向けの https:// ホスト名エンドポイント現行のノードリリースに含まれています
パブリック API ポートでの ID 結合型 TLS(ドメイン名も認証局も不要)本番ノードで稼働中。ピアが対応を通知している場合、ノード同士はこれを使います。アプリの対応は開発中です
オニオンの終端ノードから受信者のリレーインボックスへのハンドオフ本番ノードで稼働中
オペレーターが固定するシード(discovery.pinned_seeds)現行のノードリリースに含まれています
デフォルトのチャットトランスポートAeroNyx が運用する中央の RelayWS サービス

中央集権型と分散型の経路は並行して稼働しています。

ディスカバリーの仕組み

各ノードは、自身の Ed25519 ID 鍵で署名した記述子を公開します。記述子には、ノード ID、発行時刻と有効期限、オプションの公開エンドポイント、機能フラグ(オニオンの中間リレーやチャットリレーなど)、おおまかな容量の目安、オニオン暗号化に使う鍵が含まれます。ノードは、有効期限切れの記述子や署名が無効な記述子を拒否します。

  • ゴシップには上限があります。 ピア交換にはレート制限とポリシーによる制限がかかり、メッセージにはサイズ制限があります。
  • 再起動からの回復。 ノードはローカルのピアキャッシュを保持し、再起動後は設定されたシードエンドポイントにフォールバックします。オペレーターはシードを固定することもできます。
  • ルートの選択。 リレー候補として考慮されるのは、使用可能なエンドポイントとオニオン鍵を持つ新しい記述子だけです。

記述子に指定できるエンドポイント

署名が証明するのは記述子を誰が公開したかであり、そのエンドポイントに接続しても安全であることではありません。そのためノードは、次の 2 つの形式のエンドポイントだけを受け付けます。

  • http または https 上のパブリック IP アドレス。ループバック、プライベート、リンクローカル、CGNAT、ドキュメント用、マルチキャスト、予約済みの各範囲は拒否されます。
  • パブリックな DNS 名を持つ https:// URL。単一ラベルの名前、localhost、および .local、.internal、.home.arpa のようなプライベートなサフィックスは拒否されます。

ホスト名は接続時に、パブリックでないアドレスをすべて除外するリゾルバーを通じて解決されます。そのため、名前をノード自身、プライベートネットワーク、クラウドのメタデータサービスに向けることはできません。ピアクライアントはプロキシ設定も無視し、リダイレクトに従うこともありません。

ホスト名の形式は、クラウドゲートウェイの背後にある TEE ノードのように、自前の IP アドレスを持たないノードが参加できるようにするために存在します。

固定シード

オペレーターのスナップショットなしで起動したノードは、すでに保持している ID しか信頼しないため、結果として自分自身しか信頼しない状態になることがあります。この場合に備えて、オペレーターは特定のアドレスで期待する ID を指定できます。

toml
[discovery]
pinned_seeds = ["<64-hex node id>@<public ip>:<port>"]
  • 固定された ID が初めて受け入れられるのは、その ID に固定された ID 結合型 TLS での交換を行った後だけです。
  • 固定された ID の以降のすべての記述子は、どの経路から届いたものであっても、固定されたアドレスを維持し、ID 結合型 TLS を通知していなければなりません。
  • 信頼は伝播しません。シードの応答に含まれる他の記述子は、引き続き信頼されない候補のままです。
  • 削除された固定設定が、古いキャッシュやバックアップから復活することはありません。

ディレクトリチェーン

各ノードは、自身の記述子イベントの署名付きでハッシュでつながった履歴も保持しています。これをディレクトリチェーンと呼びます。他のノードはその履歴をミラーし、記述子オブジェクトを取得し、特定の記述子についての包含証明を要求できます。オペレーターが固定したピアは、自分が見た履歴に対して観測チェックポイントに署名できます。

グローバルな台帳も単一のコーディネーターもありません。各ノードが自身の履歴に署名し、他のノードがそれをミラーして検査します。

ID 結合型 TLS

HTTPS でノードに到達するには、通常、ドメイン名と認証局が発行する証明書が必要ですが、AeroNyx のノードの大半は IP アドレスでしか到達できません。そこでノードは、自身の Ed25519 ID によって自分の HTTPS エンドポイントを証明します。

  • 仕組み。 ノードは通常の ECDSA P-256 の TLS 鍵と自己署名証明書を作成します。サブジェクト代替名の 1 つに、バインディング aeronyx-tls-binding:v1:<node id>:<expiry>:<signature> が含まれます。この署名は、証明書自身の公開鍵、ノード ID、有効期限に対するドメイン分離されたダイジェストに、ノードの ID 鍵で付けられます。TLS 1.3 ハンドシェイクは、ノードが証明書の鍵を保持していることを証明します。ID 鍵がハンドシェイクに署名することはありません。
  • クライアントが確認すること。 検証側が証明書を受け入れるのは、接続しようとしたノードのものである場合だけです。具体的には、バインディングがちょうど 1 つあること、期待するノード ID であること、期限切れでないこと、残りの有効期間が最大 31 日であること、そしてこの証明書の鍵に対する署名が有効であることです。認証局が発行した証明書は、この確認を満たしません。
  • 同じポート。 パブリック API ポート(8422/TCP)は両方を提供します。TLS ハンドシェイクで始まる接続には TLS で応答し、それ以外はこれまでどおりプレーンな HTTP で応答します。デフォルトでオンです(discovery.public_api_identity_tls)。
  • ノード間。 署名付き記述子がプロトコル機能 anpf1-ibt1 を通知しているノードは、ID 結合型 TLS を提供します。この機能を確認したピアは、そのノードの ID に固定した TLS で接続しなければならず、プレーンな HTTP にフォールバックすることはありません。この機能は記述子の署名の対象に含まれるため、ネットワーク上の攻撃者がこれを取り除いてダウングレードを強いることはできません。複数の ID が同じエンドポイントを名乗る場合、TLS アドレスは生成されず、リクエストは安全側に倒れて失敗します。この機能を持たない古いノードと、DNS 名のゲートウェイエンドポイントは、従来の動作のままです。
  • リファレンス。 ソースと固定されたテストベクター:aeronyx-node-tls。

その結果、ノード間のオニオンホップのルート情報、ゴシップ、ディレクトリ同期、ウィットネスのトラフィックは、通信経路上で読み取れなくなります。この方法でノードに接続するアプリ側の対応は開発中です。

マルチホップリレーの仕組み

  1. 送信者は、各リレーが公開しているオニオン鍵を使い、ホップごとに 1 層ずつペイロードを暗号化で包みます。
  2. 各リレーは、前のホップの署名、タイムスタンプ、リプレイ状態を検証し、自分の層を外して、残りの不透明なデータを転送します。内側の層を見ることは決してありません。
  3. 最終(終端)ノードはメッセージを受信者のリレーインボックス(デフォルトでは中央リレー)にハンドオフし、リレーが受け付けた後にのみ署名付き受領証を返します。受領証は、ルート ID、ペイロードへのコミットメント、終端ノードの ID、配信時刻を結び付けます。これが証明するのはメッセージがリレーの保管下に受け入れられたことであり、受信者が読んだことではありません。ハンドオフをオフにしたノードは、メッセージを自身のストアに保持し、同じ種類の受領証に署名するため、受領証だけではこの 2 つのケースを区別できません。

各当事者に見えるもの

当事者見えるもの見えないもの
エントリーノード送信者のネットワークアドレス、封印された層、次のホップメッセージの宛先と、その内容
終端ノード送信者と受信者の鍵、および暗号文送信者のネットワークアドレスと、内容
中央リレー(ハンドオフを受け取る)あらゆる送信で見える情報:送信者と受信者の鍵、タイムスタンプ、サイズ送信者のネットワークアドレスと、内容

単一のノードが、あなたのネットワークアドレスと、誰に宛てて書いているかを結び付けることはありません。終端ノードと中央リレーは、どちらも誰が誰に宛てて書いたかを見ています。

プロトコルが受け付ける検証済みリレーホップは最大 3 つです。アプリのプライバシールートは 2 つを使います。リレーにおける不正利用の制限については、ブラインドリレー不正利用ガードで説明しています。

アプリでのチャット

  • デフォルト: メッセージは中央の RelayWS サービスを経由します。メッセージの内容はエンドツーエンドで暗号化されますが、配信メタデータはこのサービスが扱います。チャットリレー クライアント統合をご覧ください。
  • プライバシールート(オプトイン、デフォルトはオフ): オンにしてルートの準備ができている場合、アプリは 1 対 1 のメッセージをまず 2 ホップのオニオンルートで送信します。どのオニオンルートもメッセージを受け付けない場合、アプリはメッセージをデバイス上に保留し、そのメッセージについてユーザーが承認しない限り標準リレーは使用しません。
  • 匿名メールボックス(ベータ版): プライバシーネットワークに接続している間だけ動作する別のドロップです。通常の会話では使われません。

匿名メールボックスのプルサイズ

メールボックスのプル結果は以前、項目の内容にかかわらず 163,130 バイトの固定イメージ 1 つであり、短いメッセージでも約 160 KiB の応答になっていました。署名付きプロトコル機能 anpf1-ampc1 でネゴシエートされるプルバージョン 2 は、封印された項目を 5 つのサイズクラス(4,204、16,492、65,644、131,180 バイト、またはコーデックの最大値)のうち最小のものにパディングします。4,096 バイトの項目は、現在は 4,518 バイトで送られます。

TEE ノード

本番ノードのうち 1 台は、Phala Cloud の信頼実行環境(Intel TDX 上の dstack)内で動作しています。このノードは匿名メールボックスとオニオンリレーとしてのみ機能します。VPN は無効で、MemChain はオフで、ID 鍵は dstack の鍵サービスから取得されます。到達できるのはゲートウェイ上の TLS ホスト名を通じてだけであり、ホスト名エンドポイントが追加されたのはこのためです。アプリは現在、このノードの TEE アテステーションを検証していません。

ライブの状況

ネットワークの集計状況は次の場所で公開されています。

text
GET https://api.aeronyx.network/api/privacy_network/vpn/public/network-stats/

リレーとディスカバリーの集計値は data.protocol_status 以下に表示されます。たとえば peer_store.blind_relay や peer_store.peer_quorum です。読む際には次の 2 点に注意してください。

  • ノード単位の集計値に含まれるのは、直近 120 秒以内にハートビートのあったノードのみです。そのため、オフラインのノードは protocol_status.reported_nodes などの件数から外れます。network.total_nodes と network.vpn_nodes は、オンラインかどうかにかかわらず、引き続き登録済みのアクティブなノードを数えます。
  • 合成プローブのカウンター(probe_*、two_hop_probe_*)は経路の健全性を測定するものです。ユーザーのトラフィックではありません。

公開レスポンスに含まれるのは、件数、状態の区分、タイムスタンプだけです。ノード ID、エンドポイント、ルート ID、ペイロード、受信者、クライアント IP アドレス、DNS データ、ソーシャルグラフのエッジが含まれることは決してありません。ネットワーク統計とプライバシー境界をご覧ください。

<!-- faq:start -->

よくある質問

AeroNyx のチャットメッセージは分散型ノードを経由しますか?

デフォルトでは経由しません。メッセージは中央の RelayWS サービスを経由します。アプリでプライバシールートをオンにすると、ルートの準備ができていれば 1 対 1 のメッセージはノードを経由する 2 ホップのオニオンルートで送信されます。どのルートもメッセージを受け付けない場合、アプリはルートが利用可能になるまで、またはそのメッセージを標準リレーで送信することをユーザーが承認するまで、メッセージを保留します。

リレーノードは転送するメッセージを読めますか?

いいえ。リレーは自分の暗号化層だけを外し、不透明なデータを転送します。さらに、メッセージの内容は会話の参加者間でエンドツーエンドに暗号化されています。

ディレクトリチェーンとは何ですか?

ディレクトリチェーンは、各ノード自身の記述子の、署名付きでハッシュでつながった履歴です。他のノードがこれをミラーし、包含証明を要求できます。グローバルなコーディネーターはありません。

ゲートウェイの背後にあるノードはどのようにネットワークに参加できますか?

エンドポイントとして https:// ホスト名を公開できます。他のノードは接続時にその名前を解決し、パブリックアドレスだけを使用するため、その名前をプライベートや内部の宛先へリダイレクトすることはできません。

公開統計ページの登録ノード数がオンラインのノード数より多いのはなぜですか?

network.total_nodes と network.vpn_nodes は、オンラインかどうかにかかわらず登録済みのアクティブなノードを数えます。network.online_vpn_nodes と比較してください。プロトコルおよび転送のカウントには、ハートビートが新しいノードのみが含まれます。

HTTPS のためにノードにドメイン名や認証局は必要ですか?

いいえ。ノードは自身の ID 鍵によって HTTPS エンドポイントを証明できます。TLS 証明書には、証明書の鍵に対するノード ID の署名が含まれており、ノード ID を知っているクライアントやピアがこれを検証できます。ゲートウェイの背後にあるノードは、代わりに https:// ホスト名を引き続き使用できます。

署名付き配信受領証は何を証明しますか?

終端ノードがメッセージをリレーの保管下、実際には受信者のリレーインボックスに受け入れたことを証明します。受信者がメッセージを見た、または読んだことは証明しません。それにはチャットプロトコルの配信確認と既読確認を使ってください。

<!-- faq:end -->