#tor #arti #anonymity #privacy #client-connection #networking

fedimint-arti-client

用于连接Tor网络作为匿名客户端的库

1个不稳定版本

0.20.0 2024年7月30日

#968网络编程

Download history 124/week @ 2024-07-28

每月124次下载

MIT/Apache

5.5MB
85K SLoC

arti-client

作为客户端访问Tor网络的高级功能。

概述

arti-client crate旨在为想要使用Tor网络匿名化其流量的应用程序提供一个安全、易于使用的API。

此crate是Arti项目的一部分,该项目旨在使用Rust实现Tor。它是Arti中最顶层的库crate,几乎所有仅客户端的程序都应该使用它。其大部分功能由Arti中的低级crate提供。

API的形状和其他crate之间的关系

如果您的应用程序是使用异步Rust构建的,并且希望将Tor连接作为异步流(AsyncRead/AsyncWrite),则此处的API非常适合。如果您想要进行HTTP请求,请查看arti_hyper)。

如果您正在尝试将Arti与其他编程语言结合使用,目前最好的选择可能是以子进程的方式启动arti CLI SOCKS代理。我们尚未提供可以通过FFI公开的API;我们打算在未来添加此功能。

⚠ 注意事项 ⚠

请注意,此crate的API并非全部都完全稳定。我们将尽量避免在没有良好理由的情况下破坏东西,并且在我们声明arti-client 1.x时,我们将遵循语义版本控制。但请预计现在和声明arti-client 1.x之间可能会有一定程度的破坏。

Arti中低级crate公开的API更加不稳定;它们将比arti-client的API更频繁地破坏,并且理由更少。

使用arti-client

此crate的主要入口点是TorClient,这是一个对象,允许您通过Tor网络建立连接。

连接到Tor

调用 TorClient::create_bootstrapped 将建立一个与 Tor 网络的连接,并按需拉取有关网络共识的必要状态。此状态将被持久化到 TorClientConfig 指定的地方。

(此方法需要你在 async fn 中初始化客户端。如果这对你不起作用,请考虑使用下面的构建器方法。)

// The client configuration describes how to connect to the Tor network,
// and what directories to use for storing persistent state.
let config = TorClientConfig::default();

// Start the Arti client, and let it bootstrap a connection to the Tor network.
// (This takes a while to gather the necessary directory information.
// It uses cached information when possible.)
let tor_client = TorClient::create_bootstrapped(config).await?;

创建客户端并稍后连接

你可能希望立即创建一个 Tor 客户端,而不必等待其引导(或必须使用 await)。这可以通过使用 TorClientBuilder 并调用 TorClient::builder 来完成,然后调用 TorClientBuilder::create_unbootstrapped

返回的客户端在首次使用时可以引导(默认行为),也可以不引导;有关更多详细信息,请参阅 BootstrapBehavior

// Specifying `BootstrapBehavior::OnDemand` means the client will automatically
// bootstrap when it is used. `Manual` exists if you'd rather have full control.
let tor_client = TorClient::builder()
    .bootstrap_behavior(BootstrapBehavior::OnDemand)
    .create_unbootstrapped()?;

使用客户端

然后可以使用 TorClient::connect 来使用客户端通过 Tor 建立连接,该函数接受实现 IntoTorAddr 的任何内容。这返回一个 DataStream,这是一个实现了 AsyncReadAsyncWrite 的匿名化 TCP 流类型,如果启用了 tokio crate 功能,还将返回这些特质的 Tokio 版本。

示例:通过 Tor 建立连接

#
// Initiate a connection over Tor to example.com, port 80.
let mut stream = tor_client.connect(("example.com", 80)).await?;

use futures::io::{AsyncReadExt, AsyncWriteExt};

// Write out an HTTP request.
stream
    .write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n")
    .await?;

// IMPORTANT: Make sure the request was written.
// Arti buffers data, so flushing the buffer is usually required.
stream.flush().await?;

// Read and print the result.
let mut buf = Vec::new();
stream.read_to_end(&mut buf).await?;

println!("{}", String::from_utf8_lossy(&buf));
#

桥接使用

桥和可插拔传输(PT)可以用作审查规避工具,以在 Tor 被阻止的地方连接到 Tor。在 arti 中,它们通过 config::BridgesConfig 进行配置。你需要启用 pt-client 功能以支持 PT。请注意,可插拔传输需要单独安装,并且 Arti 不会自行提供它们。你可以在 TB 手册 中了解更多关于 PT 的信息。

更高级的使用

Arti 的这个版本包括了“流隔离”的基本支持:确保不同的 TCP 连接('流')通过不同的 Tor 电路(从而通过不同的出口节点,使它们来自不同的 IP 地址)。

这有助于避免通过相关性解密用户:例如,你可能希望银行和在线论坛的 Tor 连接使用不同的电路,以避免两个身份被相同源 IP 地址链接的可能性。

流可以通过两种方式隔离

多运行时支持

Arti 使用 tor_rtcompat 包来支持多个异步运行时;目前,既支持 Tokio 也支持 async-std

Arti 用于 TCP 连接的后端 (tor_rtcompat::TcpProvider) 和创建 TLS 会话的后端 (tor_rtcompat::TlsProvider) 也可以使用此包进行配置。这可以用于将 Arti 嵌入需要大量控制其网络使用的自定义环境。

查看 tor_rtcompat 包的文档 了解更多关于这些功能的信息。

报告 Arti 错误

Arti 经常输出非常长的调试信息,即使是开发者也难以理解。为了更好地了解程序中出了什么问题,对每个 match Error 和将 err.report() 记录下来,其中 err 是捕获到的错误。

例如,前面的例子可以修改为报告其中一个错误

// Initiate a connection over Tor to example.com, port 80.
// Note: here we try to handle the potential error using match
match tor_client.connect(("example.com", 80)).await {
    Ok(mut stream) => {
        eprintln!("sending request...");

        stream
            .write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n")
            .await?;

        // IMPORTANT: Make sure the request was written.
        // Arti buffers data, so flushing the buffer is usually required.
        stream.flush().await?;

        eprintln!("reading response...");

        // Read and print the result.
        let mut buf = Vec::new();
        stream.read_to_end(&mut buf).await?;

        println!("{}", String::from_utf8_lossy(&buf));
    }
    Err(err) => {
        // Use .report() on an error to get a nicer error message
        // Raw Debug output will be much harder to decipher for all parties involved
        eprintln!("{}", err.report());
    }
}

功能标志

可添加功能

  • tokio(默认)-- 带有 Tokio 支持构建

  • native-tls(默认)-- 使用 native-tls 包进行 TLS 支持构建

  • async-std -- 带有 async-std 支持构建

  • compression(默认)-- 支持下载压缩文档。需要 C 编译器。

  • bridge-client -- 带有桥接支持构建

  • onion-service-client -- 带有连接到洋葱服务的支持构建。请注意,这并不像 C-Tor 那么安全,不应用于安全性敏感的目的。

  • onion-service-service -- 带有运行洋葱服务的支持构建。请注意,这并不像 C-Tor 那么安全,不应用于安全性敏感的目的。

  • pt-client -- 带有可插拔传输支持构建

  • anyhow -- 带有从 anyhow::Error 中提取 ErrorHint 的支持构建

  • full -- 使用所有上述功能构建,包括其他 arti crate 的所有稳定附加功能。(此选项不包括实验性功能。它也不包括选择特定实现而排除其他实现的功能,或设置构建标志的功能。)

  • rustls -- 使用 rustls crate 构建以支持 TLS。由于它使用了 ring crate,该 crate 使用旧的 (3BSD/SSLEay) OpenSSL 许可证,这可能会引入许可兼容性问题,因此它不包括在 full 中。

请注意,标志 tokionative-tlsasync-stdrustlsstatic 将启用 tor_rtcompat crate 上同名标志。

  • static -- 链接 Arti 系统依赖的静态版本,如 SQLite 和 OpenSSL(⚠ 警告 ⚠:此功能将包括对 native-tls 的依赖,即使您没有计划使用 native-tls。如果您只想使用静态 sqlite 库构建,请启用 static-sqlite 功能。我们将在未来寻找更好的解决方案。)
  • static-sqlite -- 链接到静态版本的 sqlite。
  • static-native-tls -- 链接到 native-tls 的静态版本。启用 native-tls

加密加速功能

库默认不应启用这些功能,因为它们会替换一种实现为另一种实现。

  • accel-sha1-asm -- 如果可用,使用 SHA1 的汇编实现加速加密。
  • accel-openssl -- 使用 openssl 作为后端加速加密。

实验性和不稳定的功能

请注意,这些功能启用的 API 不受语义版本保证的覆盖:我们可能在补丁版本之间破坏它们或删除它们。

  • experimental-api -- 构建具有实验性和不稳定 API 支持的版本。
  • error_detail -- 揭示 arti_client::Error 内部错误类型。
  • dirfilter -- 揭示 DirFilter API,该 API 允许您在目录被使用之前修改网络目录。
  • experimental -- 构建所有上述实验性功能,以及来自其他 arti crate 的所有实验性功能。

[^1]: 记住,语义版本化是使各种 cargo 功能可靠工作的原因。明确地说:如果您想使 cargo update 仅进行安全更改,则不能启用这些功能。

许可证:MIT 或 Apache-2.0

依赖项

~46–66MB
~1M SLoC