Защита слепого relay от злоупотреблений

AeroNyx20 июня 2026 г.6 мин чтения49 просмотров

Как узлы AeroNyx сдерживают replay, циклы, перегрузку и сбойные peers, не читая шифротекст и сохраняя приватность операционных доказательств.

Blind Relay Abuse Guard — граница безопасности децентрализованной передачи шифротекста AeroNyx. Она ограничивает злоупотребления и нестабильность, не анализируя ciphertext, не создавая постоянную историю маршрутов и не превращая оператора в наблюдателя трафика.

Статус и область

Защита реализована в Rust, агрегированные результаты доступны в health metadata и Nodeboard. Её задача — сдерживание и честное доказательство: opaque relay work принято, защищается, деградировало или устарело, но не раскрывается его содержимое.

КонтрольСостояние
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, применить ограниченную политику, переслать opaque envelope и вернуть terminal-signed receipt. Он не может исследовать или выводить payload и раскрывать metadata, позволяющую восстановить маршрут, личность или социальную связь.

  • plaintext сообщений, packet payload, media или MemChain plaintext
  • DNS, destinations, domains, URLs или browsing history
  • route IDs, полные пути, endpoint URLs или client public IP
  • полные public keys, receiver identity, message IDs или social graph
  • private keys, voucher secrets, wallet-level traffic или decryption material

Конвейер допуска

Каждый request проходит ограниченные проверки до расходования forwarding capacity. Порядок ниже концептуальный; решения используют только signed routing metadata и локальное агрегированное состояние, не расшифрованное содержимое.

text
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 и по времени

Replay suppression локальна, краткосрочна и ограничена по объёму. Подписанные timestamps отклоняют старые и чрезмерно будущие frames. Таблица отражает текущие defaults main, а не вечные обещания протокола; изменения требуют tests и docs.

Runtime-константаТекущее значение
MAX_BLIND_RELAY_SEEN_ROUTES8192 route IDs
BLIND_RELAY_ROUTE_REPLAY_WINDOW_SECS600 seconds
BLIND_RELAY_PREVIOUS_HOP_RATE_LIMIT120 requests / 60 seconds
BLIND_RELAY_PREVIOUS_HOP_FAILURE_THRESHOLD12 scored failures / 300 seconds
BLIND_RELAY_PREVIOUS_HOP_QUARANTINE_SECS300 seconds
MAX_BLIND_RELAY_PREVIOUS_HOP_BUCKETS4096 buckets
BLIND_RELAY_MAX_ENVELOPE_AGE_SECS600 seconds
BLIND_RELAY_MAX_FUTURE_SKEW_SECS120 seconds
BLIND_RELAY_DELIVERY_RECEIPT_MAX_AGE_SECS120 seconds
MAX_BLIND_RELAY_FORWARD_ATTEMPTS3 attempts

Лимит и карантин предыдущего hop

Rate limit привязан к подписанной identity предыдущего hop. Более 120 requests за 60 секунд запускают локальный карантин на пять минут. Отдельный score запускает тот же карантин после 12 враждебных validation failures за пять минут.

text
invalid_previous_hop | invalid_signature | self_loop | route_loop | ttl_exhausted

В score входят только adversarial validation reasons. Transport timeout, потерянный ACK и retry дубликата маршрута не штрафуют здоровый peer. Bucket store ограничен, idle state истекает, поэтому постоянный communication graph не возникает.

Идемпотентность и повторы

Повторный route ID в окне получает idempotent success: учитывается один aggregate replay drop без повторной доставки или пересылки. Временная ошибка next hop имеет максимум три попытки с bounded jitter; постоянная validation error не повторяется.

text
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

Агрегированные runtime-счётчики

Rust публикует грубые cumulative counters и freshness timestamps по двум путям. Это node-scoped operational evidence, а не message logs, биллинговая аналитика или доказательство конкретного разговора.

text
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
Транспорт и retrybackpressure_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 probes, synthetic two-hop proofs и terminal-signed client receipts. real_relay_ready требует свежий authenticated client-originated receipt от ожидаемого terminal. Synthetic evidence нельзя показывать как App/user traffic.

statusЗначение
idleДоказательств relay или probe ещё нет.
observingЧастичные доказательства есть, readiness не установлена.
staleПредыдущее успешное доказательство устарело.
readyЕсть свежая принятая работа или proof без активной transport alert.
protectingСчётчики защиты активны, relay продолжает работать.
degradedForwarding или probe failures требуют проверки.
attentionBackpressure или exhausted retries требуют немедленного действия.

proof_scope разделяет client_message_delivery, relay_acceptance, message_delivery, control_plane, single_hop_control_plane, attempted и none. Исторические totals накопительные; readiness требует свежих доказательств и учитывает активные transport failures.

Приватная сводка здоровья peers

peer_health_summary использует сокращённый node identifier и грубые health buckets, позволяя изолировать failing/quarantined peer без раскрытия traffic relationships. Это control-plane диагностика с явной privacy boundary.

Разрешено:

  • сокращённый node_id_prefix
  • грубые health и descriptor state
  • freshness buckets gossip и route success
  • aggregate route success/failure counts
  • aggregate loop/replay/rate-limit/quarantine counts
  • остаток карантина и bounded reason buckets

Запрещено:

  • полные node public keys
  • route IDs или endpoint lists
  • encrypted blobs или payload hashes
  • message IDs или receiver identity
  • client IP, destinations или DNS
  • social graph или связи собеседников

Рабочий процесс оператора

Откройте Nodeboard, выберите узел, затем Discovery и Security / Relay Protection. Тенденции интерпретируются только вместе с node health, reachability, queue pressure и freshness подписанных proofs.

  1. Проверьте свежесть descriptors и bootstrap recovery.
  2. До объявления ready сравните accepted_total, accepted_percent и age последнего accepted.
  3. Отличайте real_relay_ready от synthetic readiness; только первое доказывает authenticated client-originated terminal receipt.
  4. При protecting, degraded или attention исследуйте aggregate buckets и transport health без user-level logs.

Карта исходного кода

Используются repository-relative paths, чтобы спецификация переживала перенос инфраструктуры. Backend и Nodeboard находятся в разных репозиториях и потребляют только owner-scoped privacy-safe metadata.

СлойПуть репозиторияРоль
Rust relay APIcrates/aeronyx-server/src/api/chat_peer.rsАутентифицирует envelopes и применяет loop, replay, freshness, rate, quarantine, retry и terminal receipt rules.
Rust PeerStorecrates/aeronyx-server/src/services/peer_store.rsХранит bounded counters, peer health, readiness и proof classification.
Rust health APIcrates/aeronyx-server/src/api/vpn_health.rsПубликует локальный privacy-safe health JSON.
Rust reportercrates/aeronyx-server/src/management/reporter.rsПередаёт aggregate status в heartbeat metadata.
Backend observabilityprivacy_network/api/vpn_observability.pyВозвращает owner-scoped metadata в консоль.
Nodeboard typestypes/index.tsОпределяет blind relay и peer health types.
Nodeboard detail и i18napp/dashboard/nodes/[id]/page.tsx and lib/i18n/index.tsПоказывает Security / Relay Protection с локализованной privacy boundary.

Основа multi-hop маршрутизации

Multi-hop требует anti-replay, сдерживания циклов, bounded retry, карантина peer и доказательств, не смешиваемых с user traffic. Guard создаёт основу layered encryption и route diversity без ослабления blind-node invariant.

Правила разработки

Каждое новое поле проходит privacy review. Метрика должна отвечать на вопрос о надёжности узла, не идентифицируя payload, sender, receiver, path, endpoint или conversation.

  1. Сохранять payload_b64 opaque на всех relay paths.
  2. Добавлять только aggregate counters или bounded reason buckets.
  3. Не соединять counters с routes, endpoints, users, receivers или message metadata.
  4. Не включать synthetic probes в totals сообщений, packets и bytes.
  5. При смене семантики обновлять Rust tests, Nodeboard types и все языки страницы.

Обнаружение узлов и проверяемая зашифрованная доставка