Module vanguards

Module vanguards 

Source
Expand description

Vanguard state management and ExcludeNodes parsing.

This module provides persistent vanguard guard selection and state management, along with ExcludeNodes configuration parsing for relay exclusion.

§Overview

The vanguard system maintains persistent sets of guard relays at two layers:

  • Layer 2 Guards: Second-hop relays with longer lifetimes (1-45 days)
  • Layer 3 Guards: Third-hop relays with shorter lifetimes (1-48 hours)

Guards are selected using bandwidth-weighted random selection and rotated based on configurable lifetime parameters.

§Guard Layer Architecture

Vanguards protect hidden services by restricting which relays can be used at each position in the circuit:

┌────────────────────────────────────────────────────────────────────────────┐
│                    Hidden Service Circuit Path                             │
│                                                                            │
│  ┌──────────┐     ┌──────────┐       ┌──────────┐     ┌──────────┐         │
│  │  Client  │───▶│ Layer 1  │───▶ │ Layer 2  │───▶│ Layer 3  │───▶ HS  │
│  │          │    │ (Entry)  │      │ (Middle) │     │ (Middle) │           │
│  └──────────┘    └──────────┘      └──────────┘    └──────────┘            │
│                       │               │               │                    │
│                       ▼               ▼               ▼                    │
│                  ┌─────────┐    ┌─────────┐    ┌─────────┐                 │
│                  │ Tor's   │    │ 4-8     │    │ 4-8     │                 │
│                  │ Guard   │    │ Guards  │    │ Guards  │                 │
│                  │ System  │    │ 1-45    │    │ 1-48    │                 │
│                  │         │    │ days    │    │ hours   │                 │
│                  └─────────┘    └─────────┘    └─────────┘                 │
└────────────────────────────────────────────────────────────────────────────┘

§Guard Lifecycle

Guards progress through the following states:

                   ┌─────────────────┐
                   │    Selection    │
                   │ (BW-weighted)   │
                   └────────┬────────┘
                            │
                            ▼
                   ┌─────────────────┐
                   │     Active      │
                   │ (in guardset)   │
                   └────────┬────────┘
                            │
         ┌──────────────────┼──────────────────┐
         │                  │                  │
         ▼                  ▼                  ▼
   ┌───────────┐     ┌───────────┐     ┌───────────┐
   │  Expired  │     │   Down    │     │ Excluded  │
   │(lifetime) │     │(consensus)│     │(ExcludeN) │
   └───────────┘     └───────────┘     └───────────┘
         │                  │                  │
         └──────────────────┼──────────────────┘
                            │
                            ▼
                   ┌─────────────────┐
                   │    Removed      │
                   │ (replenished)   │
                   └─────────────────┘

§State Persistence

State is persisted in Python pickle format for compatibility with the Python vanguards implementation. This allows seamless migration between implementations.

┌─────────────────────────────────────────────────────────────────────────┐
│                        State File Format                                │
│                                                                         │
│  VanguardState {                                                        │
│      layer2: [                                                          │
│          GuardNode { idhex, chosen_at, expires_at },                    │
│          ...                                                            │
│      ],                                                                 │
│      layer3: [                                                          │
│          GuardNode { idhex, chosen_at, expires_at },                    │
│          ...                                                            │
│      ],                                                                 │
│      rendguard: RendGuard { use_counts, total_use_counts },             │
│      pickle_revision: 1,                                                │
│  }                                                                      │
└─────────────────────────────────────────────────────────────────────────┘

§What This Module Does NOT Do

§ExcludeNodes

The ExcludeNodes struct parses Tor’s ExcludeNodes configuration to filter out unwanted relays based on:

  • Fingerprints (40 hex characters, optionally prefixed with $)
  • Country codes ({cc} format)
  • IP networks (CIDR notation)
  • Nicknames

§Example

use vanguards_rs::vanguards::{VanguardState, GuardNode, ExcludeNodes};
use std::path::Path;

// Load or create vanguard state
let mut state = VanguardState::load_or_create(Path::new("vanguards.state"));

// Check current guards
println!("Layer 2 guards: {}", state.layer2_guardset());
println!("Layer 3 guards: {}", state.layer3_guardset());

// Parse exclusion configuration
let exclude = ExcludeNodes::parse("{us},{ru},BadRelay", None);
println!("Excluding {} countries", exclude.countries.len());

§Security Considerations

  • State files contain guard fingerprints - protect with appropriate permissions
  • Guard lifetimes use max-of-two-uniform distribution for better security
  • Atomic writes prevent state file corruption
  • Validation prevents loading corrupted or malicious state files

§See Also

Structs§

ExcludeNodes
Parsed ExcludeNodes configuration for relay filtering.
GuardNode
A guard node selected as a vanguard with lifetime metadata.
RendGuard
Rendezvous point usage tracking for detecting statistical attacks.
RendUseCount
Rendezvous point usage count for a single relay.
VanguardState
Persistent vanguard state containing guard layers and rendguard tracking.