Protección contra abusos del relé ciego

AeroNyx10 min de lectura

Los límites que aplica un nodo de AeroNyx antes de reenviar tráfico de relé cifrado: límites de frecuencia y cuarentena del salto anterior, supresión de la repetición de rutas que sobrevive a reinicios, reintentos acotados y admisión de CPU, usando solo metadatos firmados y contadores agregados.

La protección contra abusos del relé ciego (Blind Relay Abuse Guard) es el conjunto de límites que aplica un nodo de AeroNyx antes de reenviar tráfico de relé cifrado para otro nodo. Contiene a los pares abusivos o inestables usando únicamente metadatos de enrutamiento firmados y contadores locales. Nunca analiza el texto cifrado, no guarda historiales de rutas ni expone quién habla con quién.

Alcance

ControlEstado
Reenvío de cargas útiles opacasImplementado
Comprobaciones de vigencia firmadas y supresión de la repetición de rutasImplementado. El estado antirrepetición sobrevive a los reinicios cuando el almacén del relé de chat del nodo está habilitado
Límite de frecuencia y cuarentena del salto anteriorImplementado
Límites de admisión de solicitudes y de criptografía para todo el procesoImplementado
Evidencia agregada de funcionamiento en el estado del nodo y en NodeboardImplementado
Inspección del texto plano o de las cargas útilesNo se realiza, por diseño
Analítica por usuario, por ruta o del grafo socialNo se realiza, por diseño

La regla del nodo ciego

Un relé puede autenticar los metadatos de enrutamiento, aplicar una política acotada, reenviar un sobre opaco y devolver un acuse de recibo firmado. Nunca debe inspeccionar la carga útil ni exponer metadatos que puedan reconstruir una ruta, la identidad de un usuario o una relación. En particular, los relés no registran ni exponen:

  • el texto plano de mensajes, paquetes, medios o memoria
  • consultas DNS, destinos, dominios, URL ni historial de navegación
  • ID de ruta, rutas completas, URL de endpoints ni direcciones IP de clientes
  • claves públicas completas, identidades de destinatarios, ID de mensajes ni aristas del grafo social
  • claves privadas, secretos de vales, tráfico a nivel de billetera ni material de descifrado

Proceso de admisión

Cada solicitud pasa por estas comprobaciones antes de poder usar capacidad de reenvío. Los pasos 1 a 6 se ejecutan en este orden. En el paso 7, una solicitud dirigida a este nodo pasa a su propio tratamiento terminal o cebolla, mientras que una solicitud para otro nodo se reserva después de resolver su siguiente salto.

text
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

Cada decisión usa metadatos de enrutamiento firmados y estado agregado local, nunca contenido descifrado.

Límites de funcionamiento

Estos son los valores predeterminados actuales en el código fuente del nodo. Son valores operativos, no promesas permanentes del protocolo.

ConstanteValor predeterminado
BLIND_RELAY_ROUTE_REPLAY_CAPACITY8192 rutas activas
BLIND_RELAY_ROUTE_REPLAY_TTL_SECS600 segundos
PREVIOUS_HOP_RATE_LIMIT por PREVIOUS_HOP_RATE_WINDOW_SECS120 solicitudes por 60 segundos
PREVIOUS_HOP_FAILURE_THRESHOLD por PREVIOUS_HOP_FAILURE_WINDOW_SECS12 fallos puntuados por 300 segundos
PREVIOUS_HOP_QUARANTINE_SECS300 segundos
MAX_PREVIOUS_HOP_BUCKETS4096 buckets
BLIND_RELAY_MAX_ENVELOPE_AGE_SECS600 segundos
BLIND_RELAY_MAX_FUTURE_SKEW_SECS120 segundos
BLIND_RELAY_DELIVERY_RECEIPT_MAX_AGE_SECS120 segundos
DEFAULT_MAX_ATTEMPTS (reintentos de reenvío)3 intentos
MAX_IN_FLIGHT_BLIND_RELAY_REQUESTS64 solicitudes

Límite de frecuencia y cuarentena del salto anterior

Los límites de frecuencia se asocian a la identidad firmada del salto anterior. Más de 120 solicitudes de un mismo salto anterior en 60 segundos inician una cuarentena local de cinco minutos para ese salto. Una puntuación de fallos independiente inicia la misma cuarentena tras 12 fallos puntuados en cinco minutos. Solo estos motivos cuentan para la puntuación:

text
invalid_previous_hop | invalid_signature | self_loop | route_loop | ttl_exhausted

Los tiempos de espera agotados del transporte, los acuses perdidos, los reintentos duplicados y los conflictos de repetición no suman a la puntuación, de modo que un par en buen estado no queda en cuarentena por problemas de red. El almacén de buckets está acotado y los buckets inactivos se desalojan, por lo que la protección no puede convertirse en un grafo de comunicaciones a largo plazo.

Repetición de rutas y reintentos

Cada solicitud de relé lleva un ID de ruta. Cuando el almacén del relé de chat del nodo está habilitado ([memchain.chat_relay] enabled = true), las reservas de rutas y las respuestas completadas se guardan en su base de datos SQLite, por lo que la protección contra repeticiones sobrevive a un reinicio. En caso contrario, el nodo usa un registro en memoria con la misma capacidad y la misma ventana. Si las 8192 posiciones contienen rutas activas, las rutas nuevas se rechazan con replay_capacity hasta que caduquen posiciones.

Un ID de ruta repetido tiene uno de cuatro resultados:

SituaciónRespuestaEfecto sobre el salto anterior
Misma solicitud; el primer intento ha finalizadoSe reproduce la respuesta almacenada, incluido cualquier acuse firmado por el nodo terminal. No se entrega ni se reenvía nada por segunda vez (duplicate_route)Se cuenta como éxito
Misma solicitud; el primer intento sigue en cursoHTTP 503 route_in_flight. El remitente puede reintentarNinguno
Solicitud distinta con el mismo ID de rutaHTTP 400 replay_conflictSe registra en el estado del par. No suma a la puntuación de cuarentena
Misma solicitud, pero la respuesta almacenada tiene más de 120 segundosHTTP 409 replay_response_expired. La ruta sigue reservada durante el resto de su ventana de 600 segundos, por lo que no puede volver a ejecutarseNinguno

El último resultado se aplica al almacén persistente. Los acuses firmados solo son válidos como evidencia reciente, por lo que el nodo no reproduce uno pasados 120 segundos.

Cuando el reenvío al siguiente salto falla por un tiempo de espera agotado, un error de conexión o un error de solicitud, el nodo reintenta hasta un total de tres intentos. La breve espera antes de cada reintento se deriva del ID de ruta, del siguiente salto y del número de intento. Los fallos que el nodo posterior notifica como rechazos definitivos no se reintentan.

Admisión criptográfica (nota de capacidad para operadores)

Las comprobaciones de firmas, el pelado de capas cebolla y la firma de acuses consumen CPU, por lo que cada proceso de nodo los limita:

  • Posiciones totales: la mitad de los hilos de CPU que indica el host, redondeada hacia arriba, con un mínimo de 4 y un máximo de 8, de modo que incluso un host de uno o dos hilos obtiene 4 posiciones.
  • Solicitudes entrantes: una posición menos que el total, para que la creación de rutas salientes y la finalización de acuses siempre puedan avanzar. Por tanto, en los hosts más pequeños las solicitudes entrantes obtienen 3 posiciones.
  • Cuando todas las posiciones están ocupadas: la solicitud se rechaza de inmediato con HTTP 429 y el motivo backpressure. No espera en una cola.

Por tanto, en un host pequeño, un relé descarta carga pronto ante ráfagas. Un contador backpressure_dropped en aumento significa que el nodo necesita más CPU o menos tráfico de relé.

Contadores agregados de funcionamiento

Los nodos notifican contadores acumulados aproximados y marcas de tiempo de vigencia en su latido, bajo:

text
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 contadoresCampos
Entrada y disposiciónreceived, terminal, forwarded, rejected
Validación y proteccióninvalid_signature, envelope_too_large, ttl_exhausted, no_route, invalid_endpoint, loop_detected, replay_dropped, timestamp_rejected, rate_limited, quarantined, quarantine_started
Transporte y reintentosbackpressure_dropped, forward_failed, retry_attempted, retry_succeeded, retry_exhausted
Sondas sintéticasprobe_attempted, probe_succeeded, probe_failed, two_hop_probe_attempted, two_hop_probe_succeeded, two_hop_probe_failed
Entrega real y vigenciaverified_client_onion_deliveries, last_verified_client_onion_delivery_at, last_accepted_at, last_event_at

Estos contadores describen el funcionamiento del nodo. No son registros de mensajes ni datos de facturación, y no demuestran que haya tenido lugar ninguna conversación concreta.

Calidad de la evidencia

El resumen de calidad mantiene separados cuatro tipos de evidencia: el trabajo de relé opaco aceptado, las sondas sintéticas de accesibilidad, las sondas sintéticas de dos saltos y los acuses firmados por el nodo terminal para entregas originadas por clientes. real_relay_ready requiere un acuse de entrega de cliente reciente y autenticado. La evidencia sintética nunca se notifica como tráfico de usuarios.

statusSignificado
idleTodavía no hay actividad de relé ni de sondas
observingExiste algo de evidencia, pero la disponibilidad no está establecida
staleLa evidencia de éxito anterior ya no es reciente
readyTrabajo aceptado reciente o una prueba válida, sin ningún problema de transporte activo
protectingLas protecciones contra abusos se han activado mientras el relé sigue funcionando
degradedLos fallos de reenvío o de sondas requieren investigación
attentionLa contrapresión o los reintentos agotados requieren la atención inmediata del operador

proof_scope indica la evidencia más sólida observada: client_message_delivery, relay_acceptance, message_delivery, control_plane, single_hop_control_plane, attempted o none.

Estado de los pares sin relaciones de tráfico

peer_health_summary permite a los operadores encontrar un par que falla o que está en cuarentena sin ver quién se comunica con quién.

Incluido: un prefijo abreviado del ID del nodo, el estado aproximado de salud y del descriptor, la vigencia de la difusión y del éxito de rutas, los recuentos agregados de éxitos y fallos de rutas, el estado de cuarentena, el tiempo restante y categorías aproximadas de motivos.

Nunca incluido: claves públicas completas de nodos, ID de ruta, listas de endpoints, bloques cifrados ni hashes de cargas útiles, ID de mensajes, identidades de destinatarios, direcciones IP de clientes, destinos, datos DNS ni aristas del grafo social.

Mapa del código fuente

CapaRuta en el repositorio del nodoFunción
Orquestación del relécrates/aeronyx-server/src/api/chat_peer/blind_relay.rsControl de solicitudes, admisión criptográfica, autenticación, comprobaciones de bucles y TTL, resultados de repetición, reenvío y tratamiento terminal
Superficie HTTP y límitescrates/aeronyx-server/src/api/chat_peer.rsRutas, límites de cuerpo y de solicitudes en curso, códigos de error y categorías de motivos
Política contra abusoscrates/aeronyx-server/src/api/chat_peer_abuse_guard.rsLímites de frecuencia del salto anterior, puntuación de fallos y cuarentena
Registro de repeticionescrates/aeronyx-server/src/api/chat_peer_replay.rsRegistro en memoria y formato de la respuesta almacenada
Almacén persistente de repeticionescrates/aeronyx-server/src/services/chat_relay_blind_route_store.rsReservas de rutas y respuestas en SQLite
Política de reintentoscrates/aeronyx-server/src/api/chat_peer_retry.rsFallos reintentables frente a definitivos y tiempos de reintento
Contadores y calidadcrates/aeronyx-server/src/services/peer_store.rs y services/peer_store/status.rsContadores agregados, disponibilidad y clasificación de pruebas
Notificación del estadocrates/aeronyx-server/src/api/vpn_health.rs y management/reporter.rsJSON de estado local y carga útil del latido

El software de nodo es de código abierto bajo la AGPL-3.0 en github.com/AeroNyxNetwork/AeroNyx. Consulte Descubrimiento de nodos y relé cifrado multisalto para saber cómo se construyen las rutas.

<!-- faq:start -->

Preguntas frecuentes

¿Puede un nodo relé leer o registrar el tráfico que reenvía?

No. Un relé comprueba metadatos de enrutamiento firmados y reenvía un sobre opaco. Solo guarda contadores agregados, nunca cargas útiles, historiales de rutas ni identidades de destinatarios.

¿Qué ocurre cuando un nodo reintenta la misma ruta?

Si el primer intento ha terminado, el nodo reproduce su respuesta almacenada y no entrega nada por segunda vez. Si el primer intento sigue en curso, el nodo devuelve un route_in_flight reintentable. Una solicitud distinta con el mismo ID de ruta se rechaza como replay_conflict.

¿La protección contra repeticiones sobrevive a un reinicio del nodo?

Sí, cuando el almacén del relé de chat del nodo está habilitado. En ese caso, las reservas de rutas y las respuestas completadas se guardan en SQLite. Sin ese almacén, el nodo usa un registro en memoria que se borra al reiniciar.

¿Por qué se pone en cuarentena a un par?

Un par queda en cuarentena durante cinco minutos tras enviar más de 120 solicitudes en 60 segundos, o tras 12 fallos de validación puntuados en cinco minutos. Los tiempos de espera agotados, los acuses perdidos y los reintentos duplicados no cuentan como fallos.

¿Por qué mi nodo devuelve backpressure bajo carga?

Todas sus posiciones criptográficas de relé estaban ocupadas. Un nodo dedica aproximadamente la mitad de sus hilos de CPU (como mínimo 4 y como máximo 8) al trabajo de firmas y de capas cebolla, y rechaza de inmediato las solicitudes sobrantes en lugar de ponerlas en cola.

<!-- faq:end -->