2021-10-21 19:15:13 +01:00
|
|
|
# arti-client
|
2021-05-25 20:41:23 +01:00
|
|
|
|
|
|
|
High-level functionality for accessing the Tor network as a client.
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
2021-10-25 13:40:00 +01:00
|
|
|
The `arti-client` crate aims to provide a safe, easy-to-use API for
|
2022-03-01 13:30:53 +00:00
|
|
|
applications that want to use the Tor network to anonymize their traffic.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
This crate is part of [Arti](https://gitlab.torproject.org/tpo/core/arti/),
|
|
|
|
a project to implement [Tor](https://www.torproject.org/) in Rust. It is the
|
|
|
|
highest-level library crate in Arti, and the one that nearly all client-only
|
|
|
|
programs should use. Most of its functionality is provided by lower-level
|
|
|
|
crates in Arti.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2021-10-27 16:13:46 +01:00
|
|
|
### ⚠ Warnings ⚠
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
Note that Arti is a work in progress; although we've tried to write all the
|
|
|
|
critical security components, you probably shouldn't use Arti in production
|
|
|
|
until it's a bit more mature. (That said, now is a _great_ time to try
|
|
|
|
our Arti on an experimental basis, so you can tell us what we need
|
|
|
|
to fix between now and the 1.0.0 release.)
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
Also note that the APIs for this crate are not all yet
|
|
|
|
completely stable. We'll try not to break things without good
|
|
|
|
reason, and we'll follow semantic versioning when we do, but
|
|
|
|
please expect a certain amount of breakage between now and 1.0.0.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
The APIs exposed by lower-level crates in Arti are _even more
|
|
|
|
unstable_; they will break more often than those from
|
|
|
|
`arti-client`, for less reason.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
## Using `arti-client`
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
The main entry point for this crate is the [`TorClient`], an object that
|
|
|
|
lets you make connections over the Tor network.
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
### Connecting to Tor
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
Calling [`TorClient::create_bootstrapped`] establishes a connection to the Tor
|
|
|
|
network, pulling in necessary state about network consensus as required.
|
|
|
|
This state gets persisted to the locations specified in the
|
|
|
|
[`TorClientConfig`].
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
(This method requires you to initialize the client in an `async fn`. Consider
|
|
|
|
using the builder method, below, if that doesn't work for you.)
|
2021-10-29 00:59:22 +01:00
|
|
|
|
|
|
|
```rust
|
2021-11-29 14:29:37 +00:00
|
|
|
// The client configuration describes how to connect to the Tor network,
|
|
|
|
// and what directories to use for storing persistent state.
|
2022-01-11 14:37:45 +00:00
|
|
|
let config = TorClientConfig::default();
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
// 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.)
|
2022-03-01 13:30:53 +00:00
|
|
|
let tor_client = TorClient::create_bootstrapped(config).await?;
|
|
|
|
```
|
|
|
|
|
|
|
|
### Creating a client and connecting later
|
|
|
|
|
|
|
|
You might wish to create a Tor client immediately, without waiting for it to bootstrap (or
|
|
|
|
having to use an `await`). This can be done by making a [`TorClientBuilder`] with
|
|
|
|
[`TorClient::builder`], and calling [`TorClientBuilder::create_unbootstrapped`].
|
|
|
|
|
|
|
|
The returned client can be made to bootstrap when it is first used (the default), or not;
|
|
|
|
see [`BootstrapBehavior`] for more details.
|
|
|
|
|
|
|
|
```rust
|
|
|
|
// 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()?;
|
|
|
|
```
|
|
|
|
|
|
|
|
### Using the client
|
2021-11-29 12:40:20 +00:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
A client can then be used to make connections over Tor with
|
|
|
|
[`TorClient::connect`], which accepts anything implementing [`IntoTorAddr`].
|
|
|
|
This returns a [`DataStream`], an anonymized TCP stream type that implements
|
|
|
|
[`AsyncRead`](futures::io::AsyncRead) and
|
|
|
|
[`AsyncWrite`](futures::io::AsyncWrite), as well as the Tokio versions of
|
|
|
|
those traits if the `tokio` crate feature is enabled.
|
|
|
|
|
|
|
|
### Example: making connections over Tor
|
|
|
|
|
|
|
|
```rust
|
2022-03-29 18:30:17 +01:00
|
|
|
#
|
2021-11-29 14:29:37 +00:00
|
|
|
// Initiate a connection over Tor to example.com, port 80.
|
2022-01-11 14:37:45 +00:00
|
|
|
let mut stream = tor_client.connect(("example.com", 80)).await?;
|
2021-11-29 12:40:20 +00:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
use futures::io::{AsyncReadExt, AsyncWriteExt};
|
2021-11-29 12:40:20 +00:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
// 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?;
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
// IMPORTANT: Make sure the request was written.
|
|
|
|
// Arti buffers data, so flushing the buffer is usually required.
|
|
|
|
stream.flush().await?;
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
// Read and print the result.
|
|
|
|
let mut buf = Vec::new();
|
|
|
|
stream.read_to_end(&mut buf).await?;
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2021-11-29 14:29:37 +00:00
|
|
|
println!("{}", String::from_utf8_lossy(&buf));
|
2022-03-29 18:30:17 +01:00
|
|
|
#
|
2021-10-29 00:59:22 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
### More advanced usage
|
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
This version of Arti includes basic support for "stream isolation": the
|
|
|
|
ability to ensure that different TCP connections ('streams') go over
|
|
|
|
different Tor circuits (and thus different exit nodes, making them originate
|
|
|
|
from different IP addresses).
|
2021-10-29 00:59:22 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
This is useful to avoid deanonymizing users by correlation: for example, you
|
|
|
|
might want a Tor connection to your bank and a Tor connection to an online
|
|
|
|
forum to use different circuits, to avoid the possibility of the two
|
2021-10-29 00:59:22 +01:00
|
|
|
identities being linked by having the same source IP.
|
|
|
|
|
|
|
|
Streams can be isolated in two ways:
|
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
- by calling [`TorClient::isolated_client`], which returns a new
|
|
|
|
[`TorClient`] whose streams will use a different circuit
|
|
|
|
- by generating [`IsolationToken`]s, and passing them in via [`StreamPrefs`]
|
|
|
|
to [`TorClient::connect`].
|
2021-10-29 00:59:22 +01:00
|
|
|
|
|
|
|
## Multiple runtime support
|
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
Arti uses the [`tor_rtcompat`] crate to support multiple asynchronous
|
|
|
|
runtimes; currently, both [Tokio](https://tokio.rs) and
|
|
|
|
[async-std](https://async.rs) are supported.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
The backend Arti uses for TCP connections ([`tor_rtcompat::TcpProvider`]) and for
|
|
|
|
creating TLS sessions ([`tor_rtcompat::TlsProvider`]) is also configurable using
|
|
|
|
this crate. This can be used to embed Arti in custom environments where you want
|
|
|
|
lots of control over how it uses the network.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
[**View the `tor_rtcompat` crate documentation**](tor_rtcompat) for more about these features.
|
2021-05-25 20:41:23 +01:00
|
|
|
|
|
|
|
## Feature flags
|
|
|
|
|
2022-03-01 13:30:53 +00:00
|
|
|
* `tokio` (default) -- build with [Tokio](https://tokio.rs/) support
|
|
|
|
* `native-tls` (default) -- build with the [native-tls](https://github.com/sfackler/rust-native-tls)
|
|
|
|
crate for TLS support
|
|
|
|
* `async-std` -- build with [async-std](https://async.rs/) support
|
|
|
|
* `rustls` -- build with the [rustls](https://github.com/rustls/rustls) crate for TLS support
|
|
|
|
* `static` -- link with static versions of Arti's system dependencies, like SQLite and
|
|
|
|
OpenSSL (⚠ Warning ⚠: this feature will include a dependency on native-tls, even if you weren't
|
|
|
|
planning to use native-tls. If you only want to build with a static sqlite library, enable the
|
|
|
|
`static-sqlite` feature. We'll look for better solutions here in the future.)
|
|
|
|
* `static-sqlite` -- link with a static version of sqlite.
|
|
|
|
* `static-native-tls` -- link with a static version of `native-tls`. Enables `native-tls`.
|
|
|
|
* `experimental-api` -- build with experimental, unstable API support. Note
|
|
|
|
that these APIs are NOT covered by semantic versioning guarantees: we might
|
|
|
|
break them or remove them between patch versions.
|
|
|
|
* `error_detail` -- expose the `arti_client::Error` inner error type. Note
|
|
|
|
that this API is NOT covered by semantic versioning guarantees: we might
|
|
|
|
break it between patch versions.
|
|
|
|
|
|
|
|
Note that flags `tokio`, `native-tls`, `async-std`, `rustls` and `static` will enable
|
|
|
|
the flags of the same name on the [`tor_rtcompat`] crate.
|
2022-02-04 13:20:54 +00:00
|
|
|
|
2021-05-25 20:41:23 +01:00
|
|
|
License: MIT OR Apache-2.0
|