Enhanced security for Tor hidden services
Protect against guard discovery attacks with persistent vanguard relay selection
🚀 Quick Start • ✨ Features • 💡 Examples • ⚙️ Configuration
vanguards-rs is a Rust implementation of vanguards, the Python addon for protecting Tor hidden services against guard discovery attacks. It provides the same security protections with Rust's safety guarantees and async-first design.
Even with Tor's v3 onion service protocol, hidden services face sophisticated attacks that require additional defenses. vanguards-rs implements these defenses as a controller addon, protecting your onion services ahead of their integration into Tor core.
use vanguards_rs::{Config, Vanguards};
#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
// Load configuration and run protection
let config = Config::default();
let mut vanguards = Vanguards::from_config(config).await?;
vanguards.run().await
}|
Persistent guard relay selection at multiple layers to prevent guard discovery attacks.
|
Detect bandwidth-based side-channel attacks through circuit analysis.
|
|
Statistical detection of rendezvous point overuse attacks.
|
Monitor Tor logs for security-relevant events.
|
|
Verify circuit construction timing to detect manipulation.
|
Verify circuit paths conform to vanguard configuration.
|
Add vanguards-rs to your Cargo.toml:
[dependencies]
vanguards-rs = "1"
tokio = { version = "1", features = ["full"] }Or install the CLI:
cargo install vanguards-rsAdd to your torrc:
ControlPort 9051
CookieAuthentication 1
DataDirectory /var/lib/tor
Or for Unix socket:
ControlSocket /run/tor/control
CookieAuthentication 1
DataDirectory /var/lib/tor
# Connect to default control port (127.0.0.1:9051)
vanguards-rs
# Connect via Unix socket
vanguards-rs --control-socket /run/tor/control
# Generate default configuration file
vanguards-rs --generate_config vanguards.conf
# Use custom configuration
vanguards-rs --config vanguards.conf# Run with default settings
vanguards-rs
# Connect to specific control port
vanguards-rs --control-ip 127.0.0.1 --control-port 9051
# Use Unix socket with custom state file
vanguards-rs --control-socket /run/tor/control --state /var/lib/tor/vanguards.state
# One-shot mode: set vanguards and exit
vanguards-rs --one-shot-vanguards
# Enable debug logging
vanguards-rs --loglevel DEBUG
# Log to file
vanguards-rs --logfile /var/log/vanguards.log# Disable specific components
vanguards-rs --disable-bandguards --disable-logguard
# Enable optional components
vanguards-rs --enable-cbtverify --enable-pathverifyuse vanguards_rs::{Config, Vanguards, LogLevel};
use std::path::PathBuf;
#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
// Create custom configuration
let mut config = Config::default();
config.control_port = Some(9051);
config.loglevel = LogLevel::Debug;
config.state_file = PathBuf::from("/var/lib/tor/vanguards.state");
// Enable optional components
config.enable_cbtverify = true;
config.enable_pathverify = true;
// Validate configuration
config.validate()?;
// Run vanguards protection
let mut vanguards = Vanguards::from_config(config).await?;
vanguards.run().await
}use vanguards_rs::Config;
use std::path::Path;
let config = Config::from_file(Path::new("vanguards.conf"))?;Configuration can be loaded from multiple sources (in order of precedence):
- CLI Arguments — Highest priority
- Environment Variables —
VANGUARDS_STATE,VANGUARDS_CONFIG - Config File — TOML format
- Defaults — Sensible defaults for all options
# Connection settings
control_ip = "127.0.0.1"
control_port = 9051
# control_socket = "/run/tor/control" # Alternative: Unix socket
# control_pass = "my_password" # If using password auth
# File paths
state_file = "vanguards.state"
# Logging
loglevel = "notice" # debug, info, notice, warn, error
# logfile = "/var/log/vanguards.log"
# Component toggles
enable_vanguards = true
enable_bandguards = true
enable_rendguard = true
enable_logguard = true
enable_cbtverify = false
enable_pathverify = false
# Operational settings
close_circuits = true
one_shot_vanguards = false
[vanguards]
num_layer1_guards = 2
num_layer2_guards = 4
num_layer3_guards = 8
min_layer2_lifetime_hours = 24
max_layer2_lifetime_hours = 1080 # 45 days
min_layer3_lifetime_hours = 1
max_layer3_lifetime_hours = 48
[bandguards]
circ_max_megabytes = 0 # 0 = disabled
circ_max_age_hours = 24
circ_max_hsdesc_kilobytes = 30
circ_max_disconnected_secs = 30
conn_max_disconnected_secs = 15
[rendguard]
use_global_start_count = 1000
use_scale_at_count = 20000
use_relay_start_count = 100
use_max_use_to_bw_ratio = 5.0
close_circuits_on_overuse = true
[logguard]
protocol_warns = true
dump_limit = 25
dump_level = "notice"| Module | Description |
|---|---|
api |
High-level Vanguards struct for programmatic use |
config |
Configuration management (TOML, CLI, environment) |
control |
Main event loop and Tor connection management |
vanguards |
Vanguard state and guard selection |
bandguards |
Bandwidth monitoring and attack detection |
rendguard |
Rendezvous point usage tracking |
logguard |
Tor log monitoring and buffering |
cbtverify |
Circuit build timeout verification |
pathverify |
Circuit path verification |
node_selection |
Bandwidth-weighted relay selection |
vanguards-rs is designed with security as a priority:
- Memory Safety — Passwords cleared after use (zeroize)
- File Permissions — State files written with 0600 permissions
- Input Validation — All external inputs validated
- Atomic Writes — State file corruption prevention
- Guard Persistence — Prevents restart-based guard discovery
- Async-first — Built on Tokio for high-performance async I/O
- Efficient State — Python pickle format for compatibility
- Low Overhead — Minimal CPU usage during normal operation
State files are compatible with Python vanguards for seamless migration:
# Migrate from Python vanguards
cp ~/.vanguards/vanguards.state ./vanguards.state
vanguards-rs --state vanguards.state- Rust 1.70+
- Tokio runtime
- Tor instance with control port enabled
# Run unit tests
cargo test| Feature | Python vanguards | vanguards-rs |
|---|---|---|
| Vanguard Selection | ✅ | ✅ |
| Bandwidth Monitoring | ✅ | ✅ |
| Rendezvous Analysis | ✅ | ✅ |
| Log Monitoring | ✅ | ✅ |
| CBT Verification | ✅ | ✅ |
| Path Verification | ✅ | ✅ |
| State Compatibility | ✅ | ✅ |
| Type Safety | ❌ | ✅ |
| Memory Safety | ❌ | ✅ |
| Async/Await | ❌ | ✅ |
Copyright 2026 vanguards-rs contributors
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Contributions are welcome! Please feel free to submit issues and pull requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation • crates.io • GitHub • Python vanguards
Built with 🦀 by the vanguards-rs contributors