Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 697d55248d | |||
| 570cc36385 | |||
| ee64762b87 | |||
| f4528bb521 | |||
| f4630e0b8a | |||
| 65f948d012 | |||
| d16a288b6d | |||
| 72c40d8576 | |||
| 34e1709b75 | |||
| 257df97e3a | |||
| 870570d5c3 | |||
| 0000baa343 | |||
| 6a307d59b4 | |||
| a4808635f9 | |||
| 29965782a2 |
Generated
+3
-1
@@ -4576,7 +4576,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-gateway"
|
name = "nym-gateway"
|
||||||
version = "1.1.36"
|
version = "1.1.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -5843,7 +5843,9 @@ dependencies = [
|
|||||||
"dashmap",
|
"dashmap",
|
||||||
"hmac 0.12.1",
|
"hmac 0.12.1",
|
||||||
"log",
|
"log",
|
||||||
|
"nym-config",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
|
"nym-network-defaults",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -171,3 +171,25 @@ impl fmt::Display for GatewayIpPacketRouterDetails {
|
|||||||
writeln!(f, "\taddress: {}", self.address)
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ log = { workspace = true }
|
|||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
|
||||||
|
nym-config = { path = "../config" }
|
||||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||||
|
nym-network-defaults = { path = "../network-defaults" }
|
||||||
|
|
||||||
# feature-specific dependencies:
|
# feature-specific dependencies:
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -1,15 +1,51 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// 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 error;
|
||||||
pub mod public_key;
|
pub mod public_key;
|
||||||
pub mod registration;
|
pub mod registration;
|
||||||
|
|
||||||
|
pub use config::Config;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use public_key::PeerPublicKey;
|
pub use public_key::PeerPublicKey;
|
||||||
pub use registration::{
|
pub use registration::{
|
||||||
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce,
|
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, GatewayClientRegistry,
|
||||||
|
InitMessage, Nonce,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub use registration::HmacSha256;
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ impl PeerPublicKey {
|
|||||||
pub fn as_bytes(&self) -> &[u8] {
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
self.0.as_bytes()
|
self.0.as_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inner(&self) -> PublicKey {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PeerPublicKey {
|
impl fmt::Display for PeerPublicKey {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use std::{fmt, ops::Deref, str::FromStr};
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
|
use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ impl GatewayClient {
|
|||||||
#[cfg(feature = "verify")]
|
#[cfg(feature = "verify")]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
local_secret: &PrivateKey,
|
local_secret: &PrivateKey,
|
||||||
remote_public: PublicKey,
|
remote_public: x25519_dalek::PublicKey,
|
||||||
private_ip: IpAddr,
|
private_ip: IpAddr,
|
||||||
nonce: u64,
|
nonce: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -96,8 +96,6 @@ impl GatewayClient {
|
|||||||
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
|
||||||
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
|
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);
|
let dh = static_secret.diffie_hellman(&remote_public);
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
// TODO: change that to use our nym_crypto::hmac module instead
|
||||||
|
|||||||
+15
-18
@@ -3,40 +3,37 @@
|
|||||||
// #![warn(clippy::expect_used)]
|
// #![warn(clippy::expect_used)]
|
||||||
// #![warn(clippy::unwrap_used)]
|
// #![warn(clippy::unwrap_used)]
|
||||||
|
|
||||||
pub mod setup;
|
|
||||||
|
|
||||||
/// Start wireguard device
|
/// Start wireguard device
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub async fn start_wireguard(
|
pub async fn start_wireguard(
|
||||||
mut task_client: nym_task::TaskClient,
|
mut task_client: nym_task::TaskClient,
|
||||||
_gateway_client_registry: std::sync::Arc<
|
wireguard_data: std::sync::Arc<nym_wireguard_types::WireguardGatewayData>,
|
||||||
nym_wireguard_types::registration::GatewayClientRegistry,
|
|
||||||
>,
|
|
||||||
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
|
) -> 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::{
|
use defguard_wireguard_rs::{
|
||||||
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
|
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 ifname = String::from("wg0");
|
||||||
let wgapi = WGApi::new(ifname.clone(), false)?;
|
let wgapi = WGApi::new(ifname.clone(), false)?;
|
||||||
wgapi.create_interface()?;
|
wgapi.create_interface()?;
|
||||||
let interface_config = InterfaceConfiguration {
|
let interface_config = InterfaceConfiguration {
|
||||||
name: ifname.clone(),
|
name: ifname.clone(),
|
||||||
prvkey: PRIVATE_KEY.to_string(),
|
prvkey: BASE64_STANDARD.encode(wireguard_data.keypair().private_key().to_bytes()),
|
||||||
address: WG_TUN_DEVICE_ADDRESS.to_string(),
|
address: wireguard_data.config().private_ip.to_string(),
|
||||||
port: WG_PORT as u32,
|
port: wireguard_data.config().announced_port as u32,
|
||||||
peers: vec![],
|
peers,
|
||||||
};
|
};
|
||||||
wgapi.configure_interface(&interface_config)?;
|
wgapi.configure_interface(&interface_config)?;
|
||||||
let peer = peer_static_public_key();
|
// wgapi.configure_peer_routing(&peers)?;
|
||||||
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()])?;
|
|
||||||
|
|
||||||
tokio::spawn(async move { task_client.recv().await });
|
tokio::spawn(async move { task_client.recv().await });
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
@@ -148,8 +148,8 @@ Options:
|
|||||||
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
|
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
|
||||||
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
|
--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=]
|
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>
|
--wireguard-private-gw-ip <WIREGUARD_PRIVATE_IP>
|
||||||
Ip address of the private wireguard network. default: `10.1.0.0` [env: NYMNODE_WG_IP_NETWORK=]
|
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
|
||||||
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
|
--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=]
|
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>
|
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-gateway"
|
name = "nym-gateway"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
version = "1.1.36"
|
version = "1.1.37"
|
||||||
authors = [
|
authors = [
|
||||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||||
|
|||||||
@@ -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> {
|
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 {
|
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
|
// 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
|
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||||
return Ok(false);
|
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.");
|
info!("It is going to get updated to the current specification.");
|
||||||
|
|
||||||
let updated: Config = old_config.into();
|
let updated: Config = old_config.into();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use nym_config::{
|
|||||||
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
|
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,
|
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 serde::{Deserialize, Serialize};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
@@ -20,7 +20,7 @@ use std::time::Duration;
|
|||||||
use url::Url;
|
use url::Url;
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
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_20;
|
||||||
pub mod old_config_v1_1_28;
|
pub mod old_config_v1_1_28;
|
||||||
@@ -85,10 +85,6 @@ pub struct Config {
|
|||||||
|
|
||||||
pub gateway: Gateway,
|
pub gateway: Gateway,
|
||||||
|
|
||||||
// currently not really used for anything useful
|
|
||||||
#[serde(default)]
|
|
||||||
pub wireguard: Wireguard,
|
|
||||||
|
|
||||||
pub storage_paths: GatewayPaths,
|
pub storage_paths: GatewayPaths,
|
||||||
|
|
||||||
pub network_requester: NetworkRequester,
|
pub network_requester: NetworkRequester,
|
||||||
@@ -121,7 +117,6 @@ impl Config {
|
|||||||
},
|
},
|
||||||
http: Default::default(),
|
http: Default::default(),
|
||||||
gateway: default_gateway,
|
gateway: default_gateway,
|
||||||
wireguard: Default::default(),
|
|
||||||
storage_paths: GatewayPaths::new_default(id.as_ref()),
|
storage_paths: GatewayPaths::new_default(id.as_ref()),
|
||||||
network_requester: Default::default(),
|
network_requester: Default::default(),
|
||||||
ip_packet_router: Default::default(),
|
ip_packet_router: Default::default(),
|
||||||
@@ -135,7 +130,6 @@ impl Config {
|
|||||||
host: impl Into<Host>,
|
host: impl Into<Host>,
|
||||||
http: impl Into<Http>,
|
http: impl Into<Http>,
|
||||||
gateway: impl Into<Gateway>,
|
gateway: impl Into<Gateway>,
|
||||||
wireguard: impl Into<Wireguard>,
|
|
||||||
storage_paths: impl Into<GatewayPaths>,
|
storage_paths: impl Into<GatewayPaths>,
|
||||||
network_requester: impl Into<NetworkRequester>,
|
network_requester: impl Into<NetworkRequester>,
|
||||||
ip_packet_router: impl Into<IpPacketRouter>,
|
ip_packet_router: impl Into<IpPacketRouter>,
|
||||||
@@ -147,7 +141,6 @@ impl Config {
|
|||||||
host: host.into(),
|
host: host.into(),
|
||||||
http: http.into(),
|
http: http.into(),
|
||||||
gateway: gateway.into(),
|
gateway: gateway.into(),
|
||||||
wireguard: wireguard.into(),
|
|
||||||
storage_paths: storage_paths.into(),
|
storage_paths: storage_paths.into(),
|
||||||
network_requester: network_requester.into(),
|
network_requester: network_requester.into(),
|
||||||
ip_packet_router: ip_packet_router.into(),
|
ip_packet_router: ip_packet_router.into(),
|
||||||
@@ -262,8 +255,6 @@ impl Config {
|
|||||||
|
|
||||||
let http_port = self.http.bind_address.port();
|
let http_port = self.http.bind_address.port();
|
||||||
self.http.bind_address = SocketAddr::new(listening_address, http_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
|
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
|
// we only really care about the mnemonic being zeroized
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)]
|
||||||
pub struct Gateway {
|
pub struct Gateway {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::config::persistence::paths::{GatewayPaths, WireguardPaths};
|
|
||||||
use nym_bin_common::logging::LoggingSettings;
|
|
||||||
use nym_config::{
|
use nym_config::{
|
||||||
must_get_home, read_config_from_toml_file, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR,
|
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 std::time::Duration;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use super::persistence::paths::KeysPaths;
|
use super::{Host, Http};
|
||||||
use super::{Config, Debug, Gateway, Host, Http, NetworkRequester, Wireguard};
|
use crate::config::persistence::paths::KeysPaths;
|
||||||
|
use crate::config::{Config, Debug, Gateway, GatewayPaths, LoggingSettings, NetworkRequester};
|
||||||
|
|
||||||
const DEFAULT_GATEWAYS_DIR: &str = "gateways";
|
const DEFAULT_GATEWAYS_DIR: &str = "gateways";
|
||||||
|
|
||||||
@@ -125,15 +124,6 @@ impl From<ConfigV1_1_31> for Config {
|
|||||||
nyxd_urls: value.gateway.nyxd_urls,
|
nyxd_urls: value.gateway.nyxd_urls,
|
||||||
cosmos_mnemonic: value.gateway.cosmos_mnemonic,
|
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 {
|
storage_paths: GatewayPaths {
|
||||||
keys: KeysPaths {
|
keys: KeysPaths {
|
||||||
private_identity_key_file: value.storage_paths.keys.private_identity_key_file,
|
private_identity_key_file: value.storage_paths.keys.private_identity_key_file,
|
||||||
|
|||||||
@@ -169,15 +169,3 @@ impl KeysPaths {
|
|||||||
&self.public_sphinx_key_file
|
&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 {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -63,6 +63,17 @@ pub enum GatewayError {
|
|||||||
source: io::Error,
|
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(
|
#[error(
|
||||||
"failed to save config file for id {id} using path '{}'. detailed message: {source}", path.display()
|
"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"))]
|
#[cfg(all(feature = "wireguard", target_os = "linux"))]
|
||||||
#[error("failed to remove wireguard interface: {0}")]
|
#[error("failed to remove wireguard interface: {0}")]
|
||||||
WireguardInterfaceError(#[from] defguard_wireguard_rs::error::WireguardInterfaceError),
|
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 {
|
impl From<ClientCoreError> for GatewayError {
|
||||||
|
|||||||
+8
-34
@@ -4,7 +4,6 @@
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::GatewayError;
|
use crate::error::GatewayError;
|
||||||
use crate::helpers::load_public_key;
|
use crate::helpers::load_public_key;
|
||||||
use ipnetwork::IpNetwork;
|
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use nym_bin_common::bin_info_owned;
|
use nym_bin_common::bin_info_owned;
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
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;
|
||||||
use nym_node_http_api::api::api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy;
|
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::api::api_requests::SignedHostInformation;
|
||||||
use nym_node_http_api::router::WireguardAppState;
|
|
||||||
use nym_node_http_api::NymNodeHttpError;
|
use nym_node_http_api::NymNodeHttpError;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use nym_wireguard_types::registration::GatewayClientRegistry;
|
use nym_wireguard_types::WireguardGatewayData;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn load_gateway_details(
|
fn load_gateway_details(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<api_requests::v1::gateway::models::Gateway, GatewayError> {
|
) -> 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 {
|
Ok(api_requests::v1::gateway::models::Gateway {
|
||||||
enforces_zk_nyms: config.gateway.only_coconut_credentials,
|
enforces_zk_nyms: config.gateway.only_coconut_credentials,
|
||||||
client_interfaces: api_requests::v1::gateway::models::ClientInterfaces {
|
client_interfaces: api_requests::v1::gateway::models::ClientInterfaces {
|
||||||
wireguard,
|
wireguard: None,
|
||||||
mixnet_websockets: Some(api_requests::v1::gateway::models::WebSockets {
|
mixnet_websockets: Some(api_requests::v1::gateway::models::WebSockets {
|
||||||
ws_port: config.gateway.clients_port,
|
ws_port: config.gateway.clients_port,
|
||||||
wss_port: config.gateway.clients_wss_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
|
// TODO: this should be a wg specific key and not re-used sphinx
|
||||||
sphinx_keypair: Arc<encryption::KeyPair>,
|
sphinx_keypair: Arc<encryption::KeyPair>,
|
||||||
|
|
||||||
client_registry: Option<Arc<GatewayClientRegistry>>,
|
wireguard_data: Option<Arc<WireguardGatewayData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HttpApiBuilder<'a> {
|
impl<'a> HttpApiBuilder<'a> {
|
||||||
@@ -170,7 +158,7 @@ impl<'a> HttpApiBuilder<'a> {
|
|||||||
exit_policy: None,
|
exit_policy: None,
|
||||||
identity_keypair,
|
identity_keypair,
|
||||||
sphinx_keypair,
|
sphinx_keypair,
|
||||||
client_registry: None,
|
wireguard_data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,11 +223,11 @@ impl<'a> HttpApiBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn with_wireguard_client_registry(
|
pub(crate) fn with_wireguard_data(
|
||||||
mut self,
|
mut self,
|
||||||
client_registry: Arc<GatewayClientRegistry>,
|
wireguard_data: Option<Arc<WireguardGatewayData>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.client_registry = Some(client_registry);
|
self.wireguard_data = wireguard_data;
|
||||||
self
|
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 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 {
|
tokio::spawn(async move {
|
||||||
let server = match router.build_server(&bind_address).await {
|
let server = match router.build_server(&bind_address).await {
|
||||||
|
|||||||
+23
-15
@@ -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::helpers::{initialise_main_storage, load_network_requester_config};
|
||||||
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
|
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
|
||||||
use crate::node::statistics::collector::GatewayStatisticsCollector;
|
use crate::node::statistics::collector::GatewayStatisticsCollector;
|
||||||
use dashmap::DashMap;
|
|
||||||
use futures::channel::{mpsc, oneshot};
|
use futures::channel::{mpsc, oneshot};
|
||||||
use log::*;
|
use log::*;
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
@@ -28,7 +27,7 @@ use nym_task::{TaskClient, TaskHandle, TaskManager};
|
|||||||
use nym_types::gateway::GatewayNodeDetailsResponse;
|
use nym_types::gateway::GatewayNodeDetailsResponse;
|
||||||
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
|
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
|
||||||
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
|
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
|
||||||
use nym_wireguard_types::registration::GatewayClientRegistry;
|
use nym_wireguard_types::WireguardGatewayData;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use std::net::SocketAddr;
|
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.
|
/// x25519 keypair used for Diffie-Hellman. Currently only used for sphinx key derivation.
|
||||||
sphinx_keypair: Arc<encryption::KeyPair>,
|
sphinx_keypair: Arc<encryption::KeyPair>,
|
||||||
|
|
||||||
storage: St,
|
storage: St,
|
||||||
|
|
||||||
client_registry: Arc<GatewayClientRegistry>,
|
wireguard_data: Option<Arc<WireguardGatewayData>>,
|
||||||
|
|
||||||
run_http_server: bool,
|
run_http_server: bool,
|
||||||
task_client: Option<TaskClient>,
|
task_client: Option<TaskClient>,
|
||||||
@@ -149,7 +149,7 @@ impl<St> Gateway<St> {
|
|||||||
config,
|
config,
|
||||||
network_requester_opts,
|
network_requester_opts,
|
||||||
ip_packet_router_opts,
|
ip_packet_router_opts,
|
||||||
client_registry: Arc::new(DashMap::new()),
|
wireguard_data: None,
|
||||||
run_http_server: true,
|
run_http_server: true,
|
||||||
task_client: None,
|
task_client: None,
|
||||||
})
|
})
|
||||||
@@ -170,7 +170,7 @@ impl<St> Gateway<St> {
|
|||||||
identity_keypair,
|
identity_keypair,
|
||||||
sphinx_keypair,
|
sphinx_keypair,
|
||||||
storage,
|
storage,
|
||||||
client_registry: Arc::new(DashMap::new()),
|
wireguard_data: None,
|
||||||
run_http_server: true,
|
run_http_server: true,
|
||||||
task_client: None,
|
task_client: None,
|
||||||
}
|
}
|
||||||
@@ -184,12 +184,14 @@ impl<St> Gateway<St> {
|
|||||||
self.task_client = Some(task_client)
|
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:
|
// sanity check:
|
||||||
if Arc::strong_count(&self.client_registry) != 1 {
|
if let Some(wg_data) = self.wireguard_data.as_ref() {
|
||||||
panic!("the client registry is already being used elsewhere")
|
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> {
|
pub async fn node_details(&self) -> Result<GatewayNodeDetailsResponse, GatewayError> {
|
||||||
@@ -230,7 +232,11 @@ impl<St> Gateway<St> {
|
|||||||
&self,
|
&self,
|
||||||
shutdown: TaskClient,
|
shutdown: TaskClient,
|
||||||
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync>> {
|
) -> 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")))]
|
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
|
||||||
@@ -555,7 +561,7 @@ impl<St> Gateway<St> {
|
|||||||
self.identity_keypair.as_ref(),
|
self.identity_keypair.as_ref(),
|
||||||
self.sphinx_keypair.clone(),
|
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_requester(self.network_requester_opts.as_ref().map(|o| &o.config))
|
||||||
.with_maybe_network_request_filter(nr_request_filter)
|
.with_maybe_network_request_filter(nr_request_filter)
|
||||||
.with_maybe_ip_packet_router(self.ip_packet_router_opts.as_ref().map(|o| &o.config))
|
.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
|
// Once this is a bit more mature, make this a commandline flag instead of a compile time
|
||||||
// flag
|
// flag
|
||||||
#[cfg(all(feature = "wireguard", target_os = "linux"))]
|
#[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")))]
|
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
|
||||||
self.start_wireguard(shutdown.fork("wireguard")).await;
|
self.start_wireguard(shutdown.fork("wireguard")).await;
|
||||||
@@ -577,9 +586,8 @@ impl<St> Gateway<St> {
|
|||||||
return Err(GatewayError::ShutdownFailure { source });
|
return Err(GatewayError::ShutdownFailure { source });
|
||||||
}
|
}
|
||||||
#[cfg(all(feature = "wireguard", target_os = "linux"))]
|
#[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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,3 +60,6 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions)
|
# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions)
|
||||||
cargo_metadata = "0.18.1"
|
cargo_metadata = "0.18.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
wireguard = ["nym-gateway/wireguard"]
|
||||||
|
|||||||
+6
-5
@@ -10,7 +10,6 @@ use crate::router::types::RequestError;
|
|||||||
use axum::extract::{Path, Query, State};
|
use axum::extract::{Path, Query, State};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use nym_crypto::asymmetric::encryption::PublicKey;
|
|
||||||
use nym_node_requests::api::v1::gateway::client_interfaces::wireguard::models::{
|
use nym_node_requests::api::v1::gateway::client_interfaces::wireguard::models::{
|
||||||
ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce, PeerPublicKey,
|
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.registration_in_progress.remove(&client.pub_key());
|
||||||
state.client_registry.insert(client.pub_key(), client);
|
state.client_registry.insert(client.pub_key(), client);
|
||||||
|
|
||||||
@@ -86,8 +88,7 @@ pub(crate) async fn register_client(
|
|||||||
|
|
||||||
match payload {
|
match payload {
|
||||||
ClientMessage::Initial(init) => {
|
ClientMessage::Initial(init) => {
|
||||||
let remote_public = PublicKey::from_bytes(init.pub_key().as_bytes())
|
let remote_public = init.pub_key().inner();
|
||||||
.map_err(|_| RequestError::new_status(StatusCode::BAD_REQUEST))?;
|
|
||||||
let nonce = process_init_message(init, state).await;
|
let nonce = process_init_message(init, state).await;
|
||||||
let mut private_ip_ref = state
|
let mut private_ip_ref = state
|
||||||
.free_private_network_ips
|
.free_private_network_ips
|
||||||
@@ -101,7 +102,7 @@ pub(crate) async fn register_client(
|
|||||||
// mark it as used, even though it's not final
|
// mark it as used, even though it's not final
|
||||||
*private_ip_ref = false;
|
*private_ip_ref = false;
|
||||||
let gateway_data = GatewayClient::new(
|
let gateway_data = GatewayClient::new(
|
||||||
&state.private_key,
|
&state.keypair.private_key(),
|
||||||
remote_public,
|
remote_public,
|
||||||
*private_ip_ref.key(),
|
*private_ip_ref.key(),
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
+7
-9
@@ -8,11 +8,11 @@ use crate::error::NymNodeHttpError;
|
|||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use ipnetwork::IpNetwork;
|
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_node_requests::routes::api::v1::gateway::client_interfaces::wireguard;
|
||||||
use nym_wireguard::setup;
|
|
||||||
use nym_wireguard_types::registration::PrivateIPs;
|
use nym_wireguard_types::registration::PrivateIPs;
|
||||||
use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations};
|
use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations};
|
||||||
|
use nym_wireguard_types::WireguardGatewayData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub(crate) mod client_registry;
|
pub(crate) mod client_registry;
|
||||||
@@ -27,17 +27,15 @@ pub struct WireguardAppState {
|
|||||||
|
|
||||||
impl WireguardAppState {
|
impl WireguardAppState {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
client_registry: Arc<GatewayClientRegistry>,
|
wireguard_gateway_data: &WireguardGatewayData,
|
||||||
registration_in_progress: Arc<PendingRegistrations>,
|
registration_in_progress: Arc<PendingRegistrations>,
|
||||||
binding_port: u16,
|
binding_port: u16,
|
||||||
private_ip_network: IpNetwork,
|
private_ip_network: IpNetwork,
|
||||||
) -> Result<Self, NymNodeHttpError> {
|
) -> Result<Self, NymNodeHttpError> {
|
||||||
Ok(WireguardAppState {
|
Ok(WireguardAppState {
|
||||||
inner: Some(WireguardAppStateInner {
|
inner: Some(WireguardAppStateInner {
|
||||||
private_key: Arc::new(PrivateKey::from_bytes(
|
keypair: wireguard_gateway_data.keypair().clone(),
|
||||||
setup::server_static_private_key().as_ref(),
|
client_registry: wireguard_gateway_data.client_registry().clone(),
|
||||||
)?),
|
|
||||||
client_registry,
|
|
||||||
registration_in_progress,
|
registration_in_progress,
|
||||||
binding_port,
|
binding_port,
|
||||||
free_private_network_ips: Arc::new(
|
free_private_network_ips: Arc::new(
|
||||||
@@ -83,7 +81,7 @@ macro_rules! get_state {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct WireguardAppStateInner {
|
pub(crate) struct WireguardAppStateInner {
|
||||||
private_key: Arc<PrivateKey>,
|
keypair: Arc<KeyPair>,
|
||||||
client_registry: Arc<GatewayClientRegistry>,
|
client_registry: Arc<GatewayClientRegistry>,
|
||||||
registration_in_progress: Arc<PendingRegistrations>,
|
registration_in_progress: Arc<PendingRegistrations>,
|
||||||
binding_port: u16,
|
binding_port: u16,
|
||||||
@@ -168,7 +166,7 @@ mod test {
|
|||||||
let state = WireguardAppState {
|
let state = WireguardAppState {
|
||||||
inner: Some(WireguardAppStateInner {
|
inner: Some(WireguardAppStateInner {
|
||||||
client_registry: Arc::clone(&client_registry),
|
client_registry: Arc::clone(&client_registry),
|
||||||
private_key: Arc::new(gateway_private_key),
|
keypair: Arc::new(gateway_private_key),
|
||||||
registration_in_progress: Arc::clone(®istration_in_progress),
|
registration_in_progress: Arc::clone(®istration_in_progress),
|
||||||
binding_port: 8080,
|
binding_port: 8080,
|
||||||
free_private_network_ips,
|
free_private_network_ips,
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ use nym_mixnode::MixnodeError;
|
|||||||
use nym_network_requester::{CustomGatewayDetails, GatewayDetails};
|
use nym_network_requester::{CustomGatewayDetails, GatewayDetails};
|
||||||
use nym_node::config;
|
use nym_node::config;
|
||||||
use nym_node::config::mixnode::DEFAULT_VERLOC_PORT;
|
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::{default_config_filepath, ConfigBuilder, NodeMode};
|
||||||
use nym_node::config::{Config, DEFAULT_WIREGUARD_NETWORK_IP};
|
|
||||||
use nym_node::error::{EntryGatewayError, ExitGatewayError, NymNodeError};
|
use nym_node::error::{EntryGatewayError, ExitGatewayError, NymNodeError};
|
||||||
use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription;
|
use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
@@ -400,15 +400,6 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
|
|||||||
},
|
},
|
||||||
..config::MixnodeConfig::new_default()
|
..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(
|
.with_entry_gateway(args.entry_gateway.override_config_section(
|
||||||
config::EntryGatewayConfig {
|
config::EntryGatewayConfig {
|
||||||
storage_paths: config::persistence::EntryGatewayPaths::new(&data_dir),
|
storage_paths: config::persistence::EntryGatewayPaths::new(&data_dir),
|
||||||
@@ -606,6 +597,8 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate::node::WireguardData::initialise(&config.wireguard)?;
|
||||||
|
|
||||||
save_node_description(
|
save_node_description(
|
||||||
&config.storage_paths.description,
|
&config.storage_paths.description,
|
||||||
&NodeDescription::default(),
|
&NodeDescription::default(),
|
||||||
|
|||||||
@@ -253,13 +253,13 @@ pub(crate) struct WireguardArgs {
|
|||||||
)]
|
)]
|
||||||
pub(crate) wireguard_bind_address: Option<SocketAddr>,
|
pub(crate) wireguard_bind_address: Option<SocketAddr>,
|
||||||
|
|
||||||
/// Ip address of the private wireguard network.
|
/// Private IP address of the wireguard gateway.
|
||||||
/// default: `10.1.0.0`
|
/// default: `10.1.0.1`
|
||||||
#[clap(
|
#[clap(
|
||||||
long,
|
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.
|
/// Port announced to external clients wishing to connect to the wireguard interface.
|
||||||
/// Useful in the instances where the node is behind a proxy.
|
/// Useful in the instances where the node is behind a proxy.
|
||||||
@@ -300,8 +300,8 @@ impl WireguardArgs {
|
|||||||
section.announced_port = announced_port
|
section.announced_port = announced_port
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(private_network_ip) = self.wireguard_private_network_ip {
|
if let Some(private_ip) = self.wireguard_private_ip {
|
||||||
section.private_network_ip = private_network_ip
|
section.private_ip = private_ip
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(private_network_prefix) = self.wireguard_private_network_prefix {
|
if let Some(private_network_prefix) = self.wireguard_private_network_prefix {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
use super::LocalWireguardOpts;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ExitGatewayConfig {
|
pub struct ExitGatewayConfig {
|
||||||
@@ -136,6 +138,7 @@ pub struct EphemeralConfig {
|
|||||||
pub gateway: nym_gateway::config::Config,
|
pub gateway: nym_gateway::config::Config,
|
||||||
pub nr_opts: LocalNetworkRequesterOpts,
|
pub nr_opts: LocalNetworkRequesterOpts,
|
||||||
pub ipr_opts: LocalIpPacketRouterOpts,
|
pub ipr_opts: LocalIpPacketRouterOpts,
|
||||||
|
pub wg_opts: LocalWireguardOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base_client_config(config: &Config) -> nym_client_core_config_types::Client {
|
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 ipr_enabled = config.exit_gateway.ip_packet_router.debug.enabled;
|
||||||
let nr_enabled = config.exit_gateway.network_requester.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)?;
|
let mut gateway = ephemeral_gateway_config(config, mnemonic)?;
|
||||||
gateway.ip_packet_router.enabled = ipr_enabled;
|
gateway.ip_packet_router.enabled = ipr_enabled;
|
||||||
gateway.network_requester.enabled = nr_enabled;
|
gateway.network_requester.enabled = nr_enabled;
|
||||||
@@ -253,6 +268,7 @@ pub fn ephemeral_exit_gateway_config(
|
|||||||
Ok(EphemeralConfig {
|
Ok(EphemeralConfig {
|
||||||
nr_opts,
|
nr_opts,
|
||||||
ipr_opts,
|
ipr_opts,
|
||||||
|
wg_opts,
|
||||||
gateway,
|
gateway,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,19 +57,10 @@ pub fn ephemeral_gateway_config(
|
|||||||
cosmos_mnemonic: mnemonic.clone(),
|
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(
|
Ok(nym_gateway::config::Config::externally_loaded(
|
||||||
host,
|
host,
|
||||||
http,
|
http,
|
||||||
gateway,
|
gateway,
|
||||||
wireguard,
|
|
||||||
nym_gateway::config::GatewayPaths::new_empty(),
|
nym_gateway::config::GatewayPaths::new_empty(),
|
||||||
nym_gateway::config::NetworkRequester { enabled: false },
|
nym_gateway::config::NetworkRequester { enabled: false },
|
||||||
nym_gateway::config::IpPacketRouter { enabled: false },
|
nym_gateway::config::IpPacketRouter { enabled: false },
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub use crate::config::mixnode::MixnodeConfig;
|
|||||||
const DEFAULT_NYMNODES_DIR: &str = "nym-nodes";
|
const DEFAULT_NYMNODES_DIR: &str = "nym-nodes";
|
||||||
|
|
||||||
pub const DEFAULT_WIREGUARD_PORT: u16 = WG_PORT;
|
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_WIREGUARD_PREFIX: u8 = 16;
|
||||||
pub const DEFAULT_HTTP_PORT: u16 = DEFAULT_NYM_NODE_HTTP_PORT;
|
pub const DEFAULT_HTTP_PORT: u16 = DEFAULT_NYM_NODE_HTTP_PORT;
|
||||||
pub const DEFAULT_MIXNET_PORT: u16 = DEFAULT_MIX_LISTENING_PORT;
|
pub const DEFAULT_MIXNET_PORT: u16 = DEFAULT_MIX_LISTENING_PORT;
|
||||||
@@ -500,9 +500,9 @@ pub struct Wireguard {
|
|||||||
/// default: `0.0.0.0:51822`
|
/// default: `0.0.0.0:51822`
|
||||||
pub bind_address: SocketAddr,
|
pub bind_address: SocketAddr,
|
||||||
|
|
||||||
/// Ip address of the private wireguard network.
|
/// Private IP address of the wireguard gateway.
|
||||||
/// default: `10.1.0.0`
|
/// default: `10.1.0.1`
|
||||||
pub private_network_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
|
|
||||||
/// Port announced to external clients wishing to connect to the wireguard interface.
|
/// Port announced to external clients wishing to connect to the wireguard interface.
|
||||||
/// Useful in the instances where the node is behind a proxy.
|
/// Useful in the instances where the node is behind a proxy.
|
||||||
@@ -524,10 +524,28 @@ impl Wireguard {
|
|||||||
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
DEFAULT_WIREGUARD_PORT,
|
DEFAULT_WIREGUARD_PORT,
|
||||||
),
|
),
|
||||||
private_network_ip: DEFAULT_WIREGUARD_NETWORK_IP,
|
private_ip: DEFAULT_WIREGUARD_IP,
|
||||||
announced_port: DEFAULT_WIREGUARD_PORT,
|
announced_port: DEFAULT_WIREGUARD_PORT,
|
||||||
private_network_prefix: DEFAULT_WIREGUARD_PREFIX,
|
private_network_prefix: DEFAULT_WIREGUARD_PREFIX,
|
||||||
storage_paths: persistence::WireguardPaths::new(data_dir),
|
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>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -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_REPLY_SURB_DB_FILENAME: &str = "ipr_persistent_reply_store.sqlite";
|
||||||
pub const DEFAULT_IPR_GATEWAYS_DB_FILENAME: &str = "ipr_gateways_info_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)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct NymNodePaths {
|
pub struct NymNodePaths {
|
||||||
@@ -366,11 +370,23 @@ impl ExitGatewayPaths {
|
|||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct WireguardPaths {
|
pub struct WireguardPaths {
|
||||||
// pub keys:
|
pub private_diffie_hellman_key_file: PathBuf,
|
||||||
|
pub public_diffie_hellman_key_file: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WireguardPaths {
|
impl WireguardPaths {
|
||||||
pub fn new<P: AsRef<Path>>(_data_dir: P) -> Self {
|
pub fn new<P: AsRef<Path>>(data_dir: P) -> Self {
|
||||||
WireguardPaths {}
|
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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,9 +115,9 @@ enabled = {{ wireguard.enabled }}
|
|||||||
# default: `0.0.0.0:51822`
|
# default: `0.0.0.0:51822`
|
||||||
bind_address = '{{ wireguard.bind_address }}'
|
bind_address = '{{ wireguard.bind_address }}'
|
||||||
|
|
||||||
# Ip address of the private wireguard network.
|
# Private IP address of the wireguard gateway.
|
||||||
# default: `10.1.0.0`
|
# default: `10.1.0.1`
|
||||||
private_network_ip = '{{ wireguard.private_network_ip }}'
|
private_ip = '{{ wireguard.private_ip }}'
|
||||||
|
|
||||||
# Port announced to external clients wishing to connect to the wireguard interface.
|
# Port announced to external clients wishing to connect to the wireguard interface.
|
||||||
# Useful in the instances where the node is behind a proxy.
|
# 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
|
# The maximum value for IPv4 is 32 and for IPv6 is 128
|
||||||
private_network_prefix = {{ wireguard.private_network_prefix }}
|
private_network_prefix = {{ wireguard.private_network_prefix }}
|
||||||
|
|
||||||
# Paths for wireguard keys, client registries, etc.
|
|
||||||
[wireguard.storage_paths]
|
[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 #####
|
##### mixnode mode nym-node config options #####
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ pub mod vars {
|
|||||||
// wireguard:
|
// wireguard:
|
||||||
pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED";
|
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_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_ANNOUNCED_PORT_ARG: &str = "NYMNODE_WG_ANNOUNCED_PORT";
|
||||||
pub const NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG: &str = "NYMNODE_WG_PRIVATE_NETWORK_PREFIX";
|
pub const NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG: &str = "NYMNODE_WG_PRIVATE_NETWORK_PREFIX";
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ pub(crate) struct DisplayDetails {
|
|||||||
pub(crate) ed25519_identity_key: String,
|
pub(crate) ed25519_identity_key: String,
|
||||||
pub(crate) x25519_sphinx_key: String,
|
pub(crate) x25519_sphinx_key: String,
|
||||||
pub(crate) x25519_noise_key: String,
|
pub(crate) x25519_noise_key: String,
|
||||||
|
pub(crate) x25519_wireguard_key: String,
|
||||||
|
|
||||||
pub(crate) exit_network_requester_address: String,
|
pub(crate) exit_network_requester_address: String,
|
||||||
pub(crate) exit_ip_packet_router_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")?)
|
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>>(
|
pub(crate) fn load_x25519_sphinx_public_key<P: AsRef<Path>>(
|
||||||
path: P,
|
path: P,
|
||||||
) -> Result<x25519::PublicKey, NymNodeError> {
|
) -> Result<x25519::PublicKey, NymNodeError> {
|
||||||
|
|||||||
+69
-10
@@ -20,7 +20,9 @@ use nym_network_requester::{
|
|||||||
use nym_node::config::entry_gateway::ephemeral_entry_gateway_config;
|
use nym_node::config::entry_gateway::ephemeral_entry_gateway_config;
|
||||||
use nym_node::config::exit_gateway::ephemeral_exit_gateway_config;
|
use nym_node::config::exit_gateway::ephemeral_exit_gateway_config;
|
||||||
use nym_node::config::mixnode::ephemeral_mixnode_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::error::{EntryGatewayError, ExitGatewayError, MixnodeError, NymNodeError};
|
||||||
use nym_node_http_api::api::api_requests;
|
use nym_node_http_api::api::api_requests;
|
||||||
use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription;
|
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_acknowledgements::AckKey;
|
||||||
use nym_sphinx_addressing::Recipient;
|
use nym_sphinx_addressing::Recipient;
|
||||||
use nym_task::{TaskClient, TaskManager};
|
use nym_task::{TaskClient, TaskManager};
|
||||||
use nym_wireguard_types::registration::GatewayClientRegistry;
|
use nym_wireguard_types::WireguardGatewayData;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@@ -39,6 +41,8 @@ use std::sync::Arc;
|
|||||||
use tracing::{debug, error, info, trace};
|
use tracing::{debug, error, info, trace};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
|
use self::helpers::load_x25519_wireguard_keypair;
|
||||||
|
|
||||||
pub mod bonding_information;
|
pub mod bonding_information;
|
||||||
pub mod description;
|
pub mod description;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
@@ -63,7 +67,7 @@ impl MixnodeData {
|
|||||||
pub struct EntryGatewayData {
|
pub struct EntryGatewayData {
|
||||||
mnemonic: Zeroizing<bip39::Mnemonic>,
|
mnemonic: Zeroizing<bip39::Mnemonic>,
|
||||||
client_storage: nym_gateway::node::PersistentStorage,
|
client_storage: nym_gateway::node::PersistentStorage,
|
||||||
client_registry: Arc<GatewayClientRegistry>,
|
wireguard_data: WireguardGatewayData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EntryGatewayData {
|
impl EntryGatewayData {
|
||||||
@@ -81,7 +85,10 @@ impl EntryGatewayData {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn new(config: &EntryGatewayConfig) -> Result<EntryGatewayData, EntryGatewayError> {
|
async fn new(
|
||||||
|
config: &EntryGatewayConfig,
|
||||||
|
wireguard_data: WireguardGatewayData,
|
||||||
|
) -> Result<EntryGatewayData, EntryGatewayError> {
|
||||||
Ok(EntryGatewayData {
|
Ok(EntryGatewayData {
|
||||||
mnemonic: config.storage_paths.load_mnemonic_from_file()?,
|
mnemonic: config.storage_paths.load_mnemonic_from_file()?,
|
||||||
client_storage: nym_gateway::node::PersistentStorage::init(
|
client_storage: nym_gateway::node::PersistentStorage::init(
|
||||||
@@ -90,7 +97,7 @@ impl EntryGatewayData {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(nym_gateway::GatewayError::from)?,
|
.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 {
|
pub(crate) struct NymNode {
|
||||||
config: Config,
|
config: Config,
|
||||||
description: NodeDescription,
|
description: NodeDescription,
|
||||||
@@ -259,6 +293,8 @@ pub(crate) struct NymNode {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
exit_gateway: ExitGatewayData,
|
exit_gateway: ExitGatewayData,
|
||||||
|
|
||||||
|
wireguard: WireguardData,
|
||||||
|
|
||||||
ed25519_identity_keys: Arc<ed25519::KeyPair>,
|
ed25519_identity_keys: Arc<ed25519::KeyPair>,
|
||||||
x25519_sphinx_keys: Arc<x25519::KeyPair>,
|
x25519_sphinx_keys: Arc<x25519::KeyPair>,
|
||||||
|
|
||||||
@@ -314,10 +350,18 @@ impl NymNode {
|
|||||||
ExitGatewayData::initialise(&config.exit_gateway, *ed25519_identity_keys.public_key())
|
ExitGatewayData::initialise(&config.exit_gateway, *ed25519_identity_keys.public_key())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// wireguard initialisation
|
||||||
|
WireguardData::initialise(&config.wireguard)?;
|
||||||
|
|
||||||
config.save()
|
config.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn new(config: Config) -> Result<Self, NymNodeError> {
|
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 {
|
Ok(NymNode {
|
||||||
ed25519_identity_keys: Arc::new(load_ed25519_identity_keypair(
|
ed25519_identity_keys: Arc::new(load_ed25519_identity_keypair(
|
||||||
config.storage_paths.keys.ed25519_identity_storage_paths(),
|
config.storage_paths.keys.ed25519_identity_storage_paths(),
|
||||||
@@ -331,8 +375,10 @@ impl NymNode {
|
|||||||
description: load_node_description(&config.storage_paths.description)?,
|
description: load_node_description(&config.storage_paths.description)?,
|
||||||
verloc_stats: Default::default(),
|
verloc_stats: Default::default(),
|
||||||
mixnode: MixnodeData::new(&config.mixnode)?,
|
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)?,
|
exit_gateway: ExitGatewayData::new(&config.exit_gateway)?,
|
||||||
|
wireguard: wireguard_data,
|
||||||
config,
|
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 {
|
pub(crate) fn display_details(&self) -> DisplayDetails {
|
||||||
DisplayDetails {
|
DisplayDetails {
|
||||||
current_mode: self.config.mode,
|
current_mode: self.config.mode,
|
||||||
@@ -360,6 +410,7 @@ impl NymNode {
|
|||||||
ed25519_identity_key: self.ed25519_identity_key().to_base58_string(),
|
ed25519_identity_key: self.ed25519_identity_key().to_base58_string(),
|
||||||
x25519_sphinx_key: self.x25519_sphinx_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_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_network_requester_address: self.exit_network_requester_address().to_string(),
|
||||||
exit_ip_packet_router_address: self.exit_ip_packet_router_address().to_string(),
|
exit_ip_packet_router_address: self.exit_ip_packet_router_address().to_string(),
|
||||||
}
|
}
|
||||||
@@ -409,6 +460,10 @@ impl NymNode {
|
|||||||
|
|
||||||
let config =
|
let config =
|
||||||
ephemeral_entry_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?;
|
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(
|
let mut entry_gateway = Gateway::new_loaded(
|
||||||
config,
|
config,
|
||||||
None,
|
None,
|
||||||
@@ -419,7 +474,7 @@ impl NymNode {
|
|||||||
);
|
);
|
||||||
entry_gateway.disable_http_server();
|
entry_gateway.disable_http_server();
|
||||||
entry_gateway.set_task_client(task_client);
|
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 {
|
tokio::spawn(async move {
|
||||||
if let Err(err) = entry_gateway.run().await {
|
if let Err(err) = entry_gateway.run().await {
|
||||||
@@ -434,6 +489,10 @@ impl NymNode {
|
|||||||
|
|
||||||
let config =
|
let config =
|
||||||
ephemeral_exit_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?;
|
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(
|
let mut exit_gateway = Gateway::new_loaded(
|
||||||
config.gateway,
|
config.gateway,
|
||||||
@@ -445,7 +504,7 @@ impl NymNode {
|
|||||||
);
|
);
|
||||||
exit_gateway.disable_http_server();
|
exit_gateway.disable_http_server();
|
||||||
exit_gateway.set_task_client(task_client);
|
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 {
|
tokio::spawn(async move {
|
||||||
if let Err(err) = exit_gateway.run().await {
|
if let Err(err) = exit_gateway.run().await {
|
||||||
@@ -517,12 +576,12 @@ impl NymNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let wireguard_private_network = IpNetwork::new(
|
let wireguard_private_network = IpNetwork::new(
|
||||||
self.config.wireguard.private_network_ip,
|
self.config.wireguard.private_ip,
|
||||||
self.config.wireguard.private_network_prefix,
|
self.config.wireguard.private_network_prefix,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let wg_state = WireguardAppState::new(
|
let wg_state = WireguardAppState::new(
|
||||||
self.entry_gateway.client_registry.clone(),
|
&self.entry_gateway.wireguard_data,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
self.config.wireguard.bind_address.port(),
|
self.config.wireguard.bind_address.port(),
|
||||||
wireguard_private_network,
|
wireguard_private_network,
|
||||||
|
|||||||
Reference in New Issue
Block a user