Proteção contra abuso no relay cego
Os limites que um nó da AeroNyx aplica antes de encaminhar tráfego de relay criptografado: limites de taxa e quarentena por salto anterior, supressão de replay de rotas que sobrevive a reinícios, novas tentativas limitadas e admissão de CPU, usando apenas metadados assinados e contadores agregados.
A proteção contra abuso no relay cego é o conjunto de limites que um nó da AeroNyx aplica antes de encaminhar tráfego de relay criptografado para outro nó. Ela contém pares abusivos ou instáveis usando apenas metadados de roteamento assinados e contadores locais. Ela nunca analisa texto cifrado, não guarda históricos de rotas nem expõe quem conversa com quem.
Escopo
| Controle | Estado |
|---|---|
| Encaminhamento de payload opaco | Implementado |
| Verificações de atualidade assinadas e supressão de replay de rotas | Implementado. O estado de replay sobrevive a reinícios quando o armazenamento do relay de chat do nó está ativado |
| Limitação de taxa e quarentena por salto anterior | Implementado |
| Limites de admissão de solicitações e de criptografia em todo o processo | Implementado |
| Evidências agregadas de execução na saúde do nó e no Nodeboard | Implementado |
| Inspeção de texto claro ou de payloads | Não é feita, por projeto |
| Análises por usuário, por rota ou de grafo social | Não são feitas, por projeto |
A regra do nó cego
Um relay pode autenticar metadados de roteamento, aplicar uma política limitada, encaminhar um envelope opaco e retornar um recibo assinado. Ele nunca deve inspecionar o payload nem expor metadados que possam reconstruir uma rota, a identidade de um usuário ou um relacionamento. Em particular, os relays não registram nem expõem:
- texto claro de mensagens, pacotes, mídia ou memória
- consultas de DNS, destinos, domínios, URLs ou histórico de navegação
- IDs de rotas, caminhos completos, URLs de endpoints ou endereços IP de clientes
- chaves públicas completas, identidades de destinatários, IDs de mensagens ou arestas do grafo social
- chaves privadas, segredos de vouchers, tráfego no nível da carteira ou material de descriptografia
Pipeline de admissão
Cada solicitação passa por estas verificações antes de poder usar a capacidade de encaminhamento. As etapas 1 a 6 são executadas nesta ordem. Na etapa 7, uma solicitação endereçada a este nó vai para o seu próprio tratamento terminal ou onion, enquanto uma solicitação para outro nó é reservada depois que o seu próximo salto é resolvido.
1. request gate: process-wide admission window and in-flight limit (64 requests)
2. crypto admission: a free slot for signature and onion work, or Backpressure
3. authenticate the signed previous hop and envelope
4. previous-hop rate limit and quarantine check
5. envelope metadata: size, age and future-skew limits
6. self-loop check
7. route loop, TTL and next-hop descriptor checks, plus the route replay reservation
8. forward the opaque ciphertext, or peel the terminal layer and deliver
Toda decisão usa metadados de roteamento assinados e estado agregado local, nunca conteúdo descriptografado.
Limites de execução
Estes são os padrões atuais no código-fonte do nó. São valores operacionais, não promessas permanentes do protocolo.
| Constante | Padrão |
|---|---|
BLIND_RELAY_ROUTE_REPLAY_CAPACITY | 8192 rotas ativas |
BLIND_RELAY_ROUTE_REPLAY_TTL_SECS | 600 segundos |
PREVIOUS_HOP_RATE_LIMIT por PREVIOUS_HOP_RATE_WINDOW_SECS | 120 solicitações por 60 segundos |
PREVIOUS_HOP_FAILURE_THRESHOLD por PREVIOUS_HOP_FAILURE_WINDOW_SECS | 12 falhas pontuadas por 300 segundos |
PREVIOUS_HOP_QUARANTINE_SECS | 300 segundos |
MAX_PREVIOUS_HOP_BUCKETS | 4096 buckets |
BLIND_RELAY_MAX_ENVELOPE_AGE_SECS | 600 segundos |
BLIND_RELAY_MAX_FUTURE_SKEW_SECS | 120 segundos |
BLIND_RELAY_DELIVERY_RECEIPT_MAX_AGE_SECS | 120 segundos |
DEFAULT_MAX_ATTEMPTS (novas tentativas de encaminhamento) | 3 tentativas |
MAX_IN_FLIGHT_BLIND_RELAY_REQUESTS | 64 solicitações |
Limitação de taxa e quarentena por salto anterior
Os limites de taxa são indexados pela identidade assinada do salto anterior. Mais de 120 solicitações de um mesmo salto anterior em 60 segundos iniciam uma quarentena local de cinco minutos para esse salto. Uma pontuação de falhas separada inicia a mesma quarentena após 12 falhas pontuadas em cinco minutos. Somente estes motivos contam para a pontuação:
invalid_previous_hop | invalid_signature | self_loop | route_loop | ttl_exhausted
Timeouts de transporte, confirmações perdidas, novas tentativas duplicadas e conflitos de replay não aumentam a pontuação, de modo que um par saudável não é colocado em quarentena por problemas de rede. O armazenamento de buckets é limitado, e os buckets ociosos são removidos, então a proteção não pode crescer até virar um grafo de comunicação de longo prazo.
Replay de rotas e novas tentativas
Toda solicitação de relay carrega um ID de rota. Quando o armazenamento do relay de chat do nó está ativado ([memchain.chat_relay] enabled = true), as reservas de rotas e as respostas concluídas são mantidas no seu banco de dados SQLite, de modo que a proteção contra replay sobrevive a um reinício. Caso contrário, o nó usa um registro em memória com a mesma capacidade e a mesma janela. Se todos os 8192 slots estiverem ocupados por rotas ativas, novas rotas são rejeitadas com replay_capacity até que slots expirem.
Um ID de rota repetido tem um de quatro resultados:
| Situação | Resposta | Efeito sobre o salto anterior |
|---|---|---|
| Mesma solicitação; a primeira tentativa foi concluída | A resposta armazenada é reproduzida, incluindo qualquer recibo assinado pelo nó terminal. Nada é entregue nem encaminhado uma segunda vez (duplicate_route) | Contado como sucesso |
| Mesma solicitação; a primeira tentativa ainda está em execução | HTTP 503 route_in_flight. O remetente pode tentar novamente | Nenhum |
| Solicitação diferente sob o mesmo ID de rota | HTTP 400 replay_conflict | Registrado na saúde do par. Não aumenta a pontuação de quarentena |
| Mesma solicitação, mas a resposta armazenada tem mais de 120 segundos | HTTP 409 replay_response_expired. A rota continua reservada pelo restante da sua janela de 600 segundos, então não pode ser executada novamente | Nenhum |
O último resultado se aplica ao armazenamento durável. Recibos assinados só são válidos como evidência recente, então o nó não reproduz um recibo depois de 120 segundos.
Quando o encaminhamento para o próximo salto falha com um timeout, um erro de conexão ou um erro de solicitação, o nó faz até três tentativas no total. O pequeno atraso antes de cada nova tentativa é derivado do ID da rota, do próximo salto e do número da tentativa. Falhas que o nó a jusante informa como rejeições definitivas não são repetidas.
Admissão de criptografia (nota de capacidade para operadores)
Verificações de assinatura, remoção de camadas onion e assinatura de recibos consomem CPU, então cada processo do nó as limita:
- Total de slots: metade das threads de CPU que o host informa, arredondada para cima, com no mínimo 4 e no máximo 8, de modo que até um host com uma ou duas threads recebe 4 slots.
- Solicitações de entrada: um slot a menos que o total, para que a criação de rotas de saída e a conclusão de recibos sempre possam avançar. Assim, nos menores hosts, as solicitações de entrada recebem 3 slots.
- Quando todos os slots estão ocupados: a solicitação é rejeitada imediatamente com HTTP 429 e o motivo
backpressure. Ela não espera em uma fila.
Em um host pequeno, portanto, um relay descarta carga cedo diante de picos. Um contador backpressure_dropped crescente significa que o nó precisa de mais CPU ou de menos tráfego de relay.
Contadores agregados de execução
Os nós informam contadores cumulativos aproximados e carimbos de data e hora de atualidade no seu heartbeat, sob:
system_stats.discovery_status.peer_store.runtime.blind_relay
system_stats.discovery_status.peer_store.blind_relay_quality
system_stats.discovery_status.peer_store.peer_health_summary
| Grupo de contadores | Campos |
|---|---|
| Entrada e destinação | received, terminal, forwarded, rejected |
| Validação e proteção | invalid_signature, envelope_too_large, ttl_exhausted, no_route, invalid_endpoint, loop_detected, replay_dropped, timestamp_rejected, rate_limited, quarantined, quarantine_started |
| Transporte e novas tentativas | backpressure_dropped, forward_failed, retry_attempted, retry_succeeded, retry_exhausted |
| Sondagens sintéticas | probe_attempted, probe_succeeded, probe_failed, two_hop_probe_attempted, two_hop_probe_succeeded, two_hop_probe_failed |
| Entrega real e atualidade | verified_client_onion_deliveries, last_verified_client_onion_delivery_at, last_accepted_at, last_event_at |
Esses contadores descrevem a operação do nó. Eles não são logs de mensagens nem dados de cobrança, e não comprovam que qualquer conversa específica tenha ocorrido.
Qualidade das evidências
O resumo de qualidade mantém separados quatro tipos de evidência: trabalho de relay opaco aceito, sondagens sintéticas de alcançabilidade, sondagens sintéticas de dois saltos e recibos assinados pelo nó terminal para entregas originadas por clientes. real_relay_ready exige um recibo de entrega de cliente recente e autenticado. Evidências sintéticas nunca são informadas como tráfego de usuários.
status | Significado |
|---|---|
idle | Ainda não há atividade de relay nem de sondagem |
observing | Existe alguma evidência, mas a prontidão não está estabelecida |
stale | Evidências de sucesso anteriores já não são recentes |
ready | Trabalho aceito recente ou uma prova qualificada, sem problema de transporte ativo |
protecting | As proteções contra abuso foram acionadas enquanto o relay continua funcionando |
degraded | Falhas de encaminhamento ou de sondagem precisam ser investigadas |
attention | Backpressure ou novas tentativas esgotadas exigem atenção imediata do operador |
proof_scope indica a evidência mais forte observada: client_message_delivery, relay_acceptance, message_delivery, control_plane, single_hop_control_plane, attempted ou none.
Saúde dos pares sem relações de tráfego
peer_health_summary permite que os operadores encontrem um par com falha ou em quarentena sem ver quem se comunica com quem.
Incluído: um prefixo encurtado do ID do nó, estado aproximado de saúde e do descritor, atualidade do gossip e dos sucessos de rota, contagens agregadas de sucessos e falhas de rota, estado de quarentena, tempo restante e faixas aproximadas de motivos.
Nunca incluído: chaves públicas completas de nós, IDs de rotas, listas de endpoints, blobs criptografados ou hashes de payloads, IDs de mensagens, identidades de destinatários, endereços IP de clientes, destinos, dados de DNS ou arestas do grafo social.
Mapa do código-fonte
| Camada | Caminho no repositório do nó | Função |
|---|---|---|
| Orquestração do relay | crates/aeronyx-server/src/api/chat_peer/blind_relay.rs | Controle de solicitações, admissão de criptografia, autenticação, verificações de loop e de TTL, resultados de replay, encaminhamento e tratamento terminal |
| Superfície HTTP e limites | crates/aeronyx-server/src/api/chat_peer.rs | Rotas, limites de corpo e de solicitações em andamento, códigos de erro e faixas de motivos |
| Política contra abuso | crates/aeronyx-server/src/api/chat_peer_abuse_guard.rs | Limites de taxa por salto anterior, pontuação de falhas e quarentena |
| Registro de replay | crates/aeronyx-server/src/api/chat_peer_replay.rs | Registro em memória e o formato da resposta armazenada |
| Armazenamento durável de replay | crates/aeronyx-server/src/services/chat_relay_blind_route_store.rs | Reservas de rotas e respostas no SQLite |
| Política de novas tentativas | crates/aeronyx-server/src/api/chat_peer_retry.rs | Falhas repetíveis versus definitivas e temporização das novas tentativas |
| Contadores e qualidade | crates/aeronyx-server/src/services/peer_store.rs e services/peer_store/status.rs | Contadores agregados, prontidão e classificação de provas |
| Relatórios de saúde | crates/aeronyx-server/src/api/vpn_health.rs e management/reporter.rs | JSON de saúde local e o payload do heartbeat |
O software de nó é de código aberto sob a AGPL-3.0, em github.com/AeroNyxNetwork/AeroNyx. Consulte Descoberta de nós e relay criptografado de múltiplos saltos para ver como as rotas são construídas.
<!-- faq:start -->Perguntas frequentes
Um nó de relay consegue ler ou registrar o tráfego que encaminha?
Não. Um relay verifica metadados de roteamento assinados e encaminha um envelope opaco. Ele guarda apenas contadores agregados, nunca payloads, históricos de rotas nem identidades de destinatários.
O que acontece quando um nó tenta novamente a mesma rota?
Se a primeira tentativa tiver terminado, o nó reproduz a resposta armazenada e não entrega nada uma segunda vez. Se a primeira tentativa ainda estiver em execução, o nó retorna um route_in_flight que permite nova tentativa. Uma solicitação diferente sob o mesmo ID de rota é rejeitada como replay_conflict.
A proteção contra replay sobrevive a um reinício do nó?
Sim, quando o armazenamento do relay de chat do nó está ativado. Nesse caso, as reservas de rotas e as respostas concluídas são mantidas no SQLite. Sem esse armazenamento, o nó usa um registro em memória que é apagado no reinício.
Por que um par é colocado em quarentena?
Um par é colocado em quarentena por cinco minutos depois de enviar mais de 120 solicitações em 60 segundos, ou depois de 12 falhas de validação pontuadas em cinco minutos. Timeouts, confirmações perdidas e novas tentativas duplicadas não contam como falhas.
Por que meu nó retorna backpressure sob carga?
Todos os seus slots de criptografia do relay estavam ocupados. Um nó reserva cerca de metade das suas threads de CPU (no mínimo 4 e no máximo 8) para o trabalho de assinatura e onion e rejeita imediatamente as solicitações excedentes, em vez de colocá-las em fila.
<!-- faq:end -->