diff --git a/Cargo.lock b/Cargo.lock index ba8da561af..c545037965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7562,6 +7562,7 @@ dependencies = [ "ip_network", "ip_network_table", "log", + "nym-network-defaults", "nym-sphinx", "nym-task", "nym-tun", diff --git a/common/client-core/src/client/base_client/storage/gateway_details.rs b/common/client-core/src/client/base_client/storage/gateway_details.rs index fe04aee5c3..d9eaddfa87 100644 --- a/common/client-core/src/client/base_client/storage/gateway_details.rs +++ b/common/client-core/src/client/base_client/storage/gateway_details.rs @@ -77,7 +77,7 @@ pub struct PersistedGatewayConfig { key_hash: Vec, /// Actual gateway details being persisted. - pub(crate) details: GatewayEndpointConfig, + pub details: GatewayEndpointConfig, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index b45b5483e9..bcf02d1f02 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -476,3 +476,11 @@ pub const DEFAULT_NYM_NODE_HTTP_PORT: u16 = 8080; pub const TOTAL_SUPPLY: u128 = 1_000_000_000_000_000; pub const DEFAULT_PROFIT_MARGIN: u8 = 10; + +// WIREGUARD +pub const WG_PORT: u16 = 51822; + +// The interface used to route traffic +pub const WG_TUN_BASE_NAME: &str = "nymwg"; +pub const WG_TUN_DEVICE_ADDRESS: &str = "10.1.0.1"; +pub const WG_TUN_DEVICE_NETMASK: &str = "255.255.255.0"; diff --git a/common/wireguard-types/src/lib.rs b/common/wireguard-types/src/lib.rs index 605b30ba82..8c10985cbc 100644 --- a/common/wireguard-types/src/lib.rs +++ b/common/wireguard-types/src/lib.rs @@ -15,5 +15,3 @@ pub use registration::{ #[cfg(feature = "verify")] pub use registration::HmacSha256; - -pub const WG_PORT: u16 = 51822; diff --git a/common/wireguard/Cargo.toml b/common/wireguard/Cargo.toml index f2ac47abdc..461282833d 100644 --- a/common/wireguard/Cargo.toml +++ b/common/wireguard/Cargo.toml @@ -26,6 +26,7 @@ futures = "0.3.28" ip_network = "0.4.1" ip_network_table = "0.2.0" log.workspace = true +nym-network-defaults = { path = "../network-defaults" } nym-task = { path = "../task" } nym-wireguard-types = { path = "../wireguard-types" } nym-sphinx = { path = "../nymsphinx" } diff --git a/common/wireguard/src/lib.rs b/common/wireguard/src/lib.rs index b987dbd31c..fe51636a05 100644 --- a/common/wireguard/src/lib.rs +++ b/common/wireguard/src/lib.rs @@ -44,9 +44,9 @@ pub async fn start_wireguard( // Start the tun device that is used to relay traffic outbound let config = tun_device::TunDeviceConfig { - base_name: setup::TUN_BASE_NAME.to_string(), - ip: setup::TUN_DEVICE_ADDRESS.parse().unwrap(), - netmask: setup::TUN_DEVICE_NETMASK.parse().unwrap(), + base_name: nym_network_defaults::WG_TUN_BASE_NAME.to_string(), + ip: nym_network_defaults::WG_TUN_DEVICE_ADDRESS.parse().unwrap(), + netmask: nym_network_defaults::WG_TUN_DEVICE_NETMASK.parse().unwrap(), }; let (tun, tun_task_tx, tun_task_response_rx) = tun_device::TunDevice::new(routing_mode, config); tun.start(); diff --git a/common/wireguard/src/setup.rs b/common/wireguard/src/setup.rs index a4ee4e582d..779554a6eb 100644 --- a/common/wireguard/src/setup.rs +++ b/common/wireguard/src/setup.rs @@ -7,11 +7,6 @@ use log::info; // The wireguard UDP listener pub const WG_ADDRESS: &str = "0.0.0.0"; -// The interface used to route traffic -pub const TUN_BASE_NAME: &str = "nymwg"; -pub const TUN_DEVICE_ADDRESS: &str = "10.1.0.1"; -pub const TUN_DEVICE_NETMASK: &str = "255.255.255.0"; - // The private key of the listener // Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE=" const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg="; diff --git a/common/wireguard/src/udp_listener.rs b/common/wireguard/src/udp_listener.rs index 88bab9c162..aada5b98f4 100644 --- a/common/wireguard/src/udp_listener.rs +++ b/common/wireguard/src/udp_listener.rs @@ -6,6 +6,7 @@ use boringtun::{ }; use futures::StreamExt; use log::error; +use nym_network_defaults::WG_PORT; use nym_task::TaskClient; use nym_wireguard_types::{ registration::GatewayClientRegistry, @@ -13,7 +14,7 @@ use nym_wireguard_types::{ active_peers::{ActivePeers, PeersByIp}, event::Event, }, - PeerPublicKey, WG_PORT, + PeerPublicKey, }; use tap::TapFallible; use tokio::{net::UdpSocket, sync::Mutex}; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 4e4dc04bf5..9a9e99dc92 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -705,9 +705,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -4764,10 +4764,15 @@ version = "0.1.0" dependencies = [ "base64 0.21.4", "boringtun", + "bytes", "dashmap", + "ip_network", + "ip_network_table", + "log", "nym-crypto", "serde", "thiserror", + "tokio", "x25519-dalek 2.0.0", ] diff --git a/nym-node/src/config/mod.rs b/nym-node/src/config/mod.rs index c8419d1ca9..3b712f2e63 100644 --- a/nym-node/src/config/mod.rs +++ b/nym-node/src/config/mod.rs @@ -1,8 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_config::defaults::DEFAULT_NYM_NODE_HTTP_PORT; -use nym_wireguard_types::WG_PORT; +use nym_config::defaults::{DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT}; use serde::{Deserialize, Serialize}; use serde_helpers::*; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 227ee5868c..1c18a5f3d0 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -11,7 +11,9 @@ use crate::{Error, Result}; use futures::channel::mpsc; use futures::StreamExt; use log::warn; -use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore; +use nym_client_core::client::base_client::storage::gateway_details::{ + GatewayDetailsStore, PersistedGatewayDetails, +}; use nym_client_core::client::base_client::storage::{ Ephemeral, MixnetClientStorage, OnDiskPersistent, }; @@ -24,6 +26,7 @@ use nym_client_core::{ client::{base_client::BaseClientBuilder, replies::reply_storage::ReplyStorageBackend}, config::GatewayEndpointConfig, }; +use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, WG_TUN_DEVICE_ADDRESS}; use nym_socks5_client_core::config::Socks5; use nym_task::manager::TaskStatus; use nym_task::{TaskClient, TaskHandle}; @@ -44,6 +47,7 @@ pub struct MixnetClientBuilder { gateway_config: Option, socks5_config: Option, + wireguard_mode: bool, wait_for_gateway: bool, custom_topology_provider: Option>, custom_gateway_transceiver: Option>, @@ -79,6 +83,7 @@ impl MixnetClientBuilder { storage_paths: None, gateway_config: None, socks5_config: None, + wireguard_mode: false, wait_for_gateway: false, custom_topology_provider: None, storage: storage_paths @@ -109,6 +114,7 @@ where storage_paths: None, gateway_config: None, socks5_config: None, + wireguard_mode: false, wait_for_gateway: false, custom_topology_provider: None, custom_gateway_transceiver: None, @@ -127,6 +133,7 @@ where storage_paths: self.storage_paths, gateway_config: self.gateway_config, socks5_config: self.socks5_config, + wireguard_mode: self.wireguard_mode, wait_for_gateway: self.wait_for_gateway, custom_topology_provider: self.custom_topology_provider, custom_gateway_transceiver: self.custom_gateway_transceiver, @@ -205,6 +212,13 @@ where self } + /// Attempt to wait for the selected gateway (if applicable) to come online if its currently not bonded. + #[must_use] + pub fn with_wireguard_mode(mut self, wireguard_mode: bool) -> Self { + self.wireguard_mode = wireguard_mode; + self + } + /// Attempt to wait for the selected gateway (if applicable) to come online if its currently not bonded. #[must_use] pub fn with_wait_for_gateway(mut self, wait_for_gateway: bool) -> Self { @@ -235,6 +249,7 @@ where .custom_gateway_transceiver(self.custom_gateway_transceiver) .custom_topology_provider(self.custom_topology_provider) .custom_shutdown(self.custom_shutdown) + .wireguard_mode(self.wireguard_mode) .wait_for_gateway(self.wait_for_gateway) .force_tls(self.force_tls); @@ -274,6 +289,9 @@ where /// advanced usage of custom gateways custom_gateway_transceiver: Option>, + /// If the client connects via Wireguard tunnel to the gateway. + wireguard_mode: bool, + /// Attempt to wait for the selected gateway (if applicable) to come online if its currently not bonded. wait_for_gateway: bool, @@ -326,6 +344,7 @@ where storage, custom_topology_provider: None, custom_gateway_transceiver: None, + wireguard_mode: false, wait_for_gateway: false, force_tls: false, custom_shutdown: None, @@ -356,6 +375,12 @@ where self } + #[must_use] + pub fn wireguard_mode(mut self, wireguard_mode: bool) -> Self { + self.wireguard_mode = wireguard_mode; + self + } + #[must_use] pub fn wait_for_gateway(mut self, wait_for_gateway: bool) -> Self { self.wait_for_gateway = wait_for_gateway; @@ -503,11 +528,7 @@ where let known_gateway = self.has_valid_gateway_info().await; - let mut base_builder: BaseClientBuilder<_, _> = - BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) - .with_wait_for_gateway(self.wait_for_gateway); - - if !known_gateway { + let mut base_builder: BaseClientBuilder<_, _> = if !known_gateway { let selection_spec = GatewaySelectionSpecification::new( self.config.user_chosen_gateway, None, @@ -515,14 +536,49 @@ where ); let mut rng = OsRng; + let mut available_gateways = current_gateways(&mut rng, &nym_api_endpoints).await?; + if self.wireguard_mode { + available_gateways + .iter_mut() + .for_each(|node| node.host = WG_TUN_DEVICE_ADDRESS.parse().unwrap()); + } let setup = GatewaySetup::New { specification: selection_spec, - available_gateways: current_gateways(&mut rng, &nym_api_endpoints).await?, + available_gateways, overwrite_data: !self.config.key_mode.is_keep(), }; - base_builder = base_builder.with_gateway_setup(setup) - } + BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + .with_wait_for_gateway(self.wait_for_gateway) + .with_gateway_setup(setup) + } else if self.wireguard_mode { + if let Ok(PersistedGatewayDetails::Default(mut config)) = self + .storage + .gateway_details_store() + .load_gateway_details() + .await + { + config.details.gateway_listener = format!( + "ws://{}:{}", + WG_TUN_DEVICE_ADDRESS, DEFAULT_CLIENT_LISTENING_PORT + ); + if let Err(e) = self + .storage + .gateway_details_store() + .store_gateway_details(&PersistedGatewayDetails::Default(config)) + .await + { + warn!("Could not switch to using wireguard mode - {:?}", e); + } + } else { + warn!("Storage type not supported with wireguard mode"); + } + BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + .with_wait_for_gateway(self.wait_for_gateway) + } else { + BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + .with_wait_for_gateway(self.wait_for_gateway) + }; if let Some(topology_provider) = self.custom_topology_provider { base_builder = base_builder.with_topology_provider(topology_provider);