From 857fb55520145ece48b4b5cca0aa5d7fd8f6c69e Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Tue, 2 May 2023 11:44:24 +0400 Subject: [PATCH] feat(p2p): allow listener bind to differ from the tor forward address (#5357) Description --- Add `p2p.tor.listener_address_override` config to allow a listener bind address that differs from the forward_address for incoming tor connections. Motivation and Context --- This is useful for docker setups where containers are addressed by DNS. In this case, the forward_address would be `/dns4/my_base_node/tcp/xxxxx` and the `listener_address_override="/ip4/0.0.0.0/tcp/xxxxx"` How Has This Been Tested? --- Manually by setting the override to `"/ip4/0.0.0.0/tcp/12345"` and the forward_address to `/dns4/localhost/tcp/12345` What process can a PR reviewer use to test or verify this change? --- Breaking Changes --- - [x] None - [ ] Requires data directory on base node to be deleted - [ ] Requires hard fork - [ ] Other - Please specify --- base_layer/p2p/examples/gen_tor_identity.rs | 1 - base_layer/p2p/src/initialization.rs | 8 ++++++-- base_layer/p2p/src/transport.rs | 6 +++++- common/config/presets/c_base_node.toml | 4 +++- comms/core/examples/stress/node.rs | 2 +- comms/core/examples/tor.rs | 2 +- comms/core/src/tor/hidden_service/builder.rs | 2 +- comms/dht/examples/propagation/node.rs | 2 +- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/base_layer/p2p/examples/gen_tor_identity.rs b/base_layer/p2p/examples/gen_tor_identity.rs index 195f270354..d32e9ac27b 100644 --- a/base_layer/p2p/examples/gen_tor_identity.rs +++ b/base_layer/p2p/examples/gen_tor_identity.rs @@ -90,7 +90,6 @@ async fn main() { .with_port_mapping(port) .with_control_server_address(tor_control_addr) .build() - .await .unwrap() .create_hidden_service() .await diff --git a/base_layer/p2p/src/initialization.rs b/base_layer/p2p/src/initialization.rs index 616a3e96d4..5e7ba112a5 100644 --- a/base_layer/p2p/src/initialization.rs +++ b/base_layer/p2p/src/initialization.rs @@ -248,12 +248,16 @@ pub async fn spawn_comms_using_transport( TransportType::Tor => { let tor_config = transport_config.tor; debug!(target: LOG_TARGET, "Building TOR comms stack ({:?})", tor_config); + let listener_address_override = tor_config.listener_address_override.clone(); let mut hidden_service_ctl = initialize_hidden_service(tor_config).await?; // Set the listener address to be the address (usually local) to which tor will forward all traffic let transport = hidden_service_ctl.initialize_transport().await?; debug!(target: LOG_TARGET, "Comms and DHT configured"); + comms - .with_listener_address(hidden_service_ctl.proxied_address()) + .with_listener_address( + listener_address_override.unwrap_or_else(|| hidden_service_ctl.proxied_address()), + ) .with_hidden_service_controller(hidden_service_ctl) .spawn_with_transport(transport) .await? @@ -290,7 +294,7 @@ async fn initialize_hidden_service( builder = builder.with_tor_identity(identity); } - let hidden_svc_ctl = builder.build().await?; + let hidden_svc_ctl = builder.build()?; Ok(hidden_svc_ctl) } diff --git a/base_layer/p2p/src/transport.rs b/base_layer/p2p/src/transport.rs index 4bad376ecc..a220fa9d0e 100644 --- a/base_layer/p2p/src/transport.rs +++ b/base_layer/p2p/src/transport.rs @@ -147,8 +147,11 @@ 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. + /// If set, instructs tor to forward traffic the the provided address. Otherwise, an OS-assigned port on 127.0.0.1 + /// is used. pub forward_address: Option, + /// If set, the listener will bind to this address instead of the forward_address. + pub listener_address_override: Option, /// The tor identity to use to create the hidden service. If None, a new one will be generated. #[serde(skip)] pub identity: Option, @@ -195,6 +198,7 @@ impl Default for TorTransportConfig { proxy_bypass_addresses: vec![], proxy_bypass_for_outbound_tcp: false, forward_address: None, + listener_address_override: None, identity: None, } } diff --git a/common/config/presets/c_base_node.toml b/common/config/presets/c_base_node.toml index 888d32290e..f7c1b95348 100644 --- a/common/config/presets/c_base_node.toml +++ b/common/config/presets/c_base_node.toml @@ -223,8 +223,10 @@ listener_liveness_check_interval = 15 # 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 -# If set, instructs tor to forward traffic the the provided address. (e.g. "/ip4/127.0.0.1/tcp/0") (default = ) +# If set, instructs tor to forward traffic the the provided address. (e.g. "/dns4/my-base-node/tcp/32123") (default = OS-assigned port) #tor.forward_address = +# If set, the listener will bind to this address instead of the forward_address. You need to make sure that this listener is connectable from the forward_address. +#tor.listener_address_override = # Use a SOCKS5 proxy transport. This transport recognises any addresses supported by the proxy. # (use: type = "socks5") diff --git a/comms/core/examples/stress/node.rs b/comms/core/examples/stress/node.rs index a7c6631a43..6536b17572 100644 --- a/comms/core/examples/stress/node.rs +++ b/comms/core/examples/stress/node.rs @@ -139,7 +139,7 @@ pub async fn create( hs_builder = hs_builder.with_tor_identity(tor_identity); } - let mut hs_ctl = hs_builder.build().await?; + let mut hs_ctl = hs_builder.build()?; let transport = hs_ctl.initialize_transport().await?; builder diff --git a/comms/core/examples/tor.rs b/comms/core/examples/tor.rs index 21e126e68a..2b46d23f08 100644 --- a/comms/core/examples/tor.rs +++ b/comms/core/examples/tor.rs @@ -175,7 +175,7 @@ async fn setup_node_with_tor>( hs_builder = hs_builder.with_tor_identity(ident); } - let mut hs_controller = hs_builder.build().await?; + let mut hs_controller = hs_builder.build()?; let node_identity = Arc::new(NodeIdentity::random( &mut OsRng, diff --git a/comms/core/src/tor/hidden_service/builder.rs b/comms/core/src/tor/hidden_service/builder.rs index 21a19c58b0..bc385f7a31 100644 --- a/comms/core/src/tor/hidden_service/builder.rs +++ b/comms/core/src/tor/hidden_service/builder.rs @@ -156,7 +156,7 @@ impl HiddenServiceBuilder { impl HiddenServiceBuilder { /// Create a HiddenService with the given builder parameters. - pub async fn build(self) -> Result { + pub fn build(self) -> Result { let proxied_port_mapping = self .port_mapping .ok_or(HiddenServiceBuilderError::ProxiedPortMappingNotProvided)?; diff --git a/comms/dht/examples/propagation/node.rs b/comms/dht/examples/propagation/node.rs index 4f9dda1f82..e771b3d6af 100644 --- a/comms/dht/examples/propagation/node.rs +++ b/comms/dht/examples/propagation/node.rs @@ -103,7 +103,7 @@ pub async fn create>( hs_builder = hs_builder.with_tor_identity(tor_identity); } - let mut hs_ctl = hs_builder.build().await?; + let mut hs_ctl = hs_builder.build()?; let transport = hs_ctl.initialize_transport().await?; let comms_node = builder.with_listener_address(hs_ctl.proxied_address()).build()?;