ブラインドリレー悪用防止
AeroNyx ノードが暗号文を読まずにリプレイ、ループ、過剰送信、障害 peer を抑止し、プライバシーを守る運用証拠を提供する仕組み。
Blind Relay Abuse Guard は AeroNyx の分散型暗号転送における安全境界です。暗号文を解析せず、永続的な経路履歴を作らず、ノード運用者をトラフィック監視者にすることなく、悪意または不安定な中継動作を制限します。
状態と範囲
このガードは Rust に実装され、集約結果は node health metadata と Nodeboard に表示されます。目的は封じ込めと正確な証拠であり、不透明な relay work が accepted、protected、degraded、stale のどれかを示しても内容は示しません。
| 制御 | 状態 |
|---|---|
| Blind payload forwarding | 実装済み |
| Signed freshness and replay suppression | 実装済み |
| Previous-hop rate limiting and quarantine | 実装済み |
| Privacy-safe runtime evidence | 実装済み |
| Nodeboard operator visibility | 実装済み |
| Plaintext or payload inspection | 禁止 |
| User, route, or social-graph analytics | 禁止 |
ブラインドノードの不変条件
Relay は routing metadata の署名を検証し、有界な policy を適用し、不透明 envelope を転送して terminal signed receipt を返せます。しかし payload を検査・推論したり、経路、ユーザー、社会関係を再構成できる metadata を公開してはいけません。
- message plaintext、packet payload、media content、MemChain plaintext
- DNS content、destination、domain、URL、browsing history
- route ID、complete path、endpoint URL、client public IP
- full public key、receiver identity、message ID、social-graph edge
- private key、voucher secret、wallet-level traffic、decryption material
受け入れ処理
各 request は forwarding capacity を使う前に有界チェックを通ります。以下は概念的な順序で、判断は signed routing metadata と local aggregate state のみを使い、復号内容は使いません。
verify signed previous_hop and envelope
apply in-flight backpressure
check timestamp freshness
check route replay cache
apply previous-hop rate/quarantine decision
validate TTL, loop safety, next-hop descriptor, and endpoint
forward opaque ciphertext or terminate into pending store
リプレイと時刻の保護
Replay suppression は local、短期間、容量制限付きです。Signed envelope timestamp により古い frame や不自然に未来の frame を拒否します。表の値は現在の main の runtime default であり永久的な protocol promise ではありません。変更時は test と docs を更新します。
| 実行時定数 | 現在の既定値 |
|---|---|
MAX_BLIND_RELAY_SEEN_ROUTES | 8192 route IDs |
BLIND_RELAY_ROUTE_REPLAY_WINDOW_SECS | 600 seconds |
BLIND_RELAY_PREVIOUS_HOP_RATE_LIMIT | 120 requests / 60 seconds |
BLIND_RELAY_PREVIOUS_HOP_FAILURE_THRESHOLD | 12 scored failures / 300 seconds |
BLIND_RELAY_PREVIOUS_HOP_QUARANTINE_SECS | 300 seconds |
MAX_BLIND_RELAY_PREVIOUS_HOP_BUCKETS | 4096 buckets |
BLIND_RELAY_MAX_ENVELOPE_AGE_SECS | 600 seconds |
BLIND_RELAY_MAX_FUTURE_SKEW_SECS | 120 seconds |
BLIND_RELAY_DELIVERY_RECEIPT_MAX_AGE_SECS | 120 seconds |
MAX_BLIND_RELAY_FORWARD_ATTEMPTS | 3 attempts |
前ホップのレート制限と隔離
Rate limit は signed previous-hop identity ごとに適用します。60 秒で 120 request を超えると 5 分間 local quarantine になります。別の failure score は 5 分間で 12 回の攻撃的 validation failure に達すると同じ隔離を開始します。
invalid_previous_hop | invalid_signature | self_loop | route_loop | ttl_exhausted
Failure score に加算するのは敵対的な validation reason だけです。Transport timeout、ACK loss、duplicate route retry は正常な previous hop を汚しません。Bucket store は有界で idle state は失効するため、永続的な communication graph になりません。
冪等性と再試行の意味
Replay window 内の同じ route ID は idempotent success を返します。Aggregate replay drop は一度増えますが、envelope を再配信・再転送しません。一時的な next-hop failure は bounded jitter 付きで最大 3 回、恒久的な validation failure は retry しません。
duplicate route_id -> accepted=true, reason=duplicate_route, no second delivery
transient next-hop failure -> bounded retry with deterministic jitter
permanent validation failure -> no retry
実行時の集約カウンター
Rust は次の 2 path で粗い cumulative counter と freshness timestamp を公開します。これは node-scoped operational evidence であり、message log、user billing analytics、特定会話の証明ではありません。
system_stats.discovery_status.peer_store.runtime.blind_relay
system_stats.discovery_status.peer_store.peer_health_summary
| カウンター群 | フィールド |
|---|---|
| 受信と処理結果 | received, terminal, forwarded, rejected |
| 検証と保護 | invalid_signature, envelope_too_large, ttl_exhausted, no_route, invalid_endpoint, loop_detected, replay_dropped, timestamp_rejected, rate_limited, quarantined, quarantine_started |
| 転送と再試行 | backpressure_dropped, forward_failed, retry_attempted, retry_succeeded, retry_exhausted |
| 合成証拠 | probe_attempted, probe_succeeded, probe_failed, two_hop_probe_attempted, two_hop_probe_succeeded, two_hop_probe_failed |
| 実配信と鮮度 | verified_client_onion_deliveries, last_verified_client_onion_delivery_at, last_accepted_at, last_event_at |
証拠品質の意味
Quality summary は accepted opaque work、synthetic reachability probe、synthetic two-hop control proof、terminal-signed client delivery receipt を区別します。real_relay_ready は expected terminal による fresh authenticated client-originated receipt だけに使い、synthetic evidence を App/user traffic と表示してはいけません。
status | 意味 |
|---|---|
idle | Relay または probe evidence がまだありません。 |
observing | Evidence はありますが readiness は未確立です。 |
stale | 以前の成功 evidence が fresh ではありません。 |
ready | Fresh accepted work または qualifying proof があり active transport attention はありません。 |
protecting | Abuse protection counter が作動中ですが relay は稼働しています。 |
degraded | Forwarding または probe failure の調査が必要です。 |
attention | Backpressure または retry exhaustion に直ちに対応する必要があります。 |
proof_scope は client_message_delivery、relay_acceptance、message_delivery、control_plane、single_hop_control_plane、attempted、none を区別します。Historical total は累積し続けますが、readiness は fresh evidence と active transport failure を考慮します。
プライバシーを守る peer 健全性
peer_health_summary は短縮 node identifier と粗い health bucket を使い、traffic relationship を見せずに failing/quarantined peer を分離できます。明確な privacy boundary を持つ control-plane 診断です。
許可:
- 短縮
node_id_prefix - 粗い health と descriptor state
- gossip と route success の freshness bucket
- aggregate route success/failure count
- aggregate loop/replay/rate-limit/quarantine count
- quarantine remaining time と bounded reason bucket
禁止:
- 完全な node public key
- route ID または endpoint list
- encrypted blob または payload hash
- message ID または receiver identity
- client IP、destination、DNS data
- social-graph edge または通信相手の関係
運用手順
Nodeboard で node を選び、Discovery と Security / Relay Protection を開きます。傾向は node health、reachability、queue pressure、signed proof freshness の範囲だけで解釈します。
- Discovery descriptor と bootstrap recovery が fresh か確認します。
- Runtime ready と判断する前に
accepted_total、accepted_percent、last accepted age を比較します。 real_relay_readyと synthetic probe readiness を区別します。前者だけが authenticated client-originated terminal receipt の証拠です。- protecting、degraded、attention の場合は aggregate reason bucket と transport health だけを調べ、user-level log を要求しません。
ソースマップ
ホスト移転後も仕様を保つため repository-relative path を使います。Backend と Nodeboard は別 repository ですが、owner-scoped privacy-safe node metadata だけを扱います。
| レイヤー | リポジトリパス | 役割 |
|---|---|---|
| Rust relay API | crates/aeronyx-server/src/api/chat_peer.rs | Envelope を認証し loop、replay、freshness、rate、quarantine、retry、terminal receipt rule を適用します。 |
| Rust PeerStore | crates/aeronyx-server/src/services/peer_store.rs | Bounded aggregate counter、peer health、readiness、proof classification を保持します。 |
| Rust health API | crates/aeronyx-server/src/api/vpn_health.rs | Local privacy-safe health JSON を公開します。 |
| Rust reporter | crates/aeronyx-server/src/management/reporter.rs | Node heartbeat metadata で aggregate status を送ります。 |
| Backend observability | privacy_network/api/vpn_observability.py | Owner-scoped system metadata を operator console に返します。 |
| Nodeboard types | types/index.ts | Blind relay と peer health response type を定義します。 |
| Nodeboard detail と i18n | app/dashboard/nodes/[id]/page.tsx and lib/i18n/index.ts | Localized privacy-boundary copy で Security / Relay Protection を表示します。 |
マルチホップルーティングの基盤
Multi-hop routing には replay resistance、loop containment、bounded retry、peer quarantine、user traffic と混同しない evidence が必要です。この guard は blind-node invariant を弱めず layered encryption と route diversity の基盤になります。
開発ルール
新しい field はすべて privacy review の対象です。Operator metric は node reliability の問いに答えても、payload、sender、receiver、path、endpoint、conversation を識別してはいけません。
- すべての relay path で
payload_b64を opaque に保つこと。 - Aggregate counter または bounded reason bucket だけを追加すること。
- Counter を route ID、endpoint、user、receiver、message metadata と join しないこと。
- Synthetic probe を encrypted message、packet、byte total に含めないこと。
- 意味を変更したら Rust test、Nodeboard type、全言語の本ページを更新すること。