Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gateway/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ pub enum GatewayError {
#[error("failed to startup local ip packet router")]
IpPacketRouterStartupFailure,

#[error("failed to startup local authenticator")]
AuthenticatorStartupFailure,

#[error("there are no nym API endpoints available")]
NoNymApisAvailable,

Expand Down
89 changes: 72 additions & 17 deletions gateway/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ struct StartedNetworkRequester {
handle: LocalEmbeddedClientHandle,
}

// TODO: should this struct live here?
#[allow(unused)]
struct StartedAuthenticator {
#[cfg(feature = "wireguard")]
wg_api: Arc<nym_wireguard::WgApiWrapper>,

/// Handle to interact with the local authenticator
handle: LocalEmbeddedClientHandle,
}

/// Wire up and create Gateway instance
pub async fn create_gateway(
config: Config,
Expand Down Expand Up @@ -238,17 +248,63 @@ impl<St> Gateway<St> {
#[cfg(all(feature = "wireguard", target_os = "linux"))]
async fn start_authenticator(
&mut self,
opts: &LocalAuthenticatorOpts,
forwarding_channel: MixForwardingSender,
shutdown: TaskClient,
) -> Result<Arc<nym_wireguard::WgApiWrapper>, Box<dyn std::error::Error + Send + Sync>> {
) -> Result<StartedAuthenticator, Box<dyn std::error::Error + Send + Sync>> {
let opts = self
.authenticator_opts
.as_ref()
.ok_or(GatewayError::UnspecifiedAuthenticatorConfig)?;
let (router_tx, mut router_rx) = oneshot::channel();
let (auth_mix_sender, auth_mix_receiver) = mpsc::unbounded();
let router_shutdown = shutdown.fork("message_router");
let transceiver = LocalGateway::new(
*self.identity_keypair.public_key(),
forwarding_channel,
router_tx,
);

if let Some(wireguard_data) = self.wireguard_data.take() {
let authenticator_server = nym_authenticator::Authenticator::new(
let (on_start_tx, on_start_rx) = oneshot::channel();
let mut authenticator_server = nym_authenticator::Authenticator::new(
opts.config.clone(),
wireguard_data.inner.clone(),
)
.with_shutdown(shutdown.fork("authenticator"));
tokio::spawn(async move { authenticator_server.run_service_provider().await });
nym_wireguard::start_wireguard(shutdown, wireguard_data).await
.with_custom_gateway_transceiver(Box::new(transceiver))
.with_shutdown(shutdown.fork("authenticator"))
.with_wait_for_gateway(true)
.with_minimum_gateway_performance(0)
.with_on_start(on_start_tx);

if let Some(custom_mixnet) = &opts.custom_mixnet_path {
authenticator_server = authenticator_server.with_stored_topology(custom_mixnet)?
}

tokio::spawn(async move {
if let Err(e) = authenticator_server.run_service_provider().await {
log::error!("Run authenticator server - {e}");
}
});

let start_data = on_start_rx
.await
.map_err(|_| GatewayError::AuthenticatorStartupFailure)?;

// this should be instantaneous since the data is sent on this channel before the on start is called;
// the failure should be impossible
let Ok(Some(packet_router)) = router_rx.try_recv() else {
return Err(Box::new(GatewayError::AuthenticatorStartupFailure));
};

MessageRouter::new(auth_mix_receiver, packet_router)
.start_with_shutdown(router_shutdown);

let wg_api = nym_wireguard::start_wireguard(shutdown, wireguard_data).await?;

Ok(StartedAuthenticator {
wg_api,
handle: LocalEmbeddedClientHandle::new(start_data.address, auth_mix_sender),
})
} else {
Err(Box::new(GatewayError::WireguardNotSet))
}
Expand All @@ -257,9 +313,9 @@ impl<St> Gateway<St> {
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
async fn start_authenticator(
&self,
_opts: &LocalAuthenticatorOpts,
_forwarding_channel: MixForwardingSender,
_shutdown: TaskClient,
) -> Result<Arc<nym_wireguard::WgApiWrapper>, Box<dyn std::error::Error + Send + Sync>> {
) -> Result<StartedAuthenticator, Box<dyn std::error::Error + Send + Sync>> {
todo!("Authenticator is currently only supported on Linux");
}

Expand Down Expand Up @@ -554,7 +610,7 @@ impl<St> Gateway<St> {
if self.config.ip_packet_router.enabled {
let embedded_ip_sp = self
.start_ip_packet_router(
mix_forwarding_channel,
mix_forwarding_channel.clone(),
shutdown.fork("ip_service_provider"),
)
.await?;
Expand All @@ -564,14 +620,13 @@ impl<St> Gateway<St> {
};

#[cfg(feature = "wireguard")]
let _wg_api = if let Some(opts) = self.authenticator_opts.clone() {
Some(
self.start_authenticator(&opts, shutdown.fork("wireguard"))
.await
.map_err(|source| GatewayError::AuthenticatorStartError { source })?,
)
} else {
None
let _wg_api = {
let embedded_auth = self
.start_authenticator(mix_forwarding_channel, shutdown.fork("authenticator"))
.await
.map_err(|source| GatewayError::AuthenticatorStartError { source })?;
active_clients_store.insert_embedded(embedded_auth.handle);
Some(embedded_auth.wg_api)
};

if self.run_http_server {
Expand Down
6 changes: 0 additions & 6 deletions nym-node/src/cli/commands/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,6 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
bind_address: SocketAddr::new(ip, cfg.gateway.clients_port),
announce_ws_port: None,
announce_wss_port: cfg.gateway.clients_wss_port,
authenticator: config::authenticator::Authenticator {
debug: Default::default(),
},
debug: config::entry_gateway::Debug {
message_retrieval_limit: cfg.debug.message_retrieval_limit,
},
Expand Down Expand Up @@ -457,9 +454,6 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
.unwrap_or_default(),
},
},
authenticator: config::authenticator::Authenticator {
debug: Default::default(),
},
}),
)
.build();
Expand Down
49 changes: 43 additions & 6 deletions nym-node/src/config/entry_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use crate::error::EntryGatewayError;
use nym_config::defaults::DEFAULT_CLIENT_LISTENING_PORT;
use nym_config::helpers::inaddr_any;
use nym_config::serde_helpers::de_maybe_port;
use nym_gateway::node::LocalAuthenticatorOpts;
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::path::Path;

use super::authenticator::Authenticator;
use super::helpers::{base_client_config, EphemeralConfig};
use super::LocalWireguardOpts;

pub const DEFAULT_WS_PORT: u16 = DEFAULT_CLIENT_LISTENING_PORT;

Expand Down Expand Up @@ -40,8 +42,6 @@ pub struct EntryGatewayConfig {
#[serde(deserialize_with = "de_maybe_port")]
pub announce_wss_port: Option<u16>,

pub authenticator: Authenticator,

#[serde(default)]
pub debug: Debug,
}
Expand Down Expand Up @@ -73,7 +73,6 @@ impl EntryGatewayConfig {
bind_address: SocketAddr::new(inaddr_any(), DEFAULT_WS_PORT),
announce_ws_port: None,
announce_wss_port: None,
authenticator: Default::default(),
debug: Default::default(),
}
}
Expand All @@ -83,6 +82,44 @@ impl EntryGatewayConfig {
pub fn ephemeral_entry_gateway_config(
config: Config,
mnemonic: &bip39::Mnemonic,
) -> Result<nym_gateway::config::Config, EntryGatewayError> {
Ok(ephemeral_gateway_config(config, mnemonic)?)
) -> Result<EphemeralConfig, EntryGatewayError> {
let auth_opts = LocalAuthenticatorOpts {
config: nym_authenticator::Config {
base: nym_client_core_config_types::Config {
client: base_client_config(&config),
debug: config.authenticator.debug.client_debug,
},
authenticator: config.wireguard.clone().into(),
storage_paths: nym_authenticator::config::AuthenticatorPaths {
common_paths: config
.exit_gateway
.storage_paths
.authenticator
.to_common_client_paths(),
},
logging: config.logging,
},
custom_mixnet_path: None,
};

let wg_opts = LocalWireguardOpts {
config: super::Wireguard {
enabled: config.wireguard.enabled,
bind_address: config.wireguard.bind_address,
private_ip: config.wireguard.private_ip,
announced_port: config.wireguard.announced_port,
private_network_prefix: config.wireguard.private_network_prefix,
storage_paths: config.wireguard.storage_paths.clone(),
},
custom_mixnet_path: None,
};

let gateway = ephemeral_gateway_config(config, mnemonic)?;
Ok(EphemeralConfig {
nr_opts: None,
ipr_opts: None,
auth_opts,
wg_opts,
gateway,
})
}
35 changes: 7 additions & 28 deletions nym-node/src/config/exit_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::config::helpers::ephemeral_gateway_config;
use crate::config::persistence::ExitGatewayPaths;
use crate::config::Config;
use crate::error::ExitGatewayError;
use clap::crate_version;
use nym_client_core_config_types::DebugConfig as ClientDebugConfig;
use nym_config::defaults::mainnet;
use nym_gateway::node::{
Expand All @@ -15,7 +14,10 @@ use serde::{Deserialize, Serialize};
use std::path::Path;
use url::Url;

use super::{authenticator::Authenticator, LocalWireguardOpts};
use super::{
helpers::{base_client_config, EphemeralConfig},
LocalWireguardOpts,
};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
Expand All @@ -32,8 +34,6 @@ pub struct ExitGatewayConfig {
pub network_requester: NetworkRequester,

pub ip_packet_router: IpPacketRouter,

pub authenticator: Authenticator,
}

impl ExitGatewayConfig {
Expand All @@ -49,7 +49,6 @@ impl ExitGatewayConfig {
.expect("invalid default exit policy URL"),
network_requester: Default::default(),
ip_packet_router: Default::default(),
authenticator: Default::default(),
}
}
}
Expand Down Expand Up @@ -139,25 +138,6 @@ impl Default for IpPacketRouterDebug {
}
}

pub struct EphemeralConfig {
pub gateway: nym_gateway::config::Config,
pub nr_opts: LocalNetworkRequesterOpts,
pub ipr_opts: LocalIpPacketRouterOpts,
pub auth_opts: LocalAuthenticatorOpts,
pub wg_opts: LocalWireguardOpts,
}

fn base_client_config(config: &Config) -> nym_client_core_config_types::Client {
nym_client_core_config_types::Client {
version: format!("{}-nym-node", crate_version!()),
id: config.id.clone(),
// irrelevant field - no need for credentials in embedded mode
disabled_credentials_mode: true,
nyxd_urls: config.mixnet.nyxd_urls.clone(),
nym_api_urls: config.mixnet.nym_api_urls.clone(),
}
}

// that function is rather disgusting, but I hope it's not going to live for too long
pub fn ephemeral_exit_gateway_config(
config: Config,
Expand Down Expand Up @@ -244,7 +224,7 @@ pub fn ephemeral_exit_gateway_config(
config: nym_authenticator::Config {
base: nym_client_core_config_types::Config {
client: base_client_config(&config),
debug: config.exit_gateway.authenticator.debug.client_debug,
debug: config.authenticator.debug.client_debug,
},
authenticator: config.wireguard.clone().into(),
storage_paths: nym_authenticator::config::AuthenticatorPaths {
Expand All @@ -253,7 +233,6 @@ pub fn ephemeral_exit_gateway_config(
.storage_paths
.authenticator
.to_common_client_paths(),
authenticator_description: Default::default(),
},
logging: config.logging,
},
Expand Down Expand Up @@ -290,8 +269,8 @@ pub fn ephemeral_exit_gateway_config(
gateway.storage_paths.keys.public_identity_key_file = pub_id_path;

Ok(EphemeralConfig {
nr_opts,
ipr_opts,
nr_opts: Some(nr_opts),
ipr_opts: Some(ipr_opts),
auth_opts,
wg_opts,
gateway,
Expand Down
24 changes: 24 additions & 0 deletions nym-node/src/config/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@

use crate::config::Config;
use clap::crate_version;
use nym_gateway::node::{
LocalAuthenticatorOpts, LocalIpPacketRouterOpts, LocalNetworkRequesterOpts,
};
use std::net::IpAddr;
use thiserror::Error;

use super::LocalWireguardOpts;

#[derive(Debug, Error)]
#[error("currently it's not supported to have different ip addresses for clients and mixnet ({clients_bind_ip} and {mix_bind_ip} were used)")]
pub struct UnsupportedGatewayAddresses {
Expand Down Expand Up @@ -80,3 +85,22 @@ pub fn ephemeral_gateway_config(
},
))
}

pub fn base_client_config(config: &Config) -> nym_client_core_config_types::Client {
nym_client_core_config_types::Client {
version: format!("{}-nym-node", crate_version!()),
id: config.id.clone(),
// irrelevant field - no need for credentials in embedded mode
disabled_credentials_mode: true,
nyxd_urls: config.mixnet.nyxd_urls.clone(),
nym_api_urls: config.mixnet.nym_api_urls.clone(),
}
}

pub struct EphemeralConfig {
pub gateway: nym_gateway::config::Config,
pub nr_opts: Option<LocalNetworkRequesterOpts>,
pub ipr_opts: Option<LocalIpPacketRouterOpts>,
pub auth_opts: LocalAuthenticatorOpts,
pub wg_opts: LocalWireguardOpts,
}
Loading