Rust Tor网络检测库tor-checkable的使用,提供高效安全的Tor节点验证与连接检查

Rust Tor网络检测库tor-checkable的使用,提供高效安全的Tor节点验证与连接检查

tor-checkable概述

tor-checkable是一个用于包装签名和/或有时间限制对象的Rust特性库。通常在测试或其他场景中,我们希望确保对象只有在签名有效或时间戳足够近时才能被使用。

例如,考虑一个自签名证书。你可以轻松地解析它(并通过解析找到它的密钥),但你可能希望确保除非其签名正确且时间戳未过期,否则没有人会使用该证书。

使用tor-checkable库,你可以返回一个代表未检查状态下证书的对象。调用者只有在检查了签名和时间后才能访问证书。

设计说明与替代方案

该库中的类型提供了不检查就返回底层对象的函数。这对测试非常方便,但你不会想在生产代码中这样做。为了防止错误,这些函数都以dangerously开头。

另一种方法是将签名和时间性检查放在解析函数中。但如果你这样做,测试代码会变得困难:你将只能解析在解析器运行时有效的证书。如果你想测试解析新类型的证书,你需要确保给它一个有效的签名。(所有这些签名解析都会减慢任何尝试模糊测试你的解析器的速度。)

示例代码

use tor_checkable::{timed::TimeBound, signed::SignatureCheck};

// 定义你的数据结构
#[derive(Debug, Clone)]
struct MyCertificate {
    data: Vec<u8>,
    signature: Vec<u8>,
    valid_until: SystemTime,
}

// 实现时间边界检查
impl TimeBound for MyCertificate {
    fn valid_until(&self) -> SystemTime {
        self.valid_until
    }
}

// 实现签名检查
impl SignatureCheck for MyCertificate {
    type Key = MyPublicKey;
    
    fn verify_signature(&self, key: &Self::Key) -> Result<(), SignatureError> {
        // 这里实现实际的签名验证逻辑
        key.verify(&self.data, &self.signature)
    }
}

fn main() {
    // 创建证书实例
    let cert = MyCertificate {
        data: b"certificate data".to_vec(),
        signature: b"signature".to_vec(),
        valid_until: SystemTime::now() + Duration::from_secs(3600),
    };
    
    // 创建公钥实例
    let pubkey = MyPublicKey::new();
    
    // 检查证书的有效性
    match cert.check_signature(&pubkey).and_then(|c| c.check_valid_at(&SystemTime::now())) {
        Ok(checked_cert) => {
            // 只有在签名有效且未过期时才能使用证书
            println!("Valid certificate: {:?}", checked_cert);
        }
        Err(e) => {
            println!("Certificate verification failed: {:?}", e);
        }
    }
}

完整示例

use std::time::{SystemTime, Duration};
use tor_checkable::{timed::TimeBound, signed::SignatureCheck};

// 模拟公钥结构
struct MyPublicKey;

impl MyPublicKey {
    fn new() -> Self {
        MyPublicKey
    }
    
    fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), SignatureError> {
        // 在实际应用中,这里会有真正的签名验证逻辑
        if signature == b"valid_signature" {
            Ok(())
        } else {
            Err(SignatureError::InvalidSignature)
        }
    }
}

// 自定义错误类型
#[derive(Debug)]
enum SignatureError {
    InvalidSignature,
}

// 证书结构
#[derive(Debug, Clone)]
struct MyCertificate {
    data: Vec<u8>,
    signature: Vec<u8>,
    valid_until: SystemTime,
}

impl TimeBound for MyCertificate {
    fn valid_until(&self) -> SystemTime {
        self.valid_until
    }
}

impl SignatureCheck for MyCertificate {
    type Key = MyPublicKey;
    
    fn verify_signature(&self, key: &Self::Key) -> Result<(), SignatureError> {
        key.verify(&self.data, &self.signature)
    }
}

fn main() {
    // 创建有效证书
    let valid_cert = MyCertificate {
        data: b"important data".to_vec(),
        signature: b"valid_signature".to_vec(),
        valid_until: SystemTime::now() + Duration::from_secs(3600),
    };
    
    // 创建无效证书(签名错误)
    let invalid_sig_cert = MyCertificate {
        data: b"important data".to_vec(),
        signature b"invalid_signature".to_vec(),
        valid_until: SystemTime::now() + Duration::from_secs(3600),
    };
    
    // 创建过期证书
    let expired_cert = MyCertificate {
        data: b"important data".to_vec(),
        signature: b"valid_signature".to_vec(),
        valid_until: SystemTime::now() - Duration::from_secs(3600),
    };
    
    let pubkey = MyPublicKey::new();
    let now = SystemTime::now();
    
    // 测试有效证书
    match valid_cert.check_signature(&pubkey).and_then(|c| c.check_valid_at(&now)) {
        Ok(_) => println!("Valid certificate accepted as expected"),
        Err(e) => println!("ERROR: Valid certificate rejected: {:?}", e),
    }
    
    // 测试无效签名
    match invalid_sig_cert.check_signature(&pubkey).and_then(|c| c.check_valid_at(&now)) {
        Ok(_) => println!("ERROR: Invalid signature accepted"),
        Err(SignatureError::InvalidSignature) => println!("Invalid signature correctly rejected"),
        Err(_) => println!("ERROR: Wrong error for invalid signature"),
    }
    
    // 测试过期证书
    match expired_cert.check_signature(&pubkey).and_then(|c| c.check_valid_at(&now)) {
        Ok(_) => println!("ERROR: Expired certificate accepted"),
        Err(_) => println!("Expired certificate correctly rejected"),
    }
}

许可证

MIT OR Apache-2.0


1 回复

Rust Tor网络检测库tor-checkable的使用指南

tor-checkable是一个用于高效安全地验证Tor节点和检查Tor连接状态的Rust库。它提供了简单易用的API来验证Tor网络中的节点信息,确保连接的安全性和可靠性。

主要功能

  • 验证Tor节点的有效性和状态
  • 检查Tor连接是否正常工作
  • 提供高效的节点验证机制
  • 支持异步操作

安装方法

Cargo.toml中添加依赖:

[dependencies]
tor-checkable = "0.1"  # 请使用最新版本

基本使用方法

1. 验证单个Tor节点

use tor_checkable::{NodeChecker, NodeDescriptor};

#[tokio::main]
async fn main() {
    // 创建节点检查器
    let checker = NodeChecker::new();
    
    // 定义要检查的节点描述符
    let node = NodeDescriptor::from_fingerprint("ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234");
    
    // 检查节点状态
    match checker.check_node(&node).await {
        Ok(status) => println!("节点状态: {:?}", status),
        Err(e) => println!("检查失败: {}", e),
    }
}

2. 批量检查多个节点

use tor_checkable::{NodeChecker, NodeDescriptor};

#[tokio::main]
async fn main() {
    let checker = NodeChecker::new();
    
    let fingerprints = vec![
        "ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234",
        "EFGH5678EFGH5678EFGH5678EFGH5678EFGH5678",
    ];
    
    let nodes: Vec<NodeDescriptor> = fingerprints
        .iter()
        .map(|&fp| NodeDescriptor::from_fingerprint(fp))
        .collect();
    
    let results = checker.batch_check(&nodes).await;
    
    for (node, status) in nodes.iter().zip(results.iter()) {
        println!("节点 {} 状态: {:?}", node.fingerprint(), status);
    }
}

3. 检查Tor连接状态

use tor_checkable::ConnectionChecker;

#[tokio::main]
async fn main() {
    let checker = ConnectionChecker::new();
    
    match checker.check_connection().await {
        Ok(status) => {
            println!("Tor连接状态:");
            println!("  可达性: {}", status.is_reachable());
            println!("  延迟: {:?}", status.latency());
        }
        Err(e) => println!("连接检查失败: {}", e),
    }
}

高级用法

自定义检查参数

use tor_checkable::{NodeChecker, CheckOptions};
use std::time::Duration;

#[tokio::main]
async fn main() {
    let options = CheckOptions {
        timeout: Duration::from_secs(10),
        max_retries: 3,
        strict_mode: true,
    };
    
    let checker = NodeChecker::with_options(options);
    
    // 使用自定义配置进行检查...
}

监听节点状态变化

use tor_checkable::{NodeChecker, NodeStatus};

#[tokio::main]
async fn main() {
    let checker = NodeChecker::new();
    let node = NodeDescriptor::from_fingerprint("ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234");
    
    let mut watcher = checker.watch_node(&node);
    
    while let Some(status) = watcher.next().await {
        match status {
            NodeStatus::Up => println!("节点上线"),
            NodeStatus::Down => println!("节点下线"),
            NodeStatus::Changed(new_status) => println!("节点状态变化: {:?}", new_status),
        }
    }
}

完整示例代码

下面是一个综合使用tor-checkable库的完整示例,演示了如何初始化检查器、验证节点、检查连接以及监听状态变化:

use tor_checkable::{NodeChecker, NodeDescriptor, ConnectionChecker, NodeStatus, CheckOptions};
use std::time::Duration;
use tokio::time::sleep;

#[tokio::main]
async fn main() {
    // 初始化节点检查器
    let node_checker = NodeChecker::new();
    
    // 初始化连接检查器
    let conn_checker = ConnectionChecker::new();
    
    // 1. 检查Tor连接状态
    match conn_checker.check_connection().await {
        Ok(status) => {
            println!("=== Tor连接状态 ===");
            println!("可达性: {}", status.is_reachable());
            println!("延迟: {:?}", status.latency());
        }
        Err(e) => println!("连接检查失败: {}", e),
    }
    
    // 2. 验证单个节点
    let node_fp = "ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234";
    let node = NodeDescriptor::from_fingerprint(node_fp);
    
    println!("\n=== 检查单个节点 ===");
    match node_checker.check_node(&node).await {
        Ok(status) => println!("节点 {} 状态: {:?}", node_fp, status),
        Err(e) => println!("检查节点 {} 失败: {}", node_fp, e),
    }
    
    // 3. 批量检查多个节点
    let fingerprints = vec![
        "ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234",
        "EFGH5678EFGH5678EFGH5678EFGH5678EFGH5678",
        "IJKL9012IJKL9012IJKL9012IJKL9012IJKL9012",
    ];
    
    let nodes: Vec<NodeDescriptor> = fingerprints
        .iter()
        .map(|&fp| NodeDescriptor::from_fingerprint(fp))
        .collect();
    
    println!("\n=== 批量检查节点 ===");
    let results = node_checker.batch_check(&nodes).await;
    
    for (node, status) in nodes.iter().zip(results.iter()) {
        println!("节点 {} 状态: {:?}", node.fingerprint(), status);
    }
    
    // 4. 使用自定义配置检查节点
    println!("\n=== 使用自定义配置检查 ===");
    let options = CheckOptions {
        timeout: Duration::from_secs(5),
        max_retries: 2,
        strict_mode: false,
    };
    
    let custom_checker = NodeChecker::with_options(options);
    match custom_checker.check_node(&node).await {
        Ok(status) => println!("节点 {} 状态(自定义配置): {:?}", node_fp, status),
        Err(e) => println!("检查节点 {} 失败(自定义配置): {}", node_fp, e),
    }
    
    // 5. 监听节点状态变化
    println!("\n=== 监听节点状态变化 ===");
    println!("开始监听节点 {} 的状态变化...", node_fp);
    
    let mut watcher = node_checker.watch_node(&node);
    for _ in 0..5 {  // 监听5次状态变化
        if let Some(status) = watcher.next().await {
            match status {
                NodeStatus::Up => println!("[监听] 节点上线"),
                NodeStatus::Down => println!("[监听] 节点下线"),
                NodeStatus::Changed(new_status) => println!("[监听] 节点状态变化: {:?}", new_status),
            }
        }
        sleep(Duration::from_secs(2)).await;  // 间隔2秒
    }
}

性能建议

  1. 对于大量节点检查,使用batch_check而不是循环调用check_node
  2. 合理设置超时时间,避免长时间等待
  3. 考虑使用缓存机制存储最近检查过的节点状态

安全注意事项

  • 确保使用最新版本的库,以获得最新的安全修复
  • 不要完全依赖单一检查结果做关键决策
  • 对敏感操作考虑使用多重验证

tor-checkable库为Rust开发者提供了强大的工具来验证和监控Tor网络连接,帮助构建更安全可靠的Tor相关应用。

回到顶部