Skip to content

Commit

Permalink
feat(p2p): adds tor.forward_address setting (#4070)
Browse files Browse the repository at this point in the history
Description
---
Adds `tor.forward_address` to instruct tor to forward traffic to a custom address 

Motivation and Context
---
This setting is useful for docker setups where tor and the base node listener are accessible through DNS addresses.

How Has This Been Tested?
---
Manually: setting `tor.forward_address` and checking that traffic is forwarded through that port.
  • Loading branch information
sdbondi authored May 3, 2022
1 parent c2d60b3 commit 8c78717
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
9 changes: 6 additions & 3 deletions base_layer/p2p/src/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ pub enum CommsInitializationError {
FailedToAddSeedPeer(#[from] PeerManagerError),
#[error("Cannot acquire exclusive file lock, another instance of the application is already running")]
CannotAcquireFileLock,
#[error("Invalid tor forward address: `{0}`")]
InvalidTorForwardAddress(std::io::Error),
#[error("IO Error: `{0}`")]
IoError(#[from] std::io::Error),
}
Expand Down Expand Up @@ -249,10 +251,10 @@ pub async fn spawn_comms_using_transport(

async fn initialize_hidden_service(
mut config: TorTransportConfig,
) -> Result<tor::HiddenServiceController, tor::HiddenServiceBuilderError> {
) -> Result<tor::HiddenServiceController, CommsInitializationError> {
let mut builder = tor::HiddenServiceBuilder::new()
.with_hs_flags(tor::HsFlags::DETACH)
.with_port_mapping(config.to_port_mapping())
.with_port_mapping(config.to_port_mapping()?)
.with_socks_authentication(config.to_socks_auth())
.with_control_server_auth(config.to_control_auth())
.with_socks_address_override(config.socks_address_override)
Expand All @@ -267,7 +269,8 @@ async fn initialize_hidden_service(
builder = builder.with_tor_identity(identity);
}

builder.build().await
let hidden_svc_ctl = builder.build().await?;
Ok(hidden_svc_ctl)
}

async fn configure_comms_and_dht(
Expand Down
23 changes: 20 additions & 3 deletions base_layer/p2p/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ use tari_comms::{
tor,
tor::TorIdentity,
transports::{predicate::FalsePredicate, SocksConfig},
utils::multiaddr::multiaddr_to_socketaddr,
};

use crate::{SocksAuthentication, TorControlAuthentication};
use crate::{initialization::CommsInitializationError, SocksAuthentication, TorControlAuthentication};

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -146,14 +147,29 @@ pub struct TorTransportConfig {
/// When set to true, outbound TCP connections bypass the tor proxy. Defaults to false for better privacy, setting
/// to true may improve network performance for TCP nodes.
pub proxy_bypass_for_outbound_tcp: bool,
/// If set, instructs tor to forward traffic the the provided address.
pub forward_address: Option<Multiaddr>,
/// The tor identity to use to create the hidden service. If None, a new one will be generated.
#[serde(skip)]
pub identity: Option<TorIdentity>,
}

impl TorTransportConfig {
pub fn to_port_mapping(&self) -> tor::PortMapping {
tor::PortMapping::new(self.onion_port.get(), ([127, 0, 0, 1], 0).into())
/// Returns a [self::tor::PortMapping] struct that maps the [onion_port] to an address that is listening for
/// traffic. If [forward_address] is set, that address is used, otherwise 127.0.0.1:[onion_port] is used.
///
/// [onion_port]: TorTransportConfig::onion_port
/// [forward_address]: TorTransportConfig::forward_address
pub fn to_port_mapping(&self) -> Result<tor::PortMapping, CommsInitializationError> {
let forward_addr = self
.forward_address
.as_ref()
.map(|addr| multiaddr_to_socketaddr(addr))
.transpose()
.map_err(CommsInitializationError::InvalidTorForwardAddress)?
.unwrap_or_else(|| ([127, 0, 0, 1], 0).into());

Ok(tor::PortMapping::new(self.onion_port.get(), forward_addr))
}

pub fn to_control_auth(&self) -> tor::Authentication {
Expand All @@ -175,6 +191,7 @@ impl Default for TorTransportConfig {
onion_port: NonZeroU16::new(18141).unwrap(),
proxy_bypass_addresses: vec![],
proxy_bypass_for_outbound_tcp: false,
forward_address: None,
identity: None,
}
}
Expand Down
2 changes: 2 additions & 0 deletions common/config/presets/base_node.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ tor.proxy_bypass_addresses = []
#tor.proxy_bypass_addresses = ["/dns4/my-foo-base-node/tcp/9998"]
# When using the tor transport and set to true, outbound TCP connections bypass the tor proxy. Defaults to false for better privacy
tor.proxy_bypass_for_outbound_tcp = false
# Custom address to forward tor traffic.
#tor.forward_address = "/ip4/127.0.0.1/tcp/0"

# Use a SOCKS5 proxy transport. This transport recognises any addresses supported by the proxy.
#type = "socks5"
Expand Down

0 comments on commit 8c78717

Please sign in to comment.