Compare commits

...

15 Commits

Author SHA1 Message Date
Bogdan-Ștefan Neacşu 697d55248d Simplify pub key translatations 2024-05-23 13:31:28 +00:00
Bogdan-Ștefan Neacşu 570cc36385 Merge remote-tracking branch 'origin/feature/refine_wg_config' into bogdan/testing 2024-05-23 13:24:06 +00:00
Bogdan-Ștefan Neacşu ee64762b87 Init wireguard on migration 2024-05-20 14:32:30 +00:00
Bogdan-Ștefan Neacşu f4528bb521 Remove upgrade code 2024-05-20 11:25:32 +00:00
Bogdan-Ștefan Neacşu f4630e0b8a Bump gateway version number 2024-05-20 10:59:56 +00:00
Bogdan-Ștefan Neacşu 65f948d012 Remove logs 2024-05-20 10:26:13 +00:00
Bogdan-Ștefan Neacşu d16a288b6d Propagate wireguard setup error message 2024-05-20 10:06:55 +00:00
Bogdan-Ștefan Neacşu 72c40d8576 Rename network to ip for wg gw 2024-05-20 09:48:06 +00:00
Bogdan-Ștefan Neacşu 34e1709b75 Generate and use own private key 2024-05-20 09:05:07 +00:00
Bogdan-Ștefan Neacşu 257df97e3a Use client reg 2024-05-17 12:48:46 +00:00
Bogdan-Ștefan Neacşu 870570d5c3 Move key paths to separate structure 2024-05-17 11:33:30 +00:00
Bogdan-Ștefan Neacşu 0000baa343 Activate wg feature in gw dep 2024-05-17 11:33:30 +00:00
Bogdan-Ștefan Neacşu 6a307d59b4 Create wg keypair 2024-05-17 11:33:30 +00:00
Bogdan-Ștefan Neacşu a4808635f9 Support nym node first 2024-05-17 11:33:30 +00:00
Bogdan-Ștefan Neacşu 29965782a2 Include wireguard in gw config 2024-05-17 11:33:30 +00:00
31 changed files with 339 additions and 267 deletions
Generated
+3 -1
View File
@@ -4576,7 +4576,7 @@ dependencies = [
[[package]]
name = "nym-gateway"
version = "1.1.36"
version = "1.1.37"
dependencies = [
"anyhow",
"async-trait",
@@ -5843,7 +5843,9 @@ dependencies = [
"dashmap",
"hmac 0.12.1",
"log",
"nym-config",
"nym-crypto",
"nym-network-defaults",
"rand 0.7.3",
"serde",
"serde_json",
+22
View File
@@ -171,3 +171,25 @@ impl fmt::Display for GatewayIpPacketRouterDetails {
writeln!(f, "\taddress: {}", self.address)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GatewayWireguardDetails {
pub enabled: bool,
pub announced_port: u16,
pub private_network_prefix: u8,
}
impl fmt::Display for GatewayWireguardDetails {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "wireguard:")?;
writeln!(f, "\tenabled: {}", self.enabled)?;
writeln!(f, "\tannounced_port: {}", self.announced_port)?;
writeln!(
f,
"\tprivate_network_prefix: {}",
self.private_network_prefix
)
}
}
+2
View File
@@ -17,7 +17,9 @@ log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
nym-config = { path = "../config" }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-network-defaults = { path = "../network-defaults" }
# feature-specific dependencies:
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::net::{IpAddr, SocketAddr};
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct Config {
/// Socket address this node will use for binding its wireguard interface.
/// default: `0.0.0.0:51822`
pub bind_address: SocketAddr,
/// Private IP address of the wireguard gateway.
/// default: `10.1.0.1`
pub private_ip: IpAddr,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
pub announced_port: u16,
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard.
/// The maximum value for IPv4 is 32 and for IPv6 is 128
pub private_network_prefix: u8,
}
+37 -1
View File
@@ -1,15 +1,51 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use dashmap::DashMap;
use nym_crypto::asymmetric::encryption::KeyPair;
use std::sync::Arc;
pub mod config;
pub mod error;
pub mod public_key;
pub mod registration;
pub use config::Config;
pub use error::Error;
pub use public_key::PeerPublicKey;
pub use registration::{
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce,
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, GatewayClientRegistry,
InitMessage, Nonce,
};
#[cfg(feature = "verify")]
pub use registration::HmacSha256;
#[derive(Clone)]
pub struct WireguardGatewayData {
config: Config,
keypair: Arc<KeyPair>,
client_registry: Arc<GatewayClientRegistry>,
}
impl WireguardGatewayData {
pub fn new(config: Config, keypair: Arc<KeyPair>) -> Self {
WireguardGatewayData {
config,
keypair,
client_registry: Arc::new(DashMap::default()),
}
}
pub fn config(&self) -> Config {
self.config
}
pub fn keypair(&self) -> &Arc<KeyPair> {
&self.keypair
}
pub fn client_registry(&self) -> &Arc<GatewayClientRegistry> {
&self.client_registry
}
}
+4
View File
@@ -24,6 +24,10 @@ impl PeerPublicKey {
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn inner(&self) -> PublicKey {
self.0
}
}
impl fmt::Display for PeerPublicKey {
+2 -4
View File
@@ -12,7 +12,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")]
use hmac::{Hmac, Mac};
#[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
use nym_crypto::asymmetric::encryption::PrivateKey;
#[cfg(feature = "verify")]
use sha2::Sha256;
@@ -87,7 +87,7 @@ impl GatewayClient {
#[cfg(feature = "verify")]
pub fn new(
local_secret: &PrivateKey,
remote_public: PublicKey,
remote_public: x25519_dalek::PublicKey,
private_ip: IpAddr,
nonce: u64,
) -> Self {
@@ -96,8 +96,6 @@ impl GatewayClient {
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let remote_public = x25519_dalek::PublicKey::from(remote_public.to_bytes());
let dh = static_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead
+15 -18
View File
@@ -3,40 +3,37 @@
// #![warn(clippy::expect_used)]
// #![warn(clippy::unwrap_used)]
pub mod setup;
/// Start wireguard device
#[cfg(target_os = "linux")]
pub async fn start_wireguard(
mut task_client: nym_task::TaskClient,
_gateway_client_registry: std::sync::Arc<
nym_wireguard_types::registration::GatewayClientRegistry,
>,
wireguard_data: std::sync::Arc<nym_wireguard_types::WireguardGatewayData>,
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
use crate::setup::{peer_allowed_ips, peer_static_public_key, PRIVATE_KEY};
use base64::{prelude::BASE64_STANDARD, Engine};
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
let mut peers = vec![];
for peer_client in wireguard_data.client_registry().iter() {
let mut peer = Peer::new(Key::new(peer_client.pub_key.to_bytes()));
let peer_ip_mask = IpAddrMask::new(peer_client.private_ip, 32);
peer.set_allowed_ips(vec![peer_ip_mask]);
peers.push(peer);
}
let ifname = String::from("wg0");
let wgapi = WGApi::new(ifname.clone(), false)?;
wgapi.create_interface()?;
let interface_config = InterfaceConfiguration {
name: ifname.clone(),
prvkey: PRIVATE_KEY.to_string(),
address: WG_TUN_DEVICE_ADDRESS.to_string(),
port: WG_PORT as u32,
peers: vec![],
prvkey: BASE64_STANDARD.encode(wireguard_data.keypair().private_key().to_bytes()),
address: wireguard_data.config().private_ip.to_string(),
port: wireguard_data.config().announced_port as u32,
peers,
};
wgapi.configure_interface(&interface_config)?;
let peer = peer_static_public_key();
let mut peer = Peer::new(Key::new(peer.to_bytes()));
let peer_ip = peer_allowed_ips();
let peer_ip_mask = IpAddrMask::new(peer_ip.network_address(), peer_ip.netmask());
peer.set_allowed_ips(vec![peer_ip_mask]);
wgapi.configure_peer(&peer)?;
wgapi.configure_peer_routing(&[peer.clone()])?;
// wgapi.configure_peer_routing(&peers)?;
tokio::spawn(async move { task_client.recv().await });
-56
View File
@@ -1,56 +0,0 @@
use std::net::IpAddr;
use base64::{engine::general_purpose, Engine as _};
use log::info;
// The wireguard UDP listener
pub const WG_ADDRESS: &str = "0.0.0.0";
// The private key of the listener
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
pub(crate) const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
// peer has configured on their side.
const ALLOWED_IPS: &str = "10.1.0.2";
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
general_purpose::STANDARD
.decode(base64_key)
.unwrap()
.try_into()
.unwrap()
}
pub fn server_static_private_key() -> x25519_dalek::StaticSecret {
// TODO: this is a temporary solution for development
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
let static_private = x25519_dalek::StaticSecret::from(static_private_bytes);
let static_public = x25519_dalek::PublicKey::from(&static_private);
info!(
"wg public key: {}",
general_purpose::STANDARD.encode(static_public)
);
static_private
}
pub fn peer_static_public_key() -> x25519_dalek::PublicKey {
// A single static public key is used during development
// Read from NYM_PEER_PUBLIC_KEY env variable
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
let peer_static_public_bytes: [u8; 32] = decode_base64_key(&peer);
let peer_static_public = x25519_dalek::PublicKey::from(peer_static_public_bytes);
info!(
"Adding wg peer public key: {}",
general_purpose::STANDARD.encode(peer_static_public)
);
peer_static_public
}
pub fn peer_allowed_ips() -> ip_network::IpNetwork {
let key: IpAddr = ALLOWED_IPS.parse().unwrap();
let cidr = 32u8;
ip_network::IpNetwork::new_truncate(key, cidr).unwrap()
}
+2 -2
View File
@@ -148,8 +148,8 @@ Options:
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-network-ip <WIREGUARD_PRIVATE_NETWORK_IP>
Ip address of the private wireguard network. default: `10.1.0.0` [env: NYMNODE_WG_IP_NETWORK=]
--wireguard-private-gw-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
+1 -1
View File
@@ -4,7 +4,7 @@
[package]
name = "nym-gateway"
license = "GPL-3.0"
version = "1.1.36"
version = "1.1.37"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+2 -2
View File
@@ -84,13 +84,13 @@ fn try_upgrade_v1_1_29_config(id: &str) -> Result<bool, GatewayError> {
}
fn try_upgrade_v1_1_31_config(id: &str) -> Result<bool, GatewayError> {
// explicitly load it as v1.1.30 (which is incompatible with the current, i.e. 1.1.31+)
// explicitly load it as v1.1.35 (which is incompatible with the current, i.e. 1.1.36+)
let Ok(old_config) = ConfigV1_1_31::read_from_default_path(id) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the gateway is using <= v1.1.30 config template.");
info!("It seems the gateway is using <= v1.1.35 config template.");
info!("It is going to get updated to the current specification.");
let updated: Config = old_config.into();
+2 -45
View File
@@ -11,7 +11,7 @@ use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT};
use serde::{Deserialize, Serialize};
use std::io;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
@@ -20,7 +20,7 @@ use std::time::Duration;
use url::Url;
use zeroize::{Zeroize, ZeroizeOnDrop};
pub use crate::config::persistence::paths::{GatewayPaths, WireguardPaths};
pub use crate::config::persistence::paths::GatewayPaths;
pub mod old_config_v1_1_20;
pub mod old_config_v1_1_28;
@@ -85,10 +85,6 @@ pub struct Config {
pub gateway: Gateway,
// currently not really used for anything useful
#[serde(default)]
pub wireguard: Wireguard,
pub storage_paths: GatewayPaths,
pub network_requester: NetworkRequester,
@@ -121,7 +117,6 @@ impl Config {
},
http: Default::default(),
gateway: default_gateway,
wireguard: Default::default(),
storage_paths: GatewayPaths::new_default(id.as_ref()),
network_requester: Default::default(),
ip_packet_router: Default::default(),
@@ -135,7 +130,6 @@ impl Config {
host: impl Into<Host>,
http: impl Into<Http>,
gateway: impl Into<Gateway>,
wireguard: impl Into<Wireguard>,
storage_paths: impl Into<GatewayPaths>,
network_requester: impl Into<NetworkRequester>,
ip_packet_router: impl Into<IpPacketRouter>,
@@ -147,7 +141,6 @@ impl Config {
host: host.into(),
http: http.into(),
gateway: gateway.into(),
wireguard: wireguard.into(),
storage_paths: storage_paths.into(),
network_requester: network_requester.into(),
ip_packet_router: ip_packet_router.into(),
@@ -262,8 +255,6 @@ impl Config {
let http_port = self.http.bind_address.port();
self.http.bind_address = SocketAddr::new(listening_address, http_port);
let wg_port = self.wireguard.bind_address.port();
self.wireguard.bind_address = SocketAddr::new(listening_address, wg_port);
self
}
@@ -347,40 +338,6 @@ impl Default for Http {
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Wireguard {
/// Specifies whether the wireguard service is enabled on this node.
pub enabled: bool,
/// Socket address this node will use for binding its wireguard interface.
/// default: `0.0.0.0:51822`
pub bind_address: SocketAddr,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
pub announced_port: u16,
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard.
/// The maximum value for IPv4 is 32 and for IPv6 is 128
pub private_network_prefix: u8,
/// Paths for wireguard keys, client registries, etc.
pub storage_paths: WireguardPaths,
}
impl Default for Wireguard {
fn default() -> Self {
Wireguard {
enabled: false,
bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT),
announced_port: WG_PORT,
private_network_prefix: 16,
storage_paths: WireguardPaths {},
}
}
}
// we only really care about the mnemonic being zeroized
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)]
pub struct Gateway {
+3 -13
View File
@@ -1,8 +1,6 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::persistence::paths::{GatewayPaths, WireguardPaths};
use nym_bin_common::logging::LoggingSettings;
use nym_config::{
must_get_home, read_config_from_toml_file, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR,
};
@@ -14,8 +12,9 @@ use std::path::{Path, PathBuf};
use std::time::Duration;
use url::Url;
use super::persistence::paths::KeysPaths;
use super::{Config, Debug, Gateway, Host, Http, NetworkRequester, Wireguard};
use super::{Host, Http};
use crate::config::persistence::paths::KeysPaths;
use crate::config::{Config, Debug, Gateway, GatewayPaths, LoggingSettings, NetworkRequester};
const DEFAULT_GATEWAYS_DIR: &str = "gateways";
@@ -125,15 +124,6 @@ impl From<ConfigV1_1_31> for Config {
nyxd_urls: value.gateway.nyxd_urls,
cosmos_mnemonic: value.gateway.cosmos_mnemonic,
},
wireguard: Wireguard {
enabled: value.wireguard.enabled,
bind_address: value.wireguard.bind_address,
announced_port: value.wireguard.announced_port,
private_network_prefix: Default::default(),
storage_paths: WireguardPaths {
// no fields (yet)
},
},
storage_paths: GatewayPaths {
keys: KeysPaths {
private_identity_key_file: value.storage_paths.keys.private_identity_key_file,
-12
View File
@@ -169,15 +169,3 @@ impl KeysPaths {
&self.public_sphinx_key_file
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WireguardPaths {
// pub keys:
}
impl WireguardPaths {
pub fn new_empty() -> Self {
WireguardPaths {}
}
}
+22
View File
@@ -63,6 +63,17 @@ pub enum GatewayError {
source: io::Error,
},
#[error(
"failed to load config file for wireguard (gateway-id: '{id}') using path '{}'. detailed message: {source}",
path.display()
)]
WireguardConfigLoadFailure {
id: String,
path: PathBuf,
#[source]
source: io::Error,
},
#[error(
"failed to save config file for id {id} using path '{}'. detailed message: {source}", path.display()
)]
@@ -167,6 +178,17 @@ pub enum GatewayError {
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("failed to remove wireguard interface: {0}")]
WireguardInterfaceError(#[from] defguard_wireguard_rs::error::WireguardInterfaceError),
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("wireguard not set")]
WireguardNotSet,
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("failed to catch an interrupt: {source}")]
StdError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
}
impl From<ClientCoreError> for GatewayError {
+8 -34
View File
@@ -4,7 +4,6 @@
use crate::config::Config;
use crate::error::GatewayError;
use crate::helpers::load_public_key;
use ipnetwork::IpNetwork;
use log::{debug, error, warn};
use nym_bin_common::bin_info_owned;
use nym_crypto::asymmetric::{encryption, identity};
@@ -12,30 +11,19 @@ use nym_network_requester::RequestFilter;
use nym_node_http_api::api::api_requests;
use nym_node_http_api::api::api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy;
use nym_node_http_api::api::api_requests::SignedHostInformation;
use nym_node_http_api::router::WireguardAppState;
use nym_node_http_api::NymNodeHttpError;
use nym_sphinx::addressing::clients::Recipient;
use nym_task::TaskClient;
use nym_wireguard_types::registration::GatewayClientRegistry;
use std::net::{IpAddr, Ipv4Addr};
use nym_wireguard_types::WireguardGatewayData;
use std::sync::Arc;
fn load_gateway_details(
config: &Config,
) -> Result<api_requests::v1::gateway::models::Gateway, GatewayError> {
let wireguard = if config.wireguard.enabled {
Some(api_requests::v1::gateway::models::Wireguard {
port: config.wireguard.announced_port,
public_key: "placeholder key value".to_string(),
})
} else {
None
};
Ok(api_requests::v1::gateway::models::Gateway {
enforces_zk_nyms: config.gateway.only_coconut_credentials,
client_interfaces: api_requests::v1::gateway::models::ClientInterfaces {
wireguard,
wireguard: None,
mixnet_websockets: Some(api_requests::v1::gateway::models::WebSockets {
ws_port: config.gateway.clients_port,
wss_port: config.gateway.clients_wss_port,
@@ -154,7 +142,7 @@ pub(crate) struct HttpApiBuilder<'a> {
// TODO: this should be a wg specific key and not re-used sphinx
sphinx_keypair: Arc<encryption::KeyPair>,
client_registry: Option<Arc<GatewayClientRegistry>>,
wireguard_data: Option<Arc<WireguardGatewayData>>,
}
impl<'a> HttpApiBuilder<'a> {
@@ -170,7 +158,7 @@ impl<'a> HttpApiBuilder<'a> {
exit_policy: None,
identity_keypair,
sphinx_keypair,
client_registry: None,
wireguard_data: None,
}
}
@@ -235,11 +223,11 @@ impl<'a> HttpApiBuilder<'a> {
}
#[must_use]
pub(crate) fn with_wireguard_client_registry(
pub(crate) fn with_wireguard_data(
mut self,
client_registry: Arc<GatewayClientRegistry>,
wireguard_data: Option<Arc<WireguardGatewayData>>,
) -> Self {
self.client_registry = Some(client_registry);
self.wireguard_data = wireguard_data;
self
}
@@ -281,22 +269,8 @@ impl<'a> HttpApiBuilder<'a> {
)?);
}
let wireguard_private_network = IpNetwork::new(
IpAddr::from(Ipv4Addr::new(10, 1, 0, 0)),
self.gateway_config.wireguard.private_network_prefix,
)?;
let wg_state = self.client_registry.and_then(|client_registry| {
WireguardAppState::new(
client_registry,
Default::default(),
self.gateway_config.wireguard.bind_address.port(),
wireguard_private_network,
)
.ok()
});
let bind_address = self.gateway_config.http.bind_address;
let router = nym_node_http_api::NymNodeRouter::new(config, None, wg_state);
let router = nym_node_http_api::NymNodeRouter::new(config, None, None);
tokio::spawn(async move {
let server = match router.build_server(&bind_address).await {
+23 -15
View File
@@ -16,7 +16,6 @@ use crate::node::client_handling::websocket::connection_handler::coconut::Coconu
use crate::node::helpers::{initialise_main_storage, load_network_requester_config};
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::statistics::collector::GatewayStatisticsCollector;
use dashmap::DashMap;
use futures::channel::{mpsc, oneshot};
use log::*;
use nym_crypto::asymmetric::{encryption, identity};
@@ -28,7 +27,7 @@ use nym_task::{TaskClient, TaskHandle, TaskManager};
use nym_types::gateway::GatewayNodeDetailsResponse;
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
use nym_wireguard_types::registration::GatewayClientRegistry;
use nym_wireguard_types::WireguardGatewayData;
use rand::seq::SliceRandom;
use rand::thread_rng;
use std::net::SocketAddr;
@@ -126,9 +125,10 @@ pub struct Gateway<St = PersistentStorage> {
/// x25519 keypair used for Diffie-Hellman. Currently only used for sphinx key derivation.
sphinx_keypair: Arc<encryption::KeyPair>,
storage: St,
client_registry: Arc<GatewayClientRegistry>,
wireguard_data: Option<Arc<WireguardGatewayData>>,
run_http_server: bool,
task_client: Option<TaskClient>,
@@ -149,7 +149,7 @@ impl<St> Gateway<St> {
config,
network_requester_opts,
ip_packet_router_opts,
client_registry: Arc::new(DashMap::new()),
wireguard_data: None,
run_http_server: true,
task_client: None,
})
@@ -170,7 +170,7 @@ impl<St> Gateway<St> {
identity_keypair,
sphinx_keypair,
storage,
client_registry: Arc::new(DashMap::new()),
wireguard_data: None,
run_http_server: true,
task_client: None,
}
@@ -184,12 +184,14 @@ impl<St> Gateway<St> {
self.task_client = Some(task_client)
}
pub fn set_wireguard_client_registry(&mut self, client_registry: Arc<GatewayClientRegistry>) {
pub fn set_wireguard_data(&mut self, wireguard_data: Arc<WireguardGatewayData>) {
// sanity check:
if Arc::strong_count(&self.client_registry) != 1 {
panic!("the client registry is already being used elsewhere")
if let Some(wg_data) = self.wireguard_data.as_ref() {
if Arc::strong_count(wg_data) != 1 {
panic!("the client registry is already being used elsewhere")
}
}
self.client_registry = client_registry
self.wireguard_data = Some(wireguard_data)
}
pub async fn node_details(&self) -> Result<GatewayNodeDetailsResponse, GatewayError> {
@@ -230,7 +232,11 @@ impl<St> Gateway<St> {
&self,
shutdown: TaskClient,
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync>> {
nym_wireguard::start_wireguard(shutdown, Arc::clone(&self.client_registry)).await
if let Some(wireguard_data) = self.wireguard_data.as_ref() {
nym_wireguard::start_wireguard(shutdown, Arc::clone(wireguard_data)).await
} else {
Err(Box::new(GatewayError::WireguardNotSet))
}
}
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
@@ -555,7 +561,7 @@ impl<St> Gateway<St> {
self.identity_keypair.as_ref(),
self.sphinx_keypair.clone(),
)
.with_wireguard_client_registry(self.client_registry.clone())
.with_wireguard_data(self.wireguard_data.clone())
.with_maybe_network_requester(self.network_requester_opts.as_ref().map(|o| &o.config))
.with_maybe_network_request_filter(nr_request_filter)
.with_maybe_ip_packet_router(self.ip_packet_router_opts.as_ref().map(|o| &o.config))
@@ -565,7 +571,10 @@ impl<St> Gateway<St> {
// Once this is a bit more mature, make this a commandline flag instead of a compile time
// flag
#[cfg(all(feature = "wireguard", target_os = "linux"))]
let wg_api = self.start_wireguard(shutdown.fork("wireguard")).await.ok();
let wg_api = self
.start_wireguard(shutdown.fork("wireguard"))
.await
.map_err(|source| GatewayError::StdError { source })?;
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
self.start_wireguard(shutdown.fork("wireguard")).await;
@@ -577,9 +586,8 @@ impl<St> Gateway<St> {
return Err(GatewayError::ShutdownFailure { source });
}
#[cfg(all(feature = "wireguard", target_os = "linux"))]
if let Some(wg_api) = wg_api {
defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&wg_api)?;
}
defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&wg_api)?;
Ok(())
}
}
+3
View File
@@ -60,3 +60,6 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
[build-dependencies]
# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions)
cargo_metadata = "0.18.1"
[features]
wireguard = ["nym-gateway/wireguard"]
@@ -10,7 +10,6 @@ use crate::router::types::RequestError;
use axum::extract::{Path, Query, State};
use axum::http::StatusCode;
use axum::Json;
use nym_crypto::asymmetric::encryption::PublicKey;
use nym_node_requests::api::v1::gateway::client_interfaces::wireguard::models::{
ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce, PeerPublicKey,
};
@@ -31,7 +30,10 @@ async fn process_final_message(
}
};
if client.verify(&state.private_key, preshared_nonce).is_ok() {
if client
.verify(&state.keypair.private_key(), preshared_nonce)
.is_ok()
{
state.registration_in_progress.remove(&client.pub_key());
state.client_registry.insert(client.pub_key(), client);
@@ -86,8 +88,7 @@ pub(crate) async fn register_client(
match payload {
ClientMessage::Initial(init) => {
let remote_public = PublicKey::from_bytes(init.pub_key().as_bytes())
.map_err(|_| RequestError::new_status(StatusCode::BAD_REQUEST))?;
let remote_public = init.pub_key().inner();
let nonce = process_init_message(init, state).await;
let mut private_ip_ref = state
.free_private_network_ips
@@ -101,7 +102,7 @@ pub(crate) async fn register_client(
// mark it as used, even though it's not final
*private_ip_ref = false;
let gateway_data = GatewayClient::new(
&state.private_key,
&state.keypair.private_key(),
remote_public,
*private_ip_ref.key(),
nonce,
@@ -8,11 +8,11 @@ use crate::error::NymNodeHttpError;
use axum::routing::{get, post};
use axum::Router;
use ipnetwork::IpNetwork;
use nym_crypto::asymmetric::encryption::PrivateKey;
use nym_crypto::asymmetric::x25519::KeyPair;
use nym_node_requests::routes::api::v1::gateway::client_interfaces::wireguard;
use nym_wireguard::setup;
use nym_wireguard_types::registration::PrivateIPs;
use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations};
use nym_wireguard_types::WireguardGatewayData;
use std::sync::Arc;
pub(crate) mod client_registry;
@@ -27,17 +27,15 @@ pub struct WireguardAppState {
impl WireguardAppState {
pub fn new(
client_registry: Arc<GatewayClientRegistry>,
wireguard_gateway_data: &WireguardGatewayData,
registration_in_progress: Arc<PendingRegistrations>,
binding_port: u16,
private_ip_network: IpNetwork,
) -> Result<Self, NymNodeHttpError> {
Ok(WireguardAppState {
inner: Some(WireguardAppStateInner {
private_key: Arc::new(PrivateKey::from_bytes(
setup::server_static_private_key().as_ref(),
)?),
client_registry,
keypair: wireguard_gateway_data.keypair().clone(),
client_registry: wireguard_gateway_data.client_registry().clone(),
registration_in_progress,
binding_port,
free_private_network_ips: Arc::new(
@@ -83,7 +81,7 @@ macro_rules! get_state {
#[derive(Clone)]
pub(crate) struct WireguardAppStateInner {
private_key: Arc<PrivateKey>,
keypair: Arc<KeyPair>,
client_registry: Arc<GatewayClientRegistry>,
registration_in_progress: Arc<PendingRegistrations>,
binding_port: u16,
@@ -168,7 +166,7 @@ mod test {
let state = WireguardAppState {
inner: Some(WireguardAppStateInner {
client_registry: Arc::clone(&client_registry),
private_key: Arc::new(gateway_private_key),
keypair: Arc::new(gateway_private_key),
registration_in_progress: Arc::clone(&registration_in_progress),
binding_port: 8080,
free_private_network_ips,
+3 -10
View File
@@ -18,8 +18,8 @@ use nym_mixnode::MixnodeError;
use nym_network_requester::{CustomGatewayDetails, GatewayDetails};
use nym_node::config;
use nym_node::config::mixnode::DEFAULT_VERLOC_PORT;
use nym_node::config::Config;
use nym_node::config::{default_config_filepath, ConfigBuilder, NodeMode};
use nym_node::config::{Config, DEFAULT_WIREGUARD_NETWORK_IP};
use nym_node::error::{EntryGatewayError, ExitGatewayError, NymNodeError};
use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription;
use rand::rngs::OsRng;
@@ -400,15 +400,6 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
},
..config::MixnodeConfig::new_default()
}))
.with_wireguard(args.wireguard.override_config_section(config::Wireguard {
enabled: cfg.wireguard.enabled,
bind_address: cfg.wireguard.bind_address,
private_network_ip: DEFAULT_WIREGUARD_NETWORK_IP,
announced_port: cfg.wireguard.announced_port,
private_network_prefix: cfg.wireguard.private_network_prefix,
// this is fine as currently the paths stored inside gateway itself are empty
storage_paths: config::persistence::WireguardPaths::new(&data_dir),
}))
.with_entry_gateway(args.entry_gateway.override_config_section(
config::EntryGatewayConfig {
storage_paths: config::persistence::EntryGatewayPaths::new(&data_dir),
@@ -606,6 +597,8 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
.await?;
}
crate::node::WireguardData::initialise(&config.wireguard)?;
save_node_description(
&config.storage_paths.description,
&NodeDescription::default(),
+6 -6
View File
@@ -253,13 +253,13 @@ pub(crate) struct WireguardArgs {
)]
pub(crate) wireguard_bind_address: Option<SocketAddr>,
/// Ip address of the private wireguard network.
/// default: `10.1.0.0`
/// Private IP address of the wireguard gateway.
/// default: `10.1.0.1`
#[clap(
long,
env = NYMNODE_WG_IP_NETWORK_ARG,
env = NYMNODE_WG_IP_ARG,
)]
pub(crate) wireguard_private_network_ip: Option<IpAddr>,
pub(crate) wireguard_private_ip: Option<IpAddr>,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
@@ -300,8 +300,8 @@ impl WireguardArgs {
section.announced_port = announced_port
}
if let Some(private_network_ip) = self.wireguard_private_network_ip {
section.private_network_ip = private_network_ip
if let Some(private_ip) = self.wireguard_private_ip {
section.private_ip = private_ip
}
if let Some(private_network_prefix) = self.wireguard_private_network_prefix {
+16
View File
@@ -13,6 +13,8 @@ use serde::{Deserialize, Serialize};
use std::path::Path;
use url::Url;
use super::LocalWireguardOpts;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ExitGatewayConfig {
@@ -136,6 +138,7 @@ pub struct EphemeralConfig {
pub gateway: nym_gateway::config::Config,
pub nr_opts: LocalNetworkRequesterOpts,
pub ipr_opts: LocalIpPacketRouterOpts,
pub wg_opts: LocalWireguardOpts,
}
fn base_client_config(config: &Config) -> nym_client_core_config_types::Client {
@@ -241,6 +244,18 @@ pub fn ephemeral_exit_gateway_config(
let ipr_enabled = config.exit_gateway.ip_packet_router.debug.enabled;
let nr_enabled = config.exit_gateway.network_requester.debug.enabled;
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 mut gateway = ephemeral_gateway_config(config, mnemonic)?;
gateway.ip_packet_router.enabled = ipr_enabled;
gateway.network_requester.enabled = nr_enabled;
@@ -253,6 +268,7 @@ pub fn ephemeral_exit_gateway_config(
Ok(EphemeralConfig {
nr_opts,
ipr_opts,
wg_opts,
gateway,
})
}
-9
View File
@@ -57,19 +57,10 @@ pub fn ephemeral_gateway_config(
cosmos_mnemonic: mnemonic.clone(),
};
let wireguard = nym_gateway::config::Wireguard {
enabled: config.wireguard.enabled,
bind_address: config.wireguard.bind_address,
announced_port: config.wireguard.announced_port,
private_network_prefix: config.wireguard.private_network_prefix,
storage_paths: nym_gateway::config::WireguardPaths::new_empty(),
};
Ok(nym_gateway::config::Config::externally_loaded(
host,
http,
gateway,
wireguard,
nym_gateway::config::GatewayPaths::new_empty(),
nym_gateway::config::NetworkRequester { enabled: false },
nym_gateway::config::IpPacketRouter { enabled: false },
+23 -5
View File
@@ -40,7 +40,7 @@ pub use crate::config::mixnode::MixnodeConfig;
const DEFAULT_NYMNODES_DIR: &str = "nym-nodes";
pub const DEFAULT_WIREGUARD_PORT: u16 = WG_PORT;
pub const DEFAULT_WIREGUARD_NETWORK_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 1, 0, 0));
pub const DEFAULT_WIREGUARD_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 1, 0, 1));
pub const DEFAULT_WIREGUARD_PREFIX: u8 = 16;
pub const DEFAULT_HTTP_PORT: u16 = DEFAULT_NYM_NODE_HTTP_PORT;
pub const DEFAULT_MIXNET_PORT: u16 = DEFAULT_MIX_LISTENING_PORT;
@@ -500,9 +500,9 @@ pub struct Wireguard {
/// default: `0.0.0.0:51822`
pub bind_address: SocketAddr,
/// Ip address of the private wireguard network.
/// default: `10.1.0.0`
pub private_network_ip: IpAddr,
/// Private IP address of the wireguard gateway.
/// default: `10.1.0.1`
pub private_ip: IpAddr,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
@@ -524,10 +524,28 @@ impl Wireguard {
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
DEFAULT_WIREGUARD_PORT,
),
private_network_ip: DEFAULT_WIREGUARD_NETWORK_IP,
private_ip: DEFAULT_WIREGUARD_IP,
announced_port: DEFAULT_WIREGUARD_PORT,
private_network_prefix: DEFAULT_WIREGUARD_PREFIX,
storage_paths: persistence::WireguardPaths::new(data_dir),
}
}
}
impl Into<nym_wireguard_types::Config> for Wireguard {
fn into(self) -> nym_wireguard_types::Config {
nym_wireguard_types::Config {
bind_address: self.bind_address,
private_ip: self.private_ip,
announced_port: self.announced_port,
private_network_prefix: self.private_network_prefix,
}
}
}
#[derive(Debug, Clone)]
pub struct LocalWireguardOpts {
pub config: Wireguard,
pub custom_mixnet_path: Option<PathBuf>,
}
+19 -3
View File
@@ -43,6 +43,10 @@ pub const DEFAULT_IPR_ACK_KEY_FILENAME: &str = "aes128ctr_ipr_ack";
pub const DEFAULT_IPR_REPLY_SURB_DB_FILENAME: &str = "ipr_persistent_reply_store.sqlite";
pub const DEFAULT_IPR_GATEWAYS_DB_FILENAME: &str = "ipr_gateways_info_store.sqlite";
// Wireguard
pub const DEFAULT_X25519_WG_DH_KEY_FILENAME: &str = "x25519_wg_dh";
pub const DEFAULT_X25519_WG_PUBLIC_DH_KEY_FILENAME: &str = "x25519_wg_dh.pub";
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct NymNodePaths {
@@ -366,11 +370,23 @@ impl ExitGatewayPaths {
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WireguardPaths {
// pub keys:
pub private_diffie_hellman_key_file: PathBuf,
pub public_diffie_hellman_key_file: PathBuf,
}
impl WireguardPaths {
pub fn new<P: AsRef<Path>>(_data_dir: P) -> Self {
WireguardPaths {}
pub fn new<P: AsRef<Path>>(data_dir: P) -> Self {
let data_dir = data_dir.as_ref();
WireguardPaths {
private_diffie_hellman_key_file: data_dir.join(DEFAULT_X25519_WG_DH_KEY_FILENAME),
public_diffie_hellman_key_file: data_dir.join(DEFAULT_X25519_WG_PUBLIC_DH_KEY_FILENAME),
}
}
pub fn x25519_wireguard_storage_paths(&self) -> nym_pemstore::KeyPairPath {
nym_pemstore::KeyPairPath::new(
&self.private_diffie_hellman_key_file,
&self.public_diffie_hellman_key_file,
)
}
}
+8 -5
View File
@@ -115,9 +115,9 @@ enabled = {{ wireguard.enabled }}
# default: `0.0.0.0:51822`
bind_address = '{{ wireguard.bind_address }}'
# Ip address of the private wireguard network.
# default: `10.1.0.0`
private_network_ip = '{{ wireguard.private_network_ip }}'
# Private IP address of the wireguard gateway.
# default: `10.1.0.1`
private_ip = '{{ wireguard.private_ip }}'
# Port announced to external clients wishing to connect to the wireguard interface.
# Useful in the instances where the node is behind a proxy.
@@ -127,9 +127,12 @@ announced_port = {{ wireguard.announced_port }}
# The maximum value for IPv4 is 32 and for IPv6 is 128
private_network_prefix = {{ wireguard.private_network_prefix }}
# Paths for wireguard keys, client registries, etc.
[wireguard.storage_paths]
# currently empty
# Path to file containing wireguard x25519 diffie hellman private key.
private_diffie_hellman_key_file = '{{ wireguard.storage_paths.private_diffie_hellman_key_file }}'
# Path to file containing wireguard x25519 diffie hellman public key.
public_diffie_hellman_key_file = '{{ wireguard.storage_paths.public_diffie_hellman_key_file }}'
##### mixnode mode nym-node config options #####
+1 -1
View File
@@ -40,7 +40,7 @@ pub mod vars {
// wireguard:
pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED";
pub const NYMNODE_WG_BIND_ADDRESS_ARG: &str = "NYMNODE_WG_BIND_ADDRESS";
pub const NYMNODE_WG_IP_NETWORK_ARG: &str = "NYMNODE_WG_IP_NETWORK";
pub const NYMNODE_WG_IP_ARG: &str = "NYMNODE_WG_IP";
pub const NYMNODE_WG_ANNOUNCED_PORT_ARG: &str = "NYMNODE_WG_ANNOUNCED_PORT";
pub const NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG: &str = "NYMNODE_WG_PRIVATE_NETWORK_PREFIX";
+7
View File
@@ -34,6 +34,7 @@ pub(crate) struct DisplayDetails {
pub(crate) ed25519_identity_key: String,
pub(crate) x25519_sphinx_key: String,
pub(crate) x25519_noise_key: String,
pub(crate) x25519_wireguard_key: String,
pub(crate) exit_network_requester_address: String,
pub(crate) exit_ip_packet_router_address: String,
@@ -139,6 +140,12 @@ pub(crate) fn load_x25519_noise_keypair(
Ok(load_keypair(paths, "x25519-noise")?)
}
pub(crate) fn load_x25519_wireguard_keypair(
paths: KeyPairPath,
) -> Result<x25519::KeyPair, NymNodeError> {
Ok(load_keypair(paths, "x25519-wireguard")?)
}
pub(crate) fn load_x25519_sphinx_public_key<P: AsRef<Path>>(
path: P,
) -> Result<x25519::PublicKey, NymNodeError> {
+69 -10
View File
@@ -20,7 +20,9 @@ use nym_network_requester::{
use nym_node::config::entry_gateway::ephemeral_entry_gateway_config;
use nym_node::config::exit_gateway::ephemeral_exit_gateway_config;
use nym_node::config::mixnode::ephemeral_mixnode_config;
use nym_node::config::{Config, EntryGatewayConfig, ExitGatewayConfig, MixnodeConfig, NodeMode};
use nym_node::config::{
Config, EntryGatewayConfig, ExitGatewayConfig, MixnodeConfig, NodeMode, Wireguard,
};
use nym_node::error::{EntryGatewayError, ExitGatewayError, MixnodeError, NymNodeError};
use nym_node_http_api::api::api_requests;
use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription;
@@ -31,7 +33,7 @@ use nym_node_http_api::{NymNodeHTTPServer, NymNodeRouter};
use nym_sphinx_acknowledgements::AckKey;
use nym_sphinx_addressing::Recipient;
use nym_task::{TaskClient, TaskManager};
use nym_wireguard_types::registration::GatewayClientRegistry;
use nym_wireguard_types::WireguardGatewayData;
use rand::rngs::OsRng;
use rand::{CryptoRng, RngCore};
use std::path::Path;
@@ -39,6 +41,8 @@ use std::sync::Arc;
use tracing::{debug, error, info, trace};
use zeroize::Zeroizing;
use self::helpers::load_x25519_wireguard_keypair;
pub mod bonding_information;
pub mod description;
pub mod helpers;
@@ -63,7 +67,7 @@ impl MixnodeData {
pub struct EntryGatewayData {
mnemonic: Zeroizing<bip39::Mnemonic>,
client_storage: nym_gateway::node::PersistentStorage,
client_registry: Arc<GatewayClientRegistry>,
wireguard_data: WireguardGatewayData,
}
impl EntryGatewayData {
@@ -81,7 +85,10 @@ impl EntryGatewayData {
Ok(())
}
async fn new(config: &EntryGatewayConfig) -> Result<EntryGatewayData, EntryGatewayError> {
async fn new(
config: &EntryGatewayConfig,
wireguard_data: WireguardGatewayData,
) -> Result<EntryGatewayData, EntryGatewayError> {
Ok(EntryGatewayData {
mnemonic: config.storage_paths.load_mnemonic_from_file()?,
client_storage: nym_gateway::node::PersistentStorage::init(
@@ -90,7 +97,7 @@ impl EntryGatewayData {
)
.await
.map_err(nym_gateway::GatewayError::from)?,
client_registry: Arc::new(Default::default()),
wireguard_data: wireguard_data.clone(),
})
}
}
@@ -244,6 +251,33 @@ impl ExitGatewayData {
}
}
pub struct WireguardData {
x25519_wireguard_keys: Arc<x25519::KeyPair>,
}
impl WireguardData {
pub(crate) fn new(config: &Wireguard) -> Result<Self, NymNodeError> {
Ok(WireguardData {
x25519_wireguard_keys: Arc::new(load_x25519_wireguard_keypair(
config.storage_paths.x25519_wireguard_storage_paths(),
)?),
})
}
pub(crate) fn initialise(config: &Wireguard) -> Result<(), ExitGatewayError> {
let mut rng = OsRng;
let x25519_keys = x25519::KeyPair::new(&mut rng);
store_keypair(
&x25519_keys,
config.storage_paths.x25519_wireguard_storage_paths(),
"wg-x25519-dh",
)?;
Ok(())
}
}
pub(crate) struct NymNode {
config: Config,
description: NodeDescription,
@@ -259,6 +293,8 @@ pub(crate) struct NymNode {
#[allow(dead_code)]
exit_gateway: ExitGatewayData,
wireguard: WireguardData,
ed25519_identity_keys: Arc<ed25519::KeyPair>,
x25519_sphinx_keys: Arc<x25519::KeyPair>,
@@ -314,10 +350,18 @@ impl NymNode {
ExitGatewayData::initialise(&config.exit_gateway, *ed25519_identity_keys.public_key())
.await?;
// wireguard initialisation
WireguardData::initialise(&config.wireguard)?;
config.save()
}
pub(crate) async fn new(config: Config) -> Result<Self, NymNodeError> {
let wireguard_data = WireguardData::new(&config.wireguard)?;
let wireguard_gateway_data = WireguardGatewayData::new(
config.wireguard.clone().into(),
wireguard_data.x25519_wireguard_keys.clone(),
);
Ok(NymNode {
ed25519_identity_keys: Arc::new(load_ed25519_identity_keypair(
config.storage_paths.keys.ed25519_identity_storage_paths(),
@@ -331,8 +375,10 @@ impl NymNode {
description: load_node_description(&config.storage_paths.description)?,
verloc_stats: Default::default(),
mixnode: MixnodeData::new(&config.mixnode)?,
entry_gateway: EntryGatewayData::new(&config.entry_gateway).await?,
entry_gateway: EntryGatewayData::new(&config.entry_gateway, wireguard_gateway_data)
.await?,
exit_gateway: ExitGatewayData::new(&config.exit_gateway)?,
wireguard: wireguard_data,
config,
})
}
@@ -353,6 +399,10 @@ impl NymNode {
)
}
fn x25519_wireguard_key(&self) -> &x25519::PublicKey {
self.wireguard.x25519_wireguard_keys.public_key()
}
pub(crate) fn display_details(&self) -> DisplayDetails {
DisplayDetails {
current_mode: self.config.mode,
@@ -360,6 +410,7 @@ impl NymNode {
ed25519_identity_key: self.ed25519_identity_key().to_base58_string(),
x25519_sphinx_key: self.x25519_sphinx_key().to_base58_string(),
x25519_noise_key: self.x25519_noise_key().to_base58_string(),
x25519_wireguard_key: self.x25519_wireguard_key().to_base58_string(),
exit_network_requester_address: self.exit_network_requester_address().to_string(),
exit_ip_packet_router_address: self.exit_ip_packet_router_address().to_string(),
}
@@ -409,6 +460,10 @@ impl NymNode {
let config =
ephemeral_entry_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?;
let wireguard_data = Arc::new(WireguardGatewayData::new(
self.config.wireguard.clone().into(),
self.wireguard.x25519_wireguard_keys.clone(),
));
let mut entry_gateway = Gateway::new_loaded(
config,
None,
@@ -419,7 +474,7 @@ impl NymNode {
);
entry_gateway.disable_http_server();
entry_gateway.set_task_client(task_client);
entry_gateway.set_wireguard_client_registry(self.entry_gateway.client_registry.clone());
entry_gateway.set_wireguard_data(wireguard_data);
tokio::spawn(async move {
if let Err(err) = entry_gateway.run().await {
@@ -434,6 +489,10 @@ impl NymNode {
let config =
ephemeral_exit_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?;
let wireguard_data = Arc::new(WireguardGatewayData::new(
self.config.wireguard.clone().into(),
self.wireguard.x25519_wireguard_keys.clone(),
));
let mut exit_gateway = Gateway::new_loaded(
config.gateway,
@@ -445,7 +504,7 @@ impl NymNode {
);
exit_gateway.disable_http_server();
exit_gateway.set_task_client(task_client);
exit_gateway.set_wireguard_client_registry(self.entry_gateway.client_registry.clone());
exit_gateway.set_wireguard_data(wireguard_data);
tokio::spawn(async move {
if let Err(err) = exit_gateway.run().await {
@@ -517,12 +576,12 @@ impl NymNode {
};
let wireguard_private_network = IpNetwork::new(
self.config.wireguard.private_network_ip,
self.config.wireguard.private_ip,
self.config.wireguard.private_network_prefix,
)?;
let wg_state = WireguardAppState::new(
self.entry_gateway.client_registry.clone(),
&self.entry_gateway.wireguard_data,
Default::default(),
self.config.wireguard.bind_address.port(),
wireguard_private_network,