Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a0e1103648 | |||
| 31b059c0d3 | |||
| 4fa9b8b200 | |||
| 8c56739c8d | |||
| 5599987d89 | |||
| a93763d73b | |||
| 8e8b6f4467 | |||
| 7feeed41d5 | |||
| e9a20653b8 | |||
| 9438691506 | |||
| 84a4924e77 | |||
| 49277310ba | |||
| 944d2eb7d5 | |||
| bfaf17540e | |||
| 6dbc4efbd9 | |||
| cabbeaf1bf | |||
| bf85e9eb79 |
Generated
+1
@@ -6926,6 +6926,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"encoding_rs",
|
||||
"fastrand",
|
||||
"hickory-resolver",
|
||||
"http 1.3.1",
|
||||
"inventory",
|
||||
|
||||
@@ -13,8 +13,9 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
use tokio::sync::Mutex as AsyncMutex;
|
||||
use tokio::time::Instant;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{debug, info, instrument, warn};
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use helpers::{BufferedDeposit, PerformedDeposits, make_deposits_request, split_deposits};
|
||||
@@ -146,9 +147,14 @@ impl DepositsBuffer {
|
||||
|
||||
// if we're here, we know we're below the threshold
|
||||
fn maybe_refill_deposits(&self) {
|
||||
if let Some(mut guard) = self.inner.deposits_refill_task.try_get_new_task_guard() {
|
||||
if let Some((mut guard, completion_guard)) =
|
||||
self.inner.deposits_refill_task.try_get_new_task_guard()
|
||||
{
|
||||
let this = self.clone();
|
||||
*guard = Some(tokio::spawn(async move { this.refill_deposits().await }));
|
||||
*guard = Some(tokio::spawn(async move {
|
||||
let _completion_guard = completion_guard;
|
||||
this.refill_deposits().await
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +185,8 @@ impl DepositsBuffer {
|
||||
requested_on: OffsetDateTime,
|
||||
client_pubkey: PublicKeyUser,
|
||||
) -> Result<BufferedDeposit, CredentialProxyError> {
|
||||
let wait_start = Instant::now();
|
||||
let mut i = 0;
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
if let Some(buffered_deposit) = self.inner.unused_deposits.lock().await.pop() {
|
||||
@@ -195,6 +203,15 @@ impl DepositsBuffer {
|
||||
// make sure there's always a task working in the background in case deposits get used up too quickly
|
||||
self.maybe_refill_deposits()
|
||||
}
|
||||
i += 1;
|
||||
let elapsed = wait_start.elapsed();
|
||||
if elapsed > Duration::from_secs(5) && i % 10 == 0 {
|
||||
warn!("we've been waiting for over 5s to make a deposit - something is wrong!")
|
||||
} else if elapsed > Duration::from_secs(10) && i % 5 == 0 {
|
||||
error!(
|
||||
"we've been waiting for over 10s to make a deposit - something is SERIOUSLY wrong!"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,22 @@
|
||||
|
||||
use crate::error::CredentialProxyError;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Mutex as StdMutex, MutexGuard};
|
||||
use std::sync::{Arc, Mutex as StdMutex, MutexGuard};
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub(super) type RefillTaskResult = Result<(), CredentialProxyError>;
|
||||
|
||||
pub(super) struct InProgressGuard {
|
||||
in_progress: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Drop for InProgressGuard {
|
||||
fn drop(&mut self) {
|
||||
self.in_progress.store(false, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct RefillTask {
|
||||
// note that we can only have a single transaction in progress (or it'd mess up with our sequence numbers)
|
||||
@@ -16,7 +26,7 @@ pub(super) struct RefillTask {
|
||||
// we'll have to increase the number of deposits per transaction
|
||||
join_handle: StdMutex<Option<JoinHandle<RefillTaskResult>>>,
|
||||
|
||||
in_progress: AtomicBool,
|
||||
in_progress: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl RefillTask {
|
||||
@@ -28,9 +38,15 @@ impl RefillTask {
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
/// Returns `None` if a refill is already in progress. On success, returns the
|
||||
/// join-handle guard (to store the new `JoinHandle` into) and an [`InProgressGuard`]
|
||||
/// that **must be moved into the spawned task** — it resets the flag when dropped.
|
||||
pub(super) fn try_get_new_task_guard(
|
||||
&self,
|
||||
) -> Option<MutexGuard<'_, Option<JoinHandle<RefillTaskResult>>>> {
|
||||
) -> Option<(
|
||||
MutexGuard<'_, Option<JoinHandle<RefillTaskResult>>>,
|
||||
InProgressGuard,
|
||||
)> {
|
||||
// sanity check for concurrent request
|
||||
if !self.try_set_in_progress() {
|
||||
debug!("another task has already started deposit refill request");
|
||||
@@ -48,7 +64,11 @@ impl RefillTask {
|
||||
}
|
||||
}
|
||||
|
||||
Some(guard)
|
||||
let completion_guard = InProgressGuard {
|
||||
in_progress: Arc::clone(&self.in_progress),
|
||||
};
|
||||
|
||||
Some((guard, completion_guard))
|
||||
}
|
||||
|
||||
pub(super) fn take_task_join_handle(&self) -> Option<JoinHandle<RefillTaskResult>> {
|
||||
@@ -56,3 +76,34 @@ impl RefillTask {
|
||||
self.join_handle.lock().expect("mutex got poisoned").take()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn in_progress_resets_after_guard_drop() {
|
||||
let task = RefillTask::default();
|
||||
|
||||
let (guard, completion_guard) = task.try_get_new_task_guard().unwrap();
|
||||
drop(guard);
|
||||
assert!(task.try_get_new_task_guard().is_none());
|
||||
|
||||
drop(completion_guard);
|
||||
assert!(task.try_get_new_task_guard().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_progress_resets_on_panic() {
|
||||
let task = RefillTask::default();
|
||||
|
||||
let (guard, completion_guard) = task.try_get_new_task_guard().unwrap();
|
||||
drop(guard);
|
||||
|
||||
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
let _g = completion_guard;
|
||||
panic!("simulated refill task panic");
|
||||
}));
|
||||
assert!(task.try_get_new_task_guard().is_some());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ thiserror = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
inventory = { workspace = true }
|
||||
fastrand = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt", "macros", "time"] }
|
||||
rustls = { workspace=true }
|
||||
# used for decoding text responses (they were already implicitly included)
|
||||
|
||||
@@ -56,7 +56,6 @@ use std::{
|
||||
use hickory_resolver::{
|
||||
TokioResolver,
|
||||
config::{NameServerConfig, NameServerConfigGroup, ResolverConfig, ResolverOpts},
|
||||
lookup_ip::LookupIpIntoIter,
|
||||
name_server::TokioConnectionProvider,
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -227,9 +226,11 @@ async fn resolve(
|
||||
let primary_err = match resolve_fut.await {
|
||||
Err(_) => ResolveError::Timeout,
|
||||
Ok(Ok(lookup)) => {
|
||||
let addrs: Addrs = Box::new(SocketAddrs {
|
||||
iter: lookup.into_iter(),
|
||||
});
|
||||
// Shuffle so that successive connection attempts cycle through all
|
||||
// returned IPs rather than always hitting the same first address.
|
||||
let mut ips: Vec<IpAddr> = lookup.into_iter().collect();
|
||||
fastrand::shuffle(&mut ips);
|
||||
let addrs: Addrs = Box::new(ips.into_iter().map(|ip| SocketAddr::new(ip, 0)));
|
||||
return Ok(addrs);
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
@@ -256,18 +257,6 @@ async fn resolve(
|
||||
Err(primary_err)
|
||||
}
|
||||
|
||||
struct SocketAddrs {
|
||||
iter: LookupIpIntoIter,
|
||||
}
|
||||
|
||||
impl Iterator for SocketAddrs {
|
||||
type Item = SocketAddr;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
|
||||
}
|
||||
}
|
||||
|
||||
impl HickoryDnsResolver {
|
||||
/// Returns an instance of the shared resolver.
|
||||
pub fn shared() -> Self {
|
||||
|
||||
@@ -24,11 +24,14 @@ pub const SPHINX_STREAM_VERSION_THRESHOLD: u8 = v9::VERSION;
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const _: () = {
|
||||
assert!(SPHINX_STREAM_VERSION_THRESHOLD > MAX_NON_STREAM_VERSION);
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn stream_transport_threshold_is_consistent() {
|
||||
assert_eq!(MAX_NON_STREAM_VERSION, 8);
|
||||
assert_eq!(SPHINX_STREAM_VERSION_THRESHOLD, 9);
|
||||
assert!(SPHINX_STREAM_VERSION_THRESHOLD > MAX_NON_STREAM_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"mixmining_reserve": {
|
||||
"denom": "unym",
|
||||
"amount": "168575020719057"
|
||||
"amount": "166613455567357"
|
||||
},
|
||||
"vesting_tokens": {
|
||||
"denom": "unym",
|
||||
@@ -13,6 +13,6 @@
|
||||
},
|
||||
"circulating_supply": {
|
||||
"denom": "unym",
|
||||
"amount": "831424979280943"
|
||||
"amount": "833386544432643"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"nodes": 752,
|
||||
"locations": 76,
|
||||
"mixnodes": 273,
|
||||
"exit_gateways": 470
|
||||
"nodes": 744,
|
||||
"locations": 77,
|
||||
"mixnodes": 263,
|
||||
"exit_gateways": 474
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
831_424_979
|
||||
833_386_544
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4_682
|
||||
4_628
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
0.95%
|
||||
1.06%
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
30.134
|
||||
27.103
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
254_377
|
||||
254_977
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
61_050_638
|
||||
61_194_673
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
61_050_637
|
||||
61_194_672
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
| **Item** | **Description** | **Amount in NYM** |
|
||||
|:-------------------|:------------------------------------------------------|--------------------:|
|
||||
| Total Supply | Maximum amount of NYM token in existence | 1_000_000_000 |
|
||||
| Mixmining Reserve | Tokens releasing for operators rewards | 168_575_020 |
|
||||
| Mixmining Reserve | Tokens releasing for operators rewards | 166_613_455 |
|
||||
| Vesting Tokens | Tokens locked outside of circulation for future claim | 0 |
|
||||
| Circulating Supply | Amount of unlocked tokens | 831_424_979 |
|
||||
| Stake Saturation | Optimal size of node self-bond + delegation | 254_377 |
|
||||
| Circulating Supply | Amount of unlocked tokens | 833_386_544 |
|
||||
| Stake Saturation | Optimal size of node self-bond + delegation | 254_977 |
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"interval": {
|
||||
"reward_pool": "168575020719057.456153922699547282",
|
||||
"staking_supply": "61050637328128.353993717821521057",
|
||||
"reward_pool": "166613455567357.391753168447944888",
|
||||
"staking_supply": "61194672938727.325886595653401629",
|
||||
"staking_supply_scale_factor": "0.07342892",
|
||||
"epoch_reward_budget": "4682639464.418262670942297209",
|
||||
"stake_saturation_point": "254377655533.868141640490923004",
|
||||
"epoch_reward_budget": "4628151543.537705326476901331",
|
||||
"stake_saturation_point": "254977803911.363857860815222506",
|
||||
"sybil_resistance": "0.3",
|
||||
"active_set_work_factor": "10",
|
||||
"interval_pool_emission": "0.02"
|
||||
|
||||
@@ -1 +1 @@
|
||||
Thursday, April 9th 2026, 15:33:24 UTC
|
||||
Thursday, April 30th 2026, 08:30:26 UTC
|
||||
|
||||
@@ -6,6 +6,7 @@ usage: nym-node-cli install [-h] [-V] [-d BRANCH] [-v]
|
||||
[--email EMAIL] [--moniker MONIKER]
|
||||
[--description DESCRIPTION]
|
||||
[--public-ip PUBLIC_IP]
|
||||
[--host-ssh-port HOST_SSH_PORT]
|
||||
[--nym-node-binary NYM_NODE_BINARY]
|
||||
[--uplink-dev UPLINK_DEV] [--env KEY=VALUE]
|
||||
|
||||
@@ -27,6 +28,8 @@ options:
|
||||
Short public description of the node
|
||||
--public-ip PUBLIC_IP
|
||||
External IPv4 address (autodetected if omitted)
|
||||
--host-ssh-port HOST_SSH_PORT
|
||||
Host SSH port to allow in the firewall (default: 22)
|
||||
--nym-node-binary NYM_NODE_BINARY
|
||||
URL for nym-node binary (autodetected if omitted)
|
||||
--uplink-dev UPLINK_DEV
|
||||
|
||||
@@ -4,56 +4,115 @@ Start this nym-node
|
||||
Usage: nym-node run [OPTIONS]
|
||||
|
||||
Options:
|
||||
--id <ID> Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
|
||||
--config-file <CONFIG_FILE> Path to a configuration file of this node [env: NYMNODE_CONFIG=]
|
||||
--accept-operator-terms-and-conditions Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0> [env: NYMNODE_ACCEPT_OPERATOR_TERMS=]
|
||||
--deny-init Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: NYMNODE_DENY_INIT=]
|
||||
--init-only If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: NYMNODE_INIT_ONLY=]
|
||||
--local Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=]
|
||||
--mode [<MODE>...] Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only]
|
||||
--modes <MODES> Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only]
|
||||
-w, --write-changes If this node has been initialised before, specify whether to write any new changes to the config file [env: NYMNODE_WRITE_CONFIG_CHANGES=]
|
||||
--bonding-information-output <BONDING_INFORMATION_OUTPUT> Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a subject to change and this argument should be treated only as a preview of
|
||||
future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=]
|
||||
-o, --output <OUTPUT> Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, json]
|
||||
--public-ips <PUBLIC_IPS> 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 [env: NYMNODE_PUBLIC_IPS=]
|
||||
--hostname <HOSTNAME> Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=]
|
||||
--location <LOCATION> 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 [env: NYMNODE_LOCATION=]
|
||||
--http-bind-address <HTTP_BIND_ADDRESS> Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=]
|
||||
--landing-page-assets-path <LANDING_PAGE_ASSETS_PATH> Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=]
|
||||
--http-access-token <HTTP_ACCESS_TOKEN> An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=]
|
||||
--expose-system-info <EXPOSE_SYSTEM_INFO> Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false]
|
||||
--expose-system-hardware <EXPOSE_SYSTEM_HARDWARE> Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false]
|
||||
--expose-crypto-hardware <EXPOSE_CRYPTO_HARDWARE> Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false]
|
||||
--mixnet-bind-address <MIXNET_BIND_ADDRESS> Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=]
|
||||
--mixnet-announce-port <MIXNET_ANNOUNCE_PORT> 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 [env: NYMNODE_MIXNET_ANNOUNCE_PORT=]
|
||||
--nym-api-urls <NYM_API_URLS> Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=]
|
||||
--nyxd-urls <NYXD_URLS> Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=]
|
||||
--enable-console-logging <ENABLE_CONSOLE_LOGGING> Specify whether running statistics of this node should be logged to the console [env: NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible values: true, false]
|
||||
--wireguard-enabled <WIREGUARD_ENABLED> 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: `[::]:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
|
||||
--wireguard-tunnel-announced-port <WIREGUARD_TUNNEL_ANNOUNCED_PORT> Tunnel 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> 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 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=]
|
||||
--wireguard-userspace <WIREGUARD_USERSPACE> Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel WireGuard support [env: NYMNODE_WG_USERSPACE=] [possible values: true,
|
||||
false]
|
||||
--verloc-bind-address <VERLOC_BIND_ADDRESS> Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=]
|
||||
--verloc-announce-port <VERLOC_ANNOUNCE_PORT> 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 [env: NYMNODE_VERLOC_ANNOUNCE_PORT=]
|
||||
--entry-bind-address <ENTRY_BIND_ADDRESS> Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
|
||||
--announce-ws-port <ANNOUNCE_WS_PORT> Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=]
|
||||
--announce-wss-port <ANNOUNCE_WSS_PORT> If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=]
|
||||
--enforce-zk-nyms <ENFORCE_ZK_NYMS> Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false]
|
||||
--mnemonic <MNEMONIC> Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=]
|
||||
--upgrade-mode-attestation-url <UPGRADE_MODE_ATTESTATION_URL> Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=]
|
||||
--upgrade-mode-attester-public-key <UPGRADE_MODE_ATTESTER_PUBLIC_KEY> Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=]
|
||||
--upstream-exit-policy-url <UPSTREAM_EXIT_POLICY_URL> Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=]
|
||||
--open-proxy <OPEN_PROXY> Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, false]
|
||||
--lp-control-bind-address <LP_CONTROL_BIND_ADDRESS> Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=]
|
||||
--lp-control-announce-port <LP_CONTROL_ANNOUNCE_PORT> Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the `lp_control_bind_address` will be used instead [env: NYMNODE_LP_CONTROL_ANNOUNCE_PORT=]
|
||||
--lp-data-bind-address <LP_DATA_BIND_ADDRESS> Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=]
|
||||
--lp-data-announce-port <LP_DATA_ANNOUNCE_PORT> Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the `lp_data_bind_address` will be used instead [env: NYMNODE_LP_DATA_ANNOUNCE_PORT=]
|
||||
--lp-use-mock-ecash <LP_USE_MOCK_ECASH> Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP listener will accept any credential without blockchain verification [env:
|
||||
NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false]
|
||||
-h, --help Print help
|
||||
--id <ID>
|
||||
Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node]
|
||||
--config-file <CONFIG_FILE>
|
||||
Path to a configuration file of this node [env: NYMNODE_CONFIG=]
|
||||
--accept-operator-terms-and-conditions
|
||||
Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0> [env:
|
||||
NYMNODE_ACCEPT_OPERATOR_TERMS=]
|
||||
--deny-init
|
||||
Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: NYMNODE_DENY_INIT=]
|
||||
--init-only
|
||||
If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: NYMNODE_INIT_ONLY=]
|
||||
--local
|
||||
Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=]
|
||||
--mode [<MODE>...]
|
||||
Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only]
|
||||
--modes <MODES>
|
||||
Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only]
|
||||
-w, --write-changes
|
||||
If this node has been initialised before, specify whether to write any new changes to the config file [env: NYMNODE_WRITE_CONFIG_CHANGES=]
|
||||
--bonding-information-output <BONDING_INFORMATION_OUTPUT>
|
||||
Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a subject to change and this argument
|
||||
should be treated only as a preview of future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=]
|
||||
-o, --output <OUTPUT>
|
||||
Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, json]
|
||||
--public-ips <PUBLIC_IPS>
|
||||
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 [env: NYMNODE_PUBLIC_IPS=]
|
||||
--hostname <HOSTNAME>
|
||||
Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=]
|
||||
--location <LOCATION>
|
||||
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 [env: NYMNODE_LOCATION=]
|
||||
--http-bind-address <HTTP_BIND_ADDRESS>
|
||||
Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=]
|
||||
--landing-page-assets-path <LANDING_PAGE_ASSETS_PATH>
|
||||
Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=]
|
||||
--http-access-token <HTTP_ACCESS_TOKEN>
|
||||
An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=]
|
||||
--expose-system-info <EXPOSE_SYSTEM_INFO>
|
||||
Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false]
|
||||
--expose-system-hardware <EXPOSE_SYSTEM_HARDWARE>
|
||||
Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false]
|
||||
--expose-crypto-hardware <EXPOSE_CRYPTO_HARDWARE>
|
||||
Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false]
|
||||
--mixnet-bind-address <MIXNET_BIND_ADDRESS>
|
||||
Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=]
|
||||
--mixnet-announce-port <MIXNET_ANNOUNCE_PORT>
|
||||
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 [env:
|
||||
NYMNODE_MIXNET_ANNOUNCE_PORT=]
|
||||
--nym-api-urls <NYM_API_URLS>
|
||||
Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=]
|
||||
--nyxd-urls <NYXD_URLS>
|
||||
Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=]
|
||||
--enable-console-logging <ENABLE_CONSOLE_LOGGING>
|
||||
Specify whether running statistics of this node should be logged to the console [env: NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible values: true, false]
|
||||
--wireguard-enabled <WIREGUARD_ENABLED>
|
||||
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: `[::]:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
|
||||
--wireguard-tunnel-announced-port <WIREGUARD_TUNNEL_ANNOUNCED_PORT>
|
||||
Tunnel 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>
|
||||
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 [env:
|
||||
NYMNODE_WG_PRIVATE_NETWORK_PREFIX=]
|
||||
--wireguard-userspace <WIREGUARD_USERSPACE>
|
||||
Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel WireGuard support [env:
|
||||
NYMNODE_WG_USERSPACE=] [possible values: true, false]
|
||||
--verloc-bind-address <VERLOC_BIND_ADDRESS>
|
||||
Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=]
|
||||
--verloc-announce-port <VERLOC_ANNOUNCE_PORT>
|
||||
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 [env:
|
||||
NYMNODE_VERLOC_ANNOUNCE_PORT=]
|
||||
--entry-bind-address <ENTRY_BIND_ADDRESS>
|
||||
Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
|
||||
--announce-ws-port <ANNOUNCE_WS_PORT>
|
||||
Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env:
|
||||
NYMNODE_ENTRY_ANNOUNCE_WS_PORT=]
|
||||
--announce-wss-port <ANNOUNCE_WSS_PORT>
|
||||
If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=]
|
||||
--enforce-zk-nyms <ENFORCE_ZK_NYMS>
|
||||
Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=]
|
||||
[possible values: true, false]
|
||||
--mnemonic <MNEMONIC>
|
||||
Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=]
|
||||
--upgrade-mode-attestation-url <UPGRADE_MODE_ATTESTATION_URL>
|
||||
Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks [env:
|
||||
NYMNODE_UPGRADE_MODE_ATTESTATION_URL=]
|
||||
--upgrade-mode-attester-public-key <UPGRADE_MODE_ATTESTER_PUBLIC_KEY>
|
||||
Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local networks [env:
|
||||
NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=]
|
||||
--upstream-exit-policy-url <UPSTREAM_EXIT_POLICY_URL>
|
||||
Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=]
|
||||
--open-proxy <OPEN_PROXY>
|
||||
Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values:
|
||||
true, false]
|
||||
--lp-control-bind-address <LP_CONTROL_BIND_ADDRESS>
|
||||
Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=]
|
||||
--lp-control-announce-port <LP_CONTROL_ANNOUNCE_PORT>
|
||||
Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the `lp_control_bind_address` will be used instead [env:
|
||||
NYMNODE_LP_CONTROL_ANNOUNCE_PORT=]
|
||||
--lp-data-bind-address <LP_DATA_BIND_ADDRESS>
|
||||
Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=]
|
||||
--lp-data-announce-port <LP_DATA_ANNOUNCE_PORT>
|
||||
Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the `lp_data_bind_address` will be used instead [env:
|
||||
NYMNODE_LP_DATA_ANNOUNCE_PORT=]
|
||||
--lp-use-mock-ecash <LP_USE_MOCK_ECASH>
|
||||
Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP listener will accept any credential
|
||||
without blockchain verification [env: NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false]
|
||||
-h, --help
|
||||
Print help
|
||||
```
|
||||
|
||||
@@ -17,9 +17,9 @@ Download and run instructions for the GUIs can be found [here](https://nymvpn.co
|
||||
## Download & Extract Binary
|
||||
Check the [release page](https://github.com/nymtech/nym-vpn-client/releases/) page for the latest release version and modify the instructions accordingly. These instructions use the latest as of the time of writing.
|
||||
```sh
|
||||
wget -q https://github.com/nymtech/nym-vpn-client/releases/download/nym-vpn-core-v1.27.0-beta/nym-vpn-core-v1.27.0-beta_<YOUR_OPERATING_SYSTEM>.tar.gz &&
|
||||
tar -xzf nym-vpn-core-v1.27.0-beta_<YOUR_OPERATING_SYSTEM>.tar.gz &&
|
||||
cd nym-vpn-core-v1.27.0-beta_<YOUR_OPERATING_SYSTEM>/ &&
|
||||
wget -q https://github.com/nymtech/nym-vpn-client/releases/download/nym-vpn-core-v1.29.0/nym-vpn-core-v1.29.0_<YOUR_OPERATING_SYSTEM>.tar.gz &&
|
||||
tar -xzf nym-vpn-core-v1.29.0_<YOUR_OPERATING_SYSTEM>.tar.gz &&
|
||||
cd nym-vpn-core-v1.29.0_<YOUR_OPERATING_SYSTEM>/ &&
|
||||
chmod u+x *
|
||||
```
|
||||
|
||||
@@ -165,6 +165,66 @@ View the current device identity:
|
||||
nym-vpnc device get
|
||||
```
|
||||
|
||||
## Pay as You Go: Decentralized Access to Nym
|
||||
|
||||
You can fund your VPN usage directly from your own wallet instead of going through the NymVPN account system. You deposit `$NYM` into the ticketbook smart contract and receive zk-nym ticketbooks that authenticate you on the network.
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
If you already have an account stored in `nym-vpnc`, you must remove it first with `nym-vpnc account forget` before setting a new mnemonic.
|
||||
</Callout>
|
||||
|
||||
### Set Your Mnemonic
|
||||
|
||||
Store the recovery phrase for your on-chain wallet address (`n1...`) that holds your `$NYM` tokens:
|
||||
|
||||
```sh
|
||||
nym-vpnc account set "<MNEMONIC>" --location blockchain
|
||||
```
|
||||
|
||||
You must fund this address yourself, for example by transferring `$NYM` from an exchange or another wallet. The `--location blockchain` flag tells `nym-vpnc` to use the on-chain wallet directly rather than the NymVPN account system.
|
||||
|
||||
### Obtain Ticketbooks
|
||||
|
||||
Deposit `$NYM` into the ticketbook smart contract and receive zk-nym credentials:
|
||||
|
||||
```sh
|
||||
nym-vpnc account obtain-ticketbooks --amount 1 --source smartcontract
|
||||
```
|
||||
|
||||
You can omit `--source` to use the default:
|
||||
|
||||
```sh
|
||||
nym-vpnc account obtain-ticketbooks --amount 1
|
||||
```
|
||||
|
||||
The `--amount` flag specifies how many ticketbooks to obtain **per ticket type**. Each request issues one ticketbook for each of the three types:
|
||||
|
||||
- **Mixnet Entry** — used for 5-hop mixnet mode
|
||||
- **WireGuard Entry** — used for 2-hop WireGuard mode (entry side)
|
||||
- **WireGuard Exit** — used for 2-hop WireGuard mode (exit side)
|
||||
|
||||
So `--amount 1` produces 3 ticketbooks total (one of each type), and `--amount 2` produces 6.
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
Each ticketbook costs 75 NYM. Because `--amount` applies per type, `--amount 1` deposits **225 NYM** (75 × 3 types), and `--amount 2` deposits **450 NYM**. If you only use two-hop (WireGuard) mode, the Mixnet Entry ticketbooks will go unused. There is currently no way to obtain ticketbooks for a single type.
|
||||
</Callout>
|
||||
|
||||
This command:
|
||||
|
||||
- Deposits `$NYM` into the ticketbook smart contract (plus a small fee buffer per deposit)
|
||||
- Requests credential issuance from the decentralised Nym API validators
|
||||
- Stores the resulting zk-nym ticketbooks locally on the device
|
||||
|
||||
### Connect
|
||||
|
||||
Connect using the locally stored ticketbooks:
|
||||
|
||||
```sh
|
||||
nym-vpnc connect-v2
|
||||
```
|
||||
|
||||
The CLI uses the ticketbooks to authenticate with entry nodes (gateways) and connect to the Nym network. You will see the connection happening in the `nym-vpnd` logs.
|
||||
|
||||
## Tunnel Configuration
|
||||
|
||||
Print current tunnel configuration:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-credential-proxy"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2-rc"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
Generated
+53
-30
@@ -1258,7 +1258,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "core-models"
|
||||
version = "0.0.5"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "657f625ff361906f779745d08375ae3cc9fef87a35fba5f22874cf773010daf4"
|
||||
dependencies = [
|
||||
"hax-lib",
|
||||
"pastey",
|
||||
@@ -3854,7 +3855,8 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||
[[package]]
|
||||
name = "libcrux-aesgcm"
|
||||
version = "0.0.7"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99f2a019dab4097585a7d4f5b9deebe46cd1e628b16a5bc4cb0ce35e1da334e6"
|
||||
dependencies = [
|
||||
"libcrux-intrinsics",
|
||||
"libcrux-platform",
|
||||
@@ -3864,8 +3866,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-chacha20poly1305"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc08d044676af21343b32b988411fa98dbb5cf65a03c9df478ced221bbdfdb1b"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -3877,7 +3880,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-curve25519"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1e5fd8476a6ed609d24ef42aee5ab6f99f7c65d054f92412da9f499e423299"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -3888,7 +3892,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-ecdh"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b65f73ce79337c762eb38bbac91e4c9b9e60cf318e8501b812750c640814d45e"
|
||||
dependencies = [
|
||||
"libcrux-curve25519",
|
||||
"libcrux-p256",
|
||||
@@ -3898,8 +3903,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-ed25519"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "835919315b7042fe9e03b6458efe0db94bf2aa7b873934dbee5b5463a8124b43"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -3911,7 +3917,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-hacl-rs"
|
||||
version = "0.0.4"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2637dc87d158e1f1b550fd9b226443e84153fded4de69028d897b534d16d22e6"
|
||||
dependencies = [
|
||||
"libcrux-macros",
|
||||
]
|
||||
@@ -3919,7 +3926,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-hkdf"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c1a89ca0c89be3a268a921e47105fb7873badf7267f5e3ebf4ea46baedd73ef"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-hmac",
|
||||
@@ -3929,7 +3937,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-hmac"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7a242707d65960770bd7e14e4f18a92bdf0b967777dd404887db8d087a643b"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -3939,7 +3948,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-intrinsics"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1b5db005ff8001e026b73a6842ee81bbef8ec5ff0e1915a67ae65fd2a9fafa5"
|
||||
dependencies = [
|
||||
"core-models",
|
||||
"hax-lib",
|
||||
@@ -3947,8 +3957,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-kem"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12631592f491d22fd1a176d32b2c6edfb673998fd3987e9d95f8fa79ad2a737b"
|
||||
dependencies = [
|
||||
"libcrux-curve25519",
|
||||
"libcrux-ecdh",
|
||||
@@ -3963,7 +3974,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-macros"
|
||||
version = "0.0.3"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffd6aa2dcd5be681662001b81d493f1569c6d49a32361f470b0c955465cd0338"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
@@ -3971,8 +3983,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-ml-dsa"
|
||||
version = "0.0.7"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a72929ed421cc3bf16a946b3e7d2a58d215b0b5c2a12be26b53629f081bf49b2"
|
||||
dependencies = [
|
||||
"core-models",
|
||||
"hax-lib",
|
||||
@@ -3985,8 +3998,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-ml-kem"
|
||||
version = "0.0.7"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a14ab3e477de9df6ee1273a114018ff62c4996ca9220070c4e5cb1743f94a67d"
|
||||
dependencies = [
|
||||
"hax-lib",
|
||||
"libcrux-intrinsics",
|
||||
@@ -4001,7 +4015,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-p256"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4778ba25cb08bb8a96bd100e19ed9aecf78337198fd176036e21042b2dd99bc"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -4013,15 +4028,17 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-platform"
|
||||
version = "0.0.3"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d9e21d7ed31a92ac539bd69a8c970b183ee883872d2d19ce27036e24cb8ecc4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-poly1305"
|
||||
version = "0.0.4"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02491808ee5b9db8cb65fad64ae0be812db64beef179d945c00c7787dc7dfcf9"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -4029,8 +4046,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-psq"
|
||||
version = "0.0.7"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "779ade7aa5e1b4b400c716b313cbf69070988dd005f92e961c2da4c3c42fbea4"
|
||||
dependencies = [
|
||||
"libcrux-aesgcm",
|
||||
"libcrux-chacha20poly1305",
|
||||
@@ -4050,7 +4068,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-secrets"
|
||||
version = "0.0.5"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce650f3041b44ba40d4263852347d007cd2cd9d1cc856a6f6c8b2e10c3fd40b"
|
||||
dependencies = [
|
||||
"hax-lib",
|
||||
]
|
||||
@@ -4058,7 +4077,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-sha2"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9d253473f259fc74a280c43f29c464f7e374abdf28b4942234dc707f529d4b7"
|
||||
dependencies = [
|
||||
"libcrux-hacl-rs",
|
||||
"libcrux-macros",
|
||||
@@ -4067,8 +4087,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-sha3"
|
||||
version = "0.0.7"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1ae0b7d0e1cc4793a609fd0ff2ca3b3a3fabae523770c619a3d4bc86417b0d7"
|
||||
dependencies = [
|
||||
"hax-lib",
|
||||
"libcrux-intrinsics",
|
||||
@@ -4079,7 +4100,8 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libcrux-traits"
|
||||
version = "0.0.6"
|
||||
source = "git+https://github.com/cryspen/libcrux?rev=b17f8687b67cdcfc10b55aeecc998bbbca28f775#b17f8687b67cdcfc10b55aeecc998bbbca28f775"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e4fa89f3f5e34b47f928b22b1b78395a0d4ec23b1f583db635f128159d65f"
|
||||
dependencies = [
|
||||
"libcrux-secrets",
|
||||
"rand 0.9.2",
|
||||
@@ -5070,6 +5092,7 @@ dependencies = [
|
||||
"serde",
|
||||
"thiserror 2.0.12",
|
||||
"x25519-dalek",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Executable → Regular
+241
-99
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# nym tunnel and wireguard exit policy manager
|
||||
# nym host network firewall, tunnel and wireguard exit policy manager
|
||||
# run this script as root
|
||||
|
||||
set -euo pipefail
|
||||
@@ -20,6 +20,10 @@ info() {
|
||||
printf "%b\n" "${YELLOW}[INFO] $*${NC}"
|
||||
}
|
||||
|
||||
warn() {
|
||||
printf "%b\n" "${YELLOW}[WARN] $*${NC}"
|
||||
}
|
||||
|
||||
ok() {
|
||||
printf "%b\n" "${GREEN}[OK] $*${NC}"
|
||||
}
|
||||
@@ -102,18 +106,44 @@ detect_uplink_interface() {
|
||||
}
|
||||
|
||||
# uplink device detection, can be overridden
|
||||
# Backward compatibility:
|
||||
# - NETWORK_DEVICE sets both IPv4 and IPv6 uplinks.
|
||||
# Preferred overrides:
|
||||
# - NETWORK_DEVICE_V4
|
||||
# - NETWORK_DEVICE_V6
|
||||
NETWORK_DEVICE="${NETWORK_DEVICE:-}"
|
||||
if [[ -z "$NETWORK_DEVICE" ]]; then
|
||||
NETWORK_DEVICE="$(detect_uplink_interface "ip -o route show default")"
|
||||
NETWORK_DEVICE_V4="${NETWORK_DEVICE_V4:-${NETWORK_DEVICE:-}}"
|
||||
NETWORK_DEVICE_V6="${NETWORK_DEVICE_V6:-${NETWORK_DEVICE:-}}"
|
||||
|
||||
if [[ -z "$NETWORK_DEVICE_V4" ]]; then
|
||||
NETWORK_DEVICE_V4="$(detect_uplink_interface "ip -o route show default")"
|
||||
fi
|
||||
if [[ -z "$NETWORK_DEVICE" ]]; then
|
||||
NETWORK_DEVICE="$(detect_uplink_interface "ip -o route show default table all")"
|
||||
if [[ -z "$NETWORK_DEVICE_V4" ]]; then
|
||||
NETWORK_DEVICE_V4="$(detect_uplink_interface "ip -o route show default table all")"
|
||||
fi
|
||||
if [[ -z "$NETWORK_DEVICE" ]]; then
|
||||
error "cannot determine uplink interface. set NETWORK_DEVICE or UPLINK_DEV"
|
||||
if [[ -z "$NETWORK_DEVICE_V4" ]]; then
|
||||
error "cannot determine ipv4 uplink interface. set NETWORK_DEVICE_V4 or NETWORK_DEVICE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$NETWORK_DEVICE_V6" ]]; then
|
||||
NETWORK_DEVICE_V6="$(detect_uplink_interface "ip -6 -o route show default")"
|
||||
fi
|
||||
if [[ -z "$NETWORK_DEVICE_V6" ]]; then
|
||||
NETWORK_DEVICE_V6="$(detect_uplink_interface "ip -6 -o route show default table all")"
|
||||
fi
|
||||
|
||||
has_ipv6_uplink() {
|
||||
[[ -n "${NETWORK_DEVICE_V6:-}" ]]
|
||||
}
|
||||
|
||||
info "detected ipv4 uplink: $NETWORK_DEVICE_V4"
|
||||
if has_ipv6_uplink; then
|
||||
info "detected ipv6 uplink: $NETWORK_DEVICE_V6"
|
||||
else
|
||||
warn "could not determine ipv6 uplink interface. continuing with ipv4-only setup; ipv6-specific setup will be skipped and ipv6 tests may fail"
|
||||
fi
|
||||
|
||||
###############################################################################
|
||||
# shared helpers
|
||||
###############################################################################
|
||||
@@ -168,7 +198,7 @@ EOF
|
||||
}
|
||||
|
||||
save_iptables_rules() {
|
||||
info "saving iptables rules to /etc/iptables$"
|
||||
info "saving iptables rules to /etc/iptables"
|
||||
mkdir -p /etc/iptables
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
ip6tables-save > /etc/iptables/rules.v6
|
||||
@@ -194,11 +224,16 @@ fetch_ipv6_address() {
|
||||
|
||||
fetch_and_display_ipv6() {
|
||||
local ipv6_address
|
||||
ipv6_address=$(ip -6 addr show "$NETWORK_DEVICE" scope global | awk '/inet6/ {print $2}')
|
||||
if ! has_ipv6_uplink; then
|
||||
warn "no ipv6 uplink detected; skipping ipv6 uplink address display"
|
||||
return 0
|
||||
fi
|
||||
|
||||
ipv6_address=$(ip -6 addr show "$NETWORK_DEVICE_V6" scope global | awk '/inet6/ {print $2}')
|
||||
if [[ -z "$ipv6_address" ]]; then
|
||||
error "no global ipv6 address found on $NETWORK_DEVICE"
|
||||
error "no global ipv6 address found on $NETWORK_DEVICE_V6"
|
||||
else
|
||||
ok "ipv6 address on $NETWORK_DEVICE: $ipv6_address"
|
||||
ok "ipv6 address on $NETWORK_DEVICE_V6: $ipv6_address"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -343,35 +378,39 @@ remove_duplicate_rules() {
|
||||
|
||||
apply_iptables_rules() {
|
||||
local interface=$1
|
||||
info "applying iptables rules for $interface using uplink $NETWORK_DEVICE"
|
||||
info "applying iptables rules for $interface using ipv4 uplink $NETWORK_DEVICE_V4${NETWORK_DEVICE_V6:+ and ipv6 uplink $NETWORK_DEVICE_V6}"
|
||||
sleep 1
|
||||
|
||||
# ipv4 nat and forwarding
|
||||
iptables -t nat -C POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
|
||||
iptables -t nat -C POSTROUTING -o "$NETWORK_DEVICE_V4" -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -o "$NETWORK_DEVICE_V4" -j MASQUERADE
|
||||
|
||||
# governed by NYM-EXIT, do not add a broad FORWARD ACCEPT
|
||||
if ! iptables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
iptables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || \
|
||||
iptables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
|
||||
if ! iptables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
iptables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE_V4" -j ACCEPT 2>/dev/null || \
|
||||
iptables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE_V4" -j ACCEPT
|
||||
fi
|
||||
|
||||
iptables -C FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
|
||||
iptables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
iptables -C FORWARD -i "$NETWORK_DEVICE_V4" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
|
||||
iptables -I FORWARD 2 -i "$NETWORK_DEVICE_V4" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
|
||||
# ipv6 nat and forwarding
|
||||
ip6tables -t nat -C POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE 2>/dev/null || \
|
||||
ip6tables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
|
||||
if has_ipv6_uplink; then
|
||||
ip6tables -t nat -C POSTROUTING -o "$NETWORK_DEVICE_V6" -j MASQUERADE 2>/dev/null || \
|
||||
ip6tables -t nat -A POSTROUTING -o "$NETWORK_DEVICE_V6" -j MASQUERADE
|
||||
|
||||
# governed by NYM-EXIT, do not add a broad FORWARD ACCEPT
|
||||
if ! ip6tables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ip6tables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || \
|
||||
ip6tables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
|
||||
# governed by NYM-EXIT, do not add a broad FORWARD ACCEPT
|
||||
if ! ip6tables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ip6tables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE_V6" -j ACCEPT 2>/dev/null || \
|
||||
ip6tables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE_V6" -j ACCEPT
|
||||
fi
|
||||
|
||||
ip6tables -C FORWARD -i "$NETWORK_DEVICE_V6" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
|
||||
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE_V6" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
else
|
||||
warn "no ipv6 uplink detected; skipping ipv6 nat/forwarding rules for $interface"
|
||||
fi
|
||||
|
||||
ip6tables -C FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
|
||||
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
|
||||
save_iptables_rules
|
||||
}
|
||||
|
||||
@@ -517,6 +556,34 @@ apply_smtps_465_rate_limit() {
|
||||
###############################################################################
|
||||
|
||||
NETWORK_FIREWALL_COMMENT="NYM-NETWORK-FW"
|
||||
HOST_SSH_PORT="${HOST_SSH_PORT:-22}"
|
||||
NETWORK_FIREWALL_TCP_PORTS=("$HOST_SSH_PORT" 80 443 1789 1790 8080 9000 9001 41264)
|
||||
NETWORK_FIREWALL_UDP_PORTS=(4443 51822 51264)
|
||||
NETWORK_FIREWALL_WG_TCP_PORT=51830
|
||||
|
||||
validate_port_value() {
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
|
||||
if ! [[ "$value" =~ ^[0-9]+$ ]] || (( 10#$value < 1 || 10#$value > 65535 )); then
|
||||
error "invalid ${name}='${value}'. expected integer 1-65535"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_port_value "HOST_SSH_PORT" "$HOST_SSH_PORT"
|
||||
|
||||
build_network_firewall_status_pattern() {
|
||||
local patterns=("$NETWORK_FIREWALL_COMMENT")
|
||||
local port
|
||||
|
||||
for port in "${NETWORK_FIREWALL_TCP_PORTS[@]}" "${NETWORK_FIREWALL_UDP_PORTS[@]}" "$NETWORK_FIREWALL_WG_TCP_PORT"; do
|
||||
patterns+=("dpt:${port}")
|
||||
done
|
||||
|
||||
local IFS='|'
|
||||
printf '%s' "${patterns[*]}"
|
||||
}
|
||||
|
||||
delete_managed_input_rules() {
|
||||
local cmd="$1"
|
||||
@@ -554,22 +621,19 @@ configure_network_firewall() {
|
||||
delete_managed_input_rules iptables
|
||||
delete_managed_input_rules ip6tables
|
||||
|
||||
local tcp_ports=(22 80 443 1789 1790 8080 9000 9001 41264)
|
||||
local udp_ports=(4443 51822 51264)
|
||||
|
||||
local port
|
||||
for port in "${tcp_ports[@]}"; do
|
||||
for port in "${NETWORK_FIREWALL_TCP_PORTS[@]}"; do
|
||||
add_input_port_rule iptables "$port" tcp
|
||||
add_input_port_rule ip6tables "$port" tcp
|
||||
done
|
||||
|
||||
for port in "${udp_ports[@]}"; do
|
||||
for port in "${NETWORK_FIREWALL_UDP_PORTS[@]}"; do
|
||||
add_input_port_rule iptables "$port" udp
|
||||
add_input_port_rule ip6tables "$port" udp
|
||||
done
|
||||
|
||||
add_input_port_rule iptables 51830 tcp "$WG_INTERFACE"
|
||||
add_input_port_rule ip6tables 51830 tcp "$WG_INTERFACE"
|
||||
add_input_port_rule iptables "$NETWORK_FIREWALL_WG_TCP_PORT" tcp "$WG_INTERFACE"
|
||||
add_input_port_rule ip6tables "$NETWORK_FIREWALL_WG_TCP_PORT" tcp "$WG_INTERFACE"
|
||||
|
||||
save_iptables_rules
|
||||
ok "host network firewall configuration completed"
|
||||
@@ -577,23 +641,25 @@ configure_network_firewall() {
|
||||
|
||||
show_network_firewall_status() {
|
||||
info "managed host network firewall rules"
|
||||
local status_pattern
|
||||
|
||||
status_pattern="$(build_network_firewall_status_pattern)"
|
||||
|
||||
echo
|
||||
info "ipv4 input rules:"
|
||||
iptables -L INPUT -n -v --line-numbers | grep -E "($NETWORK_FIREWALL_COMMENT|dpt:22|dpt:80|dpt:443|dpt:1789|dpt:1790|dpt:8080|dpt:9000|dpt:9001|dpt:51822|dpt:51830|dpt:41264|dpt:51264)" || true
|
||||
iptables -L INPUT -n -v --line-numbers | grep -E "(${status_pattern})" || true
|
||||
echo
|
||||
info "ipv6 input rules:"
|
||||
ip6tables -L INPUT -n -v --line-numbers | grep -E "($NETWORK_FIREWALL_COMMENT|dpt:22|dpt:80|dpt:443|dpt:1789|dpt:1790|dpt:8080|dpt:9000|dpt:9001|dpt:51822|dpt:51830|dpt:41264|dpt:51264)" || true
|
||||
ip6tables -L INPUT -n -v --line-numbers | grep -E "(${status_pattern})" || true
|
||||
}
|
||||
|
||||
test_network_firewall_rules() {
|
||||
info "testing host network firewall rules"
|
||||
|
||||
local failures=0
|
||||
local tcp_ports=(22 80 443 1789 1790 8080 9000 9001 41264)
|
||||
local udp_ports=(51822 51264)
|
||||
local port
|
||||
|
||||
for port in "${tcp_ports[@]}"; do
|
||||
for port in "${NETWORK_FIREWALL_TCP_PORTS[@]}"; do
|
||||
if iptables -C INPUT -p tcp --dport "$port" -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 tcp port $port allowed"
|
||||
else
|
||||
@@ -609,7 +675,7 @@ test_network_firewall_rules() {
|
||||
fi
|
||||
done
|
||||
|
||||
for port in "${udp_ports[@]}"; do
|
||||
for port in "${NETWORK_FIREWALL_UDP_PORTS[@]}"; do
|
||||
if iptables -C INPUT -p udp --dport "$port" -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 udp port $port allowed"
|
||||
else
|
||||
@@ -625,17 +691,17 @@ test_network_firewall_rules() {
|
||||
fi
|
||||
done
|
||||
|
||||
if iptables -C INPUT -i "$WG_INTERFACE" -p tcp --dport 51830 -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 tcp port 51830 allowed on $WG_INTERFACE"
|
||||
if iptables -C INPUT -i "$WG_INTERFACE" -p tcp --dport "$NETWORK_FIREWALL_WG_TCP_PORT" -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 tcp port $NETWORK_FIREWALL_WG_TCP_PORT allowed on $WG_INTERFACE"
|
||||
else
|
||||
error "ipv4 tcp port 51830 missing on $WG_INTERFACE"
|
||||
error "ipv4 tcp port $NETWORK_FIREWALL_WG_TCP_PORT missing on $WG_INTERFACE"
|
||||
((failures++))
|
||||
fi
|
||||
|
||||
if ip6tables -C INPUT -i "$WG_INTERFACE" -p tcp --dport 51830 -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv6 tcp port 51830 allowed on $WG_INTERFACE"
|
||||
if ip6tables -C INPUT -i "$WG_INTERFACE" -p tcp --dport "$NETWORK_FIREWALL_WG_TCP_PORT" -m conntrack --ctstate NEW -m comment --comment "$NETWORK_FIREWALL_COMMENT" -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv6 tcp port $NETWORK_FIREWALL_WG_TCP_PORT allowed on $WG_INTERFACE"
|
||||
else
|
||||
error "ipv6 tcp port 51830 missing on $WG_INTERFACE"
|
||||
error "ipv6 tcp port $NETWORK_FIREWALL_WG_TCP_PORT missing on $WG_INTERFACE"
|
||||
((failures++))
|
||||
fi
|
||||
|
||||
@@ -708,38 +774,50 @@ create_nym_chain() {
|
||||
done < <(ip6tables -S FORWARD | grep -F " -j $NYM_CHAIN" || true)
|
||||
|
||||
# remove broad ACCEPT rules for wg + tun outbound so NYM-EXIT is authoritative
|
||||
iptables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V4" -j ACCEPT 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V4" -j ACCEPT 2>/dev/null || true
|
||||
if has_ipv6_uplink; then
|
||||
ip6tables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V6" -j ACCEPT 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V6" -j ACCEPT 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# install the correct hook for both wg + tun
|
||||
iptables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN"
|
||||
iptables -I FORWARD 1 -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN"
|
||||
iptables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN"
|
||||
iptables -I FORWARD 1 -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN"
|
||||
|
||||
ip6tables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN"
|
||||
ip6tables -I FORWARD 1 -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN"
|
||||
|
||||
ok "NYM-EXIT chain ready + FORWARD hooks installed for $WG_INTERFACE and $TUNNEL_INTERFACE"
|
||||
if has_ipv6_uplink; then
|
||||
ip6tables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN"
|
||||
ip6tables -I FORWARD 1 -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN"
|
||||
ok "NYM-EXIT chain ready + IPv4/IPv6 FORWARD hooks installed for $WG_INTERFACE and $TUNNEL_INTERFACE"
|
||||
else
|
||||
warn "no ipv6 uplink detected; installing only IPv4 FORWARD hooks for $WG_INTERFACE and $TUNNEL_INTERFACE"
|
||||
ok "NYM-EXIT chain ready + IPv4 FORWARD hooks installed for $WG_INTERFACE and $TUNNEL_INTERFACE"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
setup_nat_rules() {
|
||||
info "setting up nat and forwarding rules for $WG_INTERFACE via $NETWORK_DEVICE"
|
||||
info "setting up nat and forwarding rules for $WG_INTERFACE via ipv4 uplink $NETWORK_DEVICE_V4${NETWORK_DEVICE_V6:+ and ipv6 uplink $NETWORK_DEVICE_V6}"
|
||||
|
||||
if ! iptables -t nat -C POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE 2>/dev/null; then
|
||||
iptables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
|
||||
if ! iptables -t nat -C POSTROUTING -o "$NETWORK_DEVICE_V4" -j MASQUERADE 2>/dev/null; then
|
||||
iptables -t nat -A POSTROUTING -o "$NETWORK_DEVICE_V4" -j MASQUERADE
|
||||
fi
|
||||
if ! ip6tables -t nat -C POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE 2>/dev/null; then
|
||||
ip6tables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
|
||||
if has_ipv6_uplink; then
|
||||
if ! ip6tables -t nat -C POSTROUTING -o "$NETWORK_DEVICE_V6" -j MASQUERADE 2>/dev/null; then
|
||||
ip6tables -t nat -A POSTROUTING -o "$NETWORK_DEVICE_V6" -j MASQUERADE
|
||||
fi
|
||||
else
|
||||
warn "no ipv6 uplink detected; skipping ipv6 NAT setup for $WG_INTERFACE"
|
||||
fi
|
||||
|
||||
# keep reverse RELATED,ESTABLISHED in FORWARD for return traffic.
|
||||
if ! iptables -C FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
iptables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
if ! iptables -C FORWARD -i "$NETWORK_DEVICE_V4" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
iptables -I FORWARD 2 -i "$NETWORK_DEVICE_V4" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
fi
|
||||
if ! ip6tables -C FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
if has_ipv6_uplink; then
|
||||
if ! ip6tables -C FORWARD -i "$NETWORK_DEVICE_V6" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE_V6" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -980,10 +1058,12 @@ clear_exit_policy_rules() {
|
||||
ip6tables -F "$NYM_CHAIN" 2>/dev/null || true
|
||||
|
||||
# remove hooks for BOTH wg + tun
|
||||
iptables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
iptables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
if has_ipv6_uplink; then
|
||||
ip6tables -D FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
ip6tables -D FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
iptables -X "$NYM_CHAIN" 2>/dev/null || true
|
||||
ip6tables -X "$NYM_CHAIN" 2>/dev/null || true
|
||||
@@ -991,7 +1071,12 @@ clear_exit_policy_rules() {
|
||||
|
||||
show_exit_policy_status() {
|
||||
info "nym exit policy status"
|
||||
info "network device: $NETWORK_DEVICE"
|
||||
info "ipv4 network device: $NETWORK_DEVICE_V4"
|
||||
if has_ipv6_uplink; then
|
||||
info "ipv6 network device: $NETWORK_DEVICE_V6"
|
||||
else
|
||||
warn "ipv6 network device: not detected"
|
||||
fi
|
||||
info "wireguard interface: $WG_INTERFACE"
|
||||
info "tunnel interface: $TUNNEL_INTERFACE"
|
||||
echo
|
||||
@@ -1092,21 +1177,71 @@ firewall_rule_line() {
|
||||
}
|
||||
|
||||
check_forward_chain() {
|
||||
local output
|
||||
output=$(iptables -L FORWARD -n --line-numbers)
|
||||
local errors=0
|
||||
|
||||
if ! echo "$output" | grep -q "^1[[:space:]]\+$NYM_CHAIN"; then
|
||||
error "FORWARD rule 1 is not ${NYM_CHAIN}; re-run network-tunnel-manager.sh exit_policy_install"
|
||||
return 1
|
||||
info "checking FORWARD hooks and reverse RELATED,ESTABLISHED rules"
|
||||
|
||||
if iptables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 FORWARD hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv4 FORWARD hook missing (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if ! echo "$output" | grep -q "ACCEPT.*state RELATED,ESTABLISHED"; then
|
||||
error "FORWARD chain missing RELATED,ESTABLISHED accepts; re-run network-tunnel-manager.sh apply_iptables_rules_wg"
|
||||
return 1
|
||||
if iptables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 FORWARD hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv4 FORWARD hook missing (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
ok "FORWARD chain ordering looks good"
|
||||
return 0
|
||||
if iptables -C FORWARD -i "$NETWORK_DEVICE_V4" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 reverse RELATED,ESTABLISHED ok (wg): -i $NETWORK_DEVICE_V4 -o $WG_INTERFACE"
|
||||
else
|
||||
error "ipv4 reverse RELATED,ESTABLISHED missing (wg): -i $NETWORK_DEVICE_V4 -o $WG_INTERFACE"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if iptables -C FORWARD -i "$NETWORK_DEVICE_V4" -o "$TUNNEL_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv4 reverse RELATED,ESTABLISHED ok (tun): -i $NETWORK_DEVICE_V4 -o $TUNNEL_INTERFACE"
|
||||
else
|
||||
error "ipv4 reverse RELATED,ESTABLISHED missing (tun): -i $NETWORK_DEVICE_V4 -o $TUNNEL_INTERFACE"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if has_ipv6_uplink; then
|
||||
if ip6tables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 FORWARD hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv6 FORWARD hook missing (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if ip6tables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 FORWARD hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv6 FORWARD hook missing (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if ip6tables -C FORWARD -i "$NETWORK_DEVICE_V6" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv6 reverse RELATED,ESTABLISHED ok (wg): -i $NETWORK_DEVICE_V6 -o $WG_INTERFACE"
|
||||
else
|
||||
error "ipv6 reverse RELATED,ESTABLISHED missing (wg): -i $NETWORK_DEVICE_V6 -o $WG_INTERFACE"
|
||||
errors=1
|
||||
fi
|
||||
|
||||
if ip6tables -C FORWARD -i "$NETWORK_DEVICE_V6" -o "$TUNNEL_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
||||
ok "ipv6 reverse RELATED,ESTABLISHED ok (tun): -i $NETWORK_DEVICE_V6 -o $TUNNEL_INTERFACE"
|
||||
else
|
||||
error "ipv6 reverse RELATED,ESTABLISHED missing (tun): -i $NETWORK_DEVICE_V6 -o $TUNNEL_INTERFACE"
|
||||
errors=1
|
||||
fi
|
||||
else
|
||||
warn "no ipv6 uplink detected; skipping ipv6 FORWARD validation"
|
||||
fi
|
||||
|
||||
return $errors
|
||||
}
|
||||
|
||||
check_nym_exit_chain() {
|
||||
@@ -1288,33 +1423,37 @@ test_forward_chain_hook() {
|
||||
|
||||
local failures=0
|
||||
|
||||
# verify BOTH interfaces are hooked to NYM-EXIT (IPv4 + IPv6)
|
||||
if iptables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 forward hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE -> $NYM_CHAIN"
|
||||
# verify BOTH interfaces are hooked to NYM-EXIT for IPv4
|
||||
if iptables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 forward hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv4 forward hook missing or wrong (wg)"
|
||||
((failures++))
|
||||
fi
|
||||
|
||||
if iptables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 forward hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE -> $NYM_CHAIN"
|
||||
if iptables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V4" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv4 forward hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V4 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv4 forward hook missing or wrong (tun)"
|
||||
((failures++))
|
||||
fi
|
||||
|
||||
if ip6tables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 forward hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv6 forward hook missing or wrong (wg)"
|
||||
((failures++))
|
||||
fi
|
||||
if has_ipv6_uplink; then
|
||||
if ip6tables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 forward hook ok (wg): -i $WG_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv6 forward hook missing or wrong (wg)"
|
||||
((failures++))
|
||||
fi
|
||||
|
||||
if ip6tables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 forward hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE -> $NYM_CHAIN"
|
||||
if ip6tables -C FORWARD -i "$TUNNEL_INTERFACE" -o "$NETWORK_DEVICE_V6" -j "$NYM_CHAIN" 2>/dev/null; then
|
||||
ok "ipv6 forward hook ok (tun): -i $TUNNEL_INTERFACE -o $NETWORK_DEVICE_V6 -> $NYM_CHAIN"
|
||||
else
|
||||
error "ipv6 forward hook missing or wrong (tun)"
|
||||
((failures++))
|
||||
fi
|
||||
else
|
||||
error "ipv6 forward hook missing or wrong (tun)"
|
||||
((failures++))
|
||||
warn "no ipv6 uplink detected; skipping ipv6 forward hook tests"
|
||||
fi
|
||||
|
||||
return "$failures"
|
||||
@@ -1409,7 +1548,7 @@ nym_tunnel_setup() {
|
||||
}
|
||||
|
||||
exit_policy_install() {
|
||||
info "installing nym wireguard exit policy for ${WG_INTERFACE} via ${NETWORK_DEVICE}"
|
||||
info "installing nym wireguard exit policy for ${WG_INTERFACE} via ipv4 uplink ${NETWORK_DEVICE_V4}${NETWORK_DEVICE_V6:+ and ipv6 uplink ${NETWORK_DEVICE_V6}}"
|
||||
exit_policy_install_deps
|
||||
adjust_ip_forwarding
|
||||
create_nym_chain
|
||||
@@ -1561,7 +1700,7 @@ tunnel and nat helpers:
|
||||
check_nym_wg_tun Inspect forward chain for ${WG_INTERFACE}
|
||||
check_nymtun_iptables Inspect forward chain for ${TUNNEL_INTERFACE}
|
||||
configure_dns_and_icmp_wg Allow ping and dns ports on this host
|
||||
fetch_and_display_ipv6 Show ipv6 on uplink ${NETWORK_DEVICE}
|
||||
fetch_and_display_ipv6 Show ipv6 on uplink ${NETWORK_DEVICE_V6:-<none>}
|
||||
fetch_ipv6_address_nym_tun Show global ipv6 address on ${TUNNEL_INTERFACE}
|
||||
joke_through_the_mixnet Test via ${TUNNEL_INTERFACE} with joke
|
||||
joke_through_wg_tunnel Test via ${WG_INTERFACE} with joke
|
||||
@@ -1578,9 +1717,12 @@ exit policy manager:
|
||||
Run verification tests on exit policy (options: --skip-default-reject).
|
||||
|
||||
environment overrides:
|
||||
NETWORK_DEVICE Auto-detected uplink (e.g., eth0). Set manually if detection fails.
|
||||
NETWORK_DEVICE Backward-compatible override that sets both uplinks.
|
||||
NETWORK_DEVICE_V4 Auto-detected IPv4 uplink (e.g., eth0). Set manually if detection fails.
|
||||
NETWORK_DEVICE_V6 Auto-detected IPv6 uplink (e.g., eth2). Optional; if unset, IPv6-specific setup is skipped.
|
||||
TUNNEL_INTERFACE Default: nymtun0. Requires root privileges (sudo) to manage.
|
||||
WG_INTERFACE Default: nymwg - Must match your WireGuard interface name.
|
||||
HOST_SSH_PORT Default: 22. Set manually if you connect to your host's SSH daemon through another port.
|
||||
|
||||
EOF
|
||||
status=0
|
||||
|
||||
@@ -68,23 +68,60 @@ class NodeSetupCLI:
|
||||
print("Without confirming the points above, we cannot continue.")
|
||||
exit(1)
|
||||
|
||||
def _coerce_ssh_port(self, value) -> str:
|
||||
sval = str(value).strip() if value is not None else ""
|
||||
if not sval:
|
||||
sval = "22"
|
||||
if not sval.isdigit():
|
||||
print(f"Invalid SSH port: {sval!r}. Expected integer 1..65535.")
|
||||
raise SystemExit(1)
|
||||
port = int(sval, 10)
|
||||
if not 1 <= port <= 65535:
|
||||
print(f"Invalid SSH port: {port}. Expected integer 1..65535.")
|
||||
raise SystemExit(1)
|
||||
return str(port)
|
||||
|
||||
def _resolve_field(args, existing, arg_name, env_key, prompt, *, default=None, validator=None):
|
||||
cli_val = getattr(args, arg_name, None)
|
||||
|
||||
if cli_val is not None:
|
||||
value = str(cli_val).strip()
|
||||
elif existing.get(env_key):
|
||||
value = str(existing[env_key]).strip()
|
||||
else:
|
||||
entered = input(prompt).strip()
|
||||
value = entered if entered else (default if default is not None else "")
|
||||
|
||||
if validator:
|
||||
value = validator(value)
|
||||
|
||||
return value
|
||||
|
||||
def ensure_env_values(self, args):
|
||||
"""Collect env vars from args or prompt interactively, then save to env.sh."""
|
||||
env_file = Path("env.sh")
|
||||
fields = [
|
||||
("hostname", "HOSTNAME", "Enter hostname (if you don't use a DNS, press enter): "),
|
||||
("location", "LOCATION", "Enter node location (country code or name): "),
|
||||
("email", "EMAIL", "Enter your email: "),
|
||||
("moniker", "MONIKER", "Enter node public moniker (visible in explorer & NymVPN app): "),
|
||||
("description", "DESCRIPTION", "Enter short node public description: "),
|
||||
("hostname", "HOSTNAME", "Enter hostname (if you don't use a DNS, press enter): ", None, None),
|
||||
("location", "LOCATION", "Enter node location (country code or name): ", None, None),
|
||||
("email", "EMAIL", "Enter your email: ", None, None),
|
||||
("moniker", "MONIKER", "Enter node public moniker (visible in explorer & NymVPN app): ", None, None),
|
||||
("description", "DESCRIPTION", "Enter short node public description: ", None, None),
|
||||
("host_ssh_port", "HOST_SSH_PORT", "Enter host SSH port (press enter for default port 22): ", "22", self._coerce_ssh_port),
|
||||
]
|
||||
|
||||
existing = self._read_env_file(env_file)
|
||||
updated = {}
|
||||
|
||||
for arg_name, key, prompt in fields:
|
||||
cli_val = getattr(args, arg_name, None)
|
||||
value = cli_val.strip() if cli_val else existing.get(key) or input(prompt).strip()
|
||||
for arg_name, key, prompt, default, validator in fields:
|
||||
value = self._resolve_field(
|
||||
args,
|
||||
existing,
|
||||
arg_name,
|
||||
key,
|
||||
prompt,
|
||||
default=default,
|
||||
validator=validator,
|
||||
)
|
||||
updated[key] = value
|
||||
os.environ[key] = value
|
||||
|
||||
@@ -639,6 +676,13 @@ class ArgParser:
|
||||
install_parser.add_argument("--moniker", help="Public moniker displayed in explorer & NymVPN app")
|
||||
install_parser.add_argument("--description", help="Short public description of the node")
|
||||
install_parser.add_argument("--public-ip", help="External IPv4 address (autodetected if omitted)")
|
||||
|
||||
install_parser.add_argument(
|
||||
"--host-ssh-port",
|
||||
type=int,
|
||||
help="Host SSH port to allow in the firewall (default: 22)",
|
||||
)
|
||||
|
||||
install_parser.add_argument("--nym-node-binary", help="URL for nym-node binary (autodetected if omitted)")
|
||||
install_parser.add_argument("--uplink-dev", help="Override uplink interface used for NAT/FORWARD (e.g., 'eth0'; autodetected if omitted)")
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ while true; do
|
||||
read -rp "Enter your email: " EMAIL
|
||||
read -rp "Enter node public moniker (visible in the explorer and NymVPN app): " MONIKER
|
||||
read -rp "Enter node public description: " DESCRIPTION
|
||||
read -rp "Enter host SSH port (press enter for default port 22): " HOST_SSH_PORT
|
||||
HOST_SSH_PORT="${HOST_SSH_PORT:-22}"
|
||||
|
||||
# show summary table
|
||||
echo -e "\nPlease confirm the values you entered:"
|
||||
@@ -28,6 +30,7 @@ while true; do
|
||||
printf "%-20s %s\n" "EMAIL:" "$EMAIL"
|
||||
printf "%-20s %s\n" "MONIKER:" "$MONIKER"
|
||||
printf "%-20s %s\n" "DESCRIPTION:" "$DESCRIPTION"
|
||||
printf "%-20s %s\n" "HOST_SSH_PORT:" "$HOST_SSH_PORT"
|
||||
echo "---------------------------------------"
|
||||
|
||||
read -rp "Are these correct? (y/n): " CONFIRM
|
||||
@@ -52,6 +55,7 @@ PUBLIC_IP=${PUBLIC_IP:-""}
|
||||
echo "export MONIKER=\"${MONIKER}\""
|
||||
echo "export DESCRIPTION=\"${DESCRIPTION}\""
|
||||
echo "export PUBLIC_IP=\"${PUBLIC_IP}\""
|
||||
echo "export HOST_SSH_PORT=\"${HOST_SSH_PORT}\""
|
||||
} > env.sh
|
||||
|
||||
echo -e "\nVariables saved to ./env.sh"
|
||||
|
||||
@@ -133,8 +133,7 @@ impl VersionedResponse {
|
||||
ClientVersion::V9 => {
|
||||
let mut resp = IpPacketResponseV8::try_from(self)?;
|
||||
resp.version = nym_ip_packet_requests::v9::VERSION;
|
||||
let bytes = resp.to_bytes();
|
||||
bytes
|
||||
resp.to_bytes()
|
||||
}
|
||||
}
|
||||
.map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err })
|
||||
|
||||
Reference in New Issue
Block a user