9a0b769425
* Bind to [::] on nym-node for both IP versions * Force update to be run * Fix after merging develop
491 lines
15 KiB
Rust
491 lines
15 KiB
Rust
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
use super::DEFAULT_NYMNODE_ID;
|
|
use crate::config;
|
|
use crate::config::default_config_filepath;
|
|
use crate::env::vars::*;
|
|
use celes::Country;
|
|
use clap::builder::ArgPredicate;
|
|
use clap::Args;
|
|
use std::net::{IpAddr, SocketAddr};
|
|
use std::path::{Path, PathBuf};
|
|
use url::Url;
|
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
|
|
|
#[derive(Args, Debug)]
|
|
pub(crate) struct ConfigArgs {
|
|
/// Id of the nym-node to use
|
|
#[clap(
|
|
long,
|
|
default_value = DEFAULT_NYMNODE_ID,
|
|
default_value_if("config_file", ArgPredicate::IsPresent, None),
|
|
env = NYMNODE_ID_ARG,
|
|
group = "config"
|
|
)]
|
|
id: Option<String>,
|
|
|
|
/// Path to a configuration file of this node.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_CONFIG_PATH_ARG,
|
|
group = "config"
|
|
)]
|
|
config_file: Option<PathBuf>,
|
|
}
|
|
|
|
impl ConfigArgs {
|
|
pub(crate) fn id(&self) -> &Option<String> {
|
|
&self.id
|
|
}
|
|
|
|
pub(crate) fn config_path(&self) -> PathBuf {
|
|
// SAFETY:
|
|
// if `config_file` hasn't been specified, `id` will default to "DEFAULT_NYMNODE_ID",
|
|
// so some value will always be available to use
|
|
#[allow(clippy::unwrap_used)]
|
|
self.config_file
|
|
.clone()
|
|
.unwrap_or_else(|| default_config_filepath(self.id.as_ref().unwrap()))
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct HostArgs {
|
|
/// Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients.
|
|
/// In nearly all circumstances, it's going to be identical to the address you're going to use for bonding.
|
|
#[clap(
|
|
long,
|
|
value_delimiter = ',',
|
|
env = NYMNODE_PUBLIC_IPS_ARG
|
|
)]
|
|
pub(crate) public_ips: Option<Vec<IpAddr>>,
|
|
|
|
/// Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HOSTNAME_ARG
|
|
)]
|
|
pub(crate) hostname: Option<String>,
|
|
|
|
/// Optional **physical** location of this node's server.
|
|
/// Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'),
|
|
/// three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_LOCATION_ARG
|
|
)]
|
|
pub(crate) location: Option<Country>,
|
|
}
|
|
|
|
impl HostArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section(self) -> config::Host {
|
|
self.override_config_section(config::Host::default())
|
|
}
|
|
|
|
pub(crate) fn override_config_section(self, mut section: config::Host) -> config::Host {
|
|
if let Some(public_ips) = self.public_ips {
|
|
section.public_ips = public_ips
|
|
}
|
|
if let Some(hostname) = self.hostname {
|
|
section.hostname = Some(hostname)
|
|
}
|
|
if let Some(location) = self.location {
|
|
section.location = Some(location)
|
|
}
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct HttpArgs {
|
|
/// Socket address this node will use for binding its http API.
|
|
/// default: `[::]:8080`
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_BIND_ADDRESS_ARG
|
|
)]
|
|
pub(crate) http_bind_address: Option<SocketAddr>,
|
|
|
|
/// Path to assets directory of custom landing page of this node.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_LANDING_ASSETS_ARG
|
|
)]
|
|
pub(crate) landing_page_assets_path: Option<PathBuf>,
|
|
|
|
/// An optional bearer token for accessing certain http endpoints.
|
|
/// Currently only used for prometheus metrics.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_ACCESS_TOKEN_ARG,
|
|
alias = "http-bearer-token"
|
|
)]
|
|
pub(crate) http_access_token: Option<String>,
|
|
|
|
/// Specify whether basic system information should be exposed.
|
|
/// default: true
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_EXPOSE_SYSTEM_INFO_ARG,
|
|
)]
|
|
pub(crate) expose_system_info: Option<bool>,
|
|
|
|
/// Specify whether basic system hardware information should be exposed.
|
|
/// default: true
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE_ARG
|
|
)]
|
|
pub(crate) expose_system_hardware: Option<bool>,
|
|
|
|
/// Specify whether detailed system crypto hardware information should be exposed.
|
|
/// default: true
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE_ARG
|
|
)]
|
|
pub(crate) expose_crypto_hardware: Option<bool>,
|
|
}
|
|
|
|
impl HttpArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section(self) -> config::Http {
|
|
self.override_config_section(config::Http::default())
|
|
}
|
|
|
|
pub(crate) fn override_config_section(self, mut section: config::Http) -> config::Http {
|
|
if let Some(bind_address) = self.http_bind_address {
|
|
section.bind_address = bind_address
|
|
}
|
|
if let Some(landing_page_assets_path) = self.landing_page_assets_path {
|
|
section.landing_page_assets_path = Some(landing_page_assets_path)
|
|
}
|
|
if let Some(access_token) = self.http_access_token {
|
|
section.access_token = Some(access_token)
|
|
}
|
|
if let Some(expose_system_info) = self.expose_system_info {
|
|
section.expose_system_info = expose_system_info
|
|
}
|
|
if let Some(expose_hardware_info) = self.expose_system_hardware {
|
|
section.expose_system_hardware = expose_hardware_info
|
|
}
|
|
if let Some(expose_crypto_hardware) = self.expose_crypto_hardware {
|
|
section.expose_crypto_hardware = expose_crypto_hardware
|
|
}
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct MixnetArgs {
|
|
/// Address this node will bind to for listening for mixnet packets
|
|
/// default: `[::]:1789`
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_MIXNET_BIND_ADDRESS_ARG
|
|
)]
|
|
pub(crate) mixnet_bind_address: Option<SocketAddr>,
|
|
|
|
/// If applicable, custom port announced in the self-described API that other clients and nodes
|
|
/// will use.
|
|
/// Useful when the node is behind a proxy.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_MIXNET_ANNOUNCE_PORT_ARG
|
|
)]
|
|
pub(crate) mixnet_announce_port: Option<u16>,
|
|
|
|
/// Addresses to nym APIs from which the node gets the view of the network.
|
|
#[clap(
|
|
long,
|
|
value_delimiter = ',',
|
|
env = NYMNODE_NYM_APIS_ARG
|
|
)]
|
|
pub(crate) nym_api_urls: Option<Vec<Url>>,
|
|
|
|
/// Addresses to nyxd chain endpoint which the node will use for chain interactions.
|
|
#[clap(
|
|
long,
|
|
value_delimiter = ',',
|
|
env = NYMNODE_NYXD_URLS_ARG
|
|
)]
|
|
pub(crate) nyxd_urls: Option<Vec<Url>>,
|
|
|
|
/// Specifies whether this node should **NOT** use noise protocol in the connections (currently not implemented)
|
|
#[clap(
|
|
hide = true,
|
|
long,
|
|
env = NYMNODE_UNSAFE_DISABLE_NOISE
|
|
)]
|
|
pub(crate) unsafe_disable_noise: bool,
|
|
}
|
|
|
|
impl MixnetArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section(self) -> config::Mixnet {
|
|
self.override_config_section(config::Mixnet::default())
|
|
}
|
|
|
|
pub(crate) fn override_config_section(self, mut section: config::Mixnet) -> config::Mixnet {
|
|
if let Some(bind_address) = self.mixnet_bind_address {
|
|
section.bind_address = bind_address
|
|
}
|
|
if let Some(mixnet_announce_port) = self.mixnet_announce_port {
|
|
section.announce_port = Some(mixnet_announce_port)
|
|
}
|
|
if let Some(nym_api_urls) = self.nym_api_urls {
|
|
section.nym_api_urls = nym_api_urls
|
|
}
|
|
if let Some(nyxd_urls) = self.nyxd_urls {
|
|
section.nyxd_urls = nyxd_urls
|
|
}
|
|
if self.unsafe_disable_noise {
|
|
section.debug.unsafe_disable_noise = true
|
|
}
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct WireguardArgs {
|
|
/// Specifies whether the wireguard service is enabled on this node.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_WG_ENABLED_ARG
|
|
)]
|
|
pub(crate) wireguard_enabled: Option<bool>,
|
|
|
|
/// Socket address this node will use for binding its wireguard interface.
|
|
/// default: `[::]:51822`
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_WG_BIND_ADDRESS_ARG
|
|
)]
|
|
pub(crate) wireguard_bind_address: Option<SocketAddr>,
|
|
|
|
/// Port announced to external clients wishing to connect to the wireguard interface.
|
|
/// Useful in the instances where the node is behind a proxy.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_WG_ANNOUNCED_PORT_ARG
|
|
)]
|
|
pub(crate) wireguard_announced_port: Option<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
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG
|
|
)]
|
|
pub(crate) wireguard_private_network_prefix: Option<u8>,
|
|
}
|
|
|
|
impl WireguardArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section<P: AsRef<Path>>(self, data_dir: P) -> config::Wireguard {
|
|
self.override_config_section(config::Wireguard::new_default(data_dir))
|
|
}
|
|
|
|
pub(crate) fn override_config_section(
|
|
self,
|
|
mut section: config::Wireguard,
|
|
) -> config::Wireguard {
|
|
if let Some(enabled) = self.wireguard_enabled {
|
|
section.enabled = enabled
|
|
}
|
|
|
|
if let Some(bind_address) = self.wireguard_bind_address {
|
|
section.bind_address = bind_address
|
|
}
|
|
|
|
if let Some(announced_port) = self.wireguard_announced_port {
|
|
section.announced_port = announced_port
|
|
}
|
|
|
|
if let Some(private_network_prefix) = self.wireguard_private_network_prefix {
|
|
section.private_network_prefix_v4 = private_network_prefix
|
|
}
|
|
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct VerlocArgs {
|
|
/// Socket address this node will use for binding its verloc API.
|
|
/// default: `[::]:1790`
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_VERLOC_BIND_ADDRESS_ARG
|
|
)]
|
|
pub(crate) verloc_bind_address: Option<SocketAddr>,
|
|
|
|
/// If applicable, custom port announced in the self-described API that other clients and nodes
|
|
/// will use.
|
|
/// Useful when the node is behind a proxy.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_VERLOC_ANNOUNCE_PORT_ARG
|
|
)]
|
|
pub(crate) verloc_announce_port: Option<u16>,
|
|
}
|
|
|
|
impl VerlocArgs {
|
|
pub(crate) fn build_config_section(self) -> config::Verloc {
|
|
self.override_config_section(config::Verloc::default())
|
|
}
|
|
|
|
pub(crate) fn override_config_section(self, mut section: config::Verloc) -> config::Verloc {
|
|
if let Some(bind_address) = self.verloc_bind_address {
|
|
section.bind_address = bind_address
|
|
}
|
|
if let Some(announce_port) = self.verloc_announce_port {
|
|
section.announce_port = Some(announce_port)
|
|
}
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct MetricsArgs {
|
|
/// Specify whether running statistics of this node should be logged to the console.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_ENABLE_CONSOLE_LOGGING
|
|
)]
|
|
enable_console_logging: Option<bool>,
|
|
}
|
|
|
|
impl MetricsArgs {
|
|
pub(crate) fn build_config_section(self) -> config::MetricsConfig {
|
|
self.override_config_section(config::MetricsConfig::default())
|
|
}
|
|
|
|
pub(crate) fn override_config_section(
|
|
self,
|
|
mut section: config::MetricsConfig,
|
|
) -> config::MetricsConfig {
|
|
if let Some(enable_console_logging) = self.enable_console_logging {
|
|
section.debug.log_stats_to_console = enable_console_logging;
|
|
}
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug, Zeroize, ZeroizeOnDrop)]
|
|
pub(crate) struct EntryGatewayArgs {
|
|
/// Socket address this node will use for binding its client websocket API.
|
|
/// default: `[::]:9000`
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_ENTRY_BIND_ADDRESS_ARG
|
|
)]
|
|
#[zeroize(skip)]
|
|
pub(crate) entry_bind_address: Option<SocketAddr>,
|
|
|
|
/// Custom announced port for listening for websocket client traffic.
|
|
/// If unspecified, the value from the `bind_address` will be used instead
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_ENTRY_ANNOUNCE_WS_PORT_ARG
|
|
)]
|
|
pub(crate) announce_ws_port: Option<u16>,
|
|
|
|
/// If applicable, announced port for listening for secure websocket client traffic.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_ENTRY_ANNOUNCE_WSS_PORT_ARG
|
|
)]
|
|
pub(crate) announce_wss_port: Option<u16>,
|
|
|
|
/// Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet
|
|
/// or if it also accepts non-paying clients
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_ENFORCE_ZK_NYMS_ARG
|
|
)]
|
|
pub(crate) enforce_zk_nyms: Option<bool>,
|
|
|
|
/// Custom cosmos wallet mnemonic used for zk-nym redemption.
|
|
/// If no value is provided, a fresh mnemonic is going to be generated.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_MNEMONIC_ARG
|
|
)]
|
|
pub(crate) mnemonic: Option<bip39::Mnemonic>,
|
|
}
|
|
|
|
impl EntryGatewayArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section<P: AsRef<Path>>(
|
|
self,
|
|
data_dir: P,
|
|
) -> config::GatewayTasksConfig {
|
|
self.override_config_section(config::GatewayTasksConfig::new_default(data_dir))
|
|
}
|
|
|
|
pub(crate) fn override_config_section(
|
|
self,
|
|
mut section: config::GatewayTasksConfig,
|
|
) -> config::GatewayTasksConfig {
|
|
if let Some(bind_address) = self.entry_bind_address {
|
|
section.ws_bind_address = bind_address
|
|
}
|
|
if let Some(ws_port) = self.announce_ws_port {
|
|
section.announce_ws_port = Some(ws_port)
|
|
}
|
|
if let Some(wss_port) = self.announce_wss_port {
|
|
section.announce_wss_port = Some(wss_port)
|
|
}
|
|
if let Some(enforce_zk_nyms) = self.enforce_zk_nyms {
|
|
section.enforce_zk_nyms = enforce_zk_nyms
|
|
}
|
|
|
|
section
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug)]
|
|
pub(crate) struct ExitGatewayArgs {
|
|
/// Specifies the url for an upstream source of the exit policy used by this node.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_UPSTREAM_EXIT_POLICY_ARG,
|
|
)]
|
|
pub(crate) upstream_exit_policy_url: Option<Url>,
|
|
|
|
/// Specifies whether this exit node should run in 'open-proxy' mode
|
|
/// and thus would attempt to resolve **ANY** request it receives.
|
|
#[clap(
|
|
long,
|
|
env = NYMNODE_OPEN_PROXY_ARG,
|
|
)]
|
|
pub(crate) open_proxy: Option<bool>,
|
|
}
|
|
|
|
impl ExitGatewayArgs {
|
|
// TODO: could we perhaps make a clap error here and call `safe_exit` instead?
|
|
pub(crate) fn build_config_section<P: AsRef<Path>>(
|
|
self,
|
|
data_dir: P,
|
|
) -> config::ServiceProvidersConfig {
|
|
self.override_config_section(config::ServiceProvidersConfig::new_default(data_dir))
|
|
}
|
|
|
|
pub(crate) fn override_config_section(
|
|
self,
|
|
mut section: config::ServiceProvidersConfig,
|
|
) -> config::ServiceProvidersConfig {
|
|
if let Some(upstream_exit_policy) = self.upstream_exit_policy_url {
|
|
section.upstream_exit_policy_url = upstream_exit_policy
|
|
}
|
|
if let Some(open_proxy) = self.open_proxy {
|
|
section.open_proxy = open_proxy
|
|
}
|
|
|
|
section
|
|
}
|
|
}
|