Expand description
Rendezvous point monitoring for detecting statistical attacks.
This module provides protection against statistical attacks on hidden services by monitoring rendezvous point usage patterns. It detects when a relay is being used as a rendezvous point more frequently than expected based on its bandwidth.
§Overview
The rendguard system tracks:
- Usage counts: How many times each relay has been used as a rendezvous point
- Expected weights: The expected usage based on bandwidth proportion
- Overuse detection: When a relay is used more than expected
§Overuse Detection Flow
┌─────────────────────────────────────────────────────────────────────────┐
│ Rendezvous Point Usage Check │
│ │
│ ┌─────────────────────┐ │
│ │ HS_SERVICE_REND │ │
│ │ Circuit Created │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Extract RP │ │
│ │ Fingerprint │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Increment Usage │ │
│ │ Count │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌───────────┐ ┌─────────────────┐ │
│ │ total_uses < │ │ relay_uses│ │ Check Ratio: │ │
│ │ global_start? │ │ < relay_ │ │ used/total > │ │
│ │ │ │ start? │ │ weight * max? │ │
│ └────────┬────────┘ └─────┬─────┘ └────────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ [VALID] [VALID] ┌────────┴────────┐ │
│ │ │ │
│ ▼ ▼ │
│ [OVERUSED] [VALID] │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Log Warning │ │
│ │ (potential attack) │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘§Attack Detection
An attacker controlling a relay could try to become the rendezvous point for a target hidden service more often than expected. This module detects such statistical anomalies by comparing actual usage to expected bandwidth-weighted usage.
Detection Formula:
overused = (relay_uses / total_uses) > (relay_weight * max_ratio)
Where:
relay_uses = Number of times this relay was used as RP
total_uses = Total RP uses across all relays
relay_weight = Relay's bandwidth / total network bandwidth
max_ratio = Configured maximum use-to-bandwidth ratio (default: 5.0)§Usage Tracking
┌─────────────────────────────────────────────────────────────────────────┐
│ RendGuard State │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ use_counts: HashMap<String, RendUseCount> │ │
│ │ │ │
│ │ Fingerprint │ Used │ Weight │ │
│ │ ─────────────────────┼───────┼──────── │ │
│ │ AABBCCDD... │ 15 │ 0.0023 │ │
│ │ EEFF0011... │ 8 │ 0.0015 │ │
│ │ NOT_IN_CONSENSUS │ 2 │ 0.01 (churn allowance) │ │
│ │ ... │ ... │ ... │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ total_use_counts: 1250 │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Scaling: When total_use_counts >= use_scale_at_count │ │
│ │ All counts are halved to prevent unbounded growth │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘§What This Module Does NOT Do
- Guard selection: Use
crate::vanguardsfor guard management - Circuit closure: Use
crate::controlfor circuit management - Bandwidth monitoring: Use
crate::bandguardsfor bandwidth attacks
§Configuration
Key configuration options in RendguardConfig:
| Option | Default | Description |
|---|---|---|
use_global_start_count | 1000 | Minimum total uses before checking |
use_relay_start_count | 100 | Minimum relay uses before checking |
use_max_use_to_bw_ratio | 5.0 | Maximum ratio of use to bandwidth |
use_scale_at_count | 20000 | Scale counts when reaching this total |
use_max_consensus_weight_churn | 1.0 | Weight for NOT_IN_CONSENSUS relays |
§Example
use vanguards_rs::rendguard::{RendGuard, RendUseCount, RendCheckResult};
use vanguards_rs::config::RendguardConfig;
let mut rendguard = RendGuard::new();
let config = RendguardConfig::default();
// Simulate relay usage
let fingerprint = "AABBCCDD00112233445566778899AABBCCDDEEFF";
// Check if usage is valid
let valid = rendguard.valid_rend_use(fingerprint, &config);
if !valid {
let usage_rate = rendguard.usage_rate(fingerprint);
let expected = rendguard.expected_weight(fingerprint);
println!("Overuse detected: {:.2}% vs expected {:.2}%", usage_rate, expected);
}§Security Considerations
- Start counts prevent false positives during initial operation
- Scaling prevents long-running relays from accumulating unfair counts
- NOT_IN_CONSENSUS tracking catches relays that leave the network
- Weight churn allowance handles consensus changes gracefully
§See Also
crate::config::RendguardConfig- Configuration optionscrate::vanguards::RendGuard- Main implementation (re-exported here)crate::vanguards::RendUseCount- Per-relay usage tracking- Python vanguards rendguard - Original implementation
Re-exports§
pub use crate::vanguards::RendGuard;pub use crate::vanguards::RendUseCount;
Enums§
- Rend
Check Result - Result of checking a rendezvous point usage.
Constants§
- NOT_
IN_ CONSENSUS_ ID - Identifier used for relays not in the current consensus.