Compare commits

...

6 Commits

Author SHA1 Message Date
Sachin Kamath 97c707d450 docs: simplify wss 2024-09-13 17:04:52 +05:30
import this bded491884 update known errors and bugs 2024-09-12 16:51:41 +00:00
import this e36e4eef1e update proxy setup syntax 2024-09-12 15:27:15 +00:00
Bogdan-Ștefan Neacşu 47303bcf48 Gateway database modifications for different modes (#4868)
* Gateway db modifications for different modes

* Add exit mixnet and replace whitespaces
2024-09-12 11:58:20 +02:00
Jon Häggblad 60917ec9e7 Remove the push trigger for ci-nym-wallet-rust (#4869) 2024-09-12 10:23:00 +02:00
dependabot[bot] f616b3c15a build(deps): bump strum from 0.25.0 to 0.26.3 (#4848)
* build(deps): bump strum from 0.25.0 to 0.26.3

Bumps [strum](https://github.com/Peternator7/strum) from 0.25.0 to 0.26.3.
- [Release notes](https://github.com/Peternator7/strum/releases)
- [Changelog](https://github.com/Peternator7/strum/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Peternator7/strum/commits/v0.26.3)

---
updated-dependencies:
- dependency-name: strum
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update to handle deprecation error

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2024-09-11 23:18:11 +02:00
13 changed files with 336 additions and 418 deletions
-7
View File
@@ -1,13 +1,6 @@
name: ci-nym-wallet-rust
on:
push:
paths:
- 'nym-wallet/**'
- 'common/**'
- 'contracts/vesting/**'
- 'nym-api/nym-api-requests/**'
- '.github/workflows/ci-nym-wallet-rust.yml'
pull_request:
paths:
- 'nym-wallet/**'
Generated
+5 -24
View File
@@ -4910,7 +4910,7 @@ dependencies = [
"nym-network-defaults",
"rand",
"serde",
"strum 0.25.0",
"strum 0.26.3",
"thiserror",
"time",
]
@@ -6186,7 +6186,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.8",
"strum 0.25.0",
"strum 0.26.3",
"tempfile",
"thiserror",
"ts-rs",
@@ -8576,20 +8576,14 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros 0.25.3",
]
[[package]]
name = "strum"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [
"strum_macros 0.26.4",
]
[[package]]
name = "strum_macros"
@@ -8617,19 +8611,6 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.66",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
+1 -1
View File
@@ -288,7 +288,7 @@ sha2 = "0.10.8"
si-scale = "0.2.3"
sphinx-packet = "0.1.1"
sqlx = "0.6.3"
strum = "0.25"
strum = "0.26"
subtle-encoding = "0.5"
syn = "1"
sysinfo = "0.30.12"
@@ -0,0 +1,98 @@
/*
* Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
* SPDX-License-Identifier: Apache-2.0
*/
CREATE TABLE clients (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
client_type TEXT NOT NULL CHECK(client_type IN ('entry_mixnet', 'exit_mixnet', 'entry_wireguard', 'exit_wireguard'))
);
INSERT INTO clients (id, client_type)
SELECT id, 'entry_mixnet'
FROM shared_keys;
CREATE TABLE shared_keys_tmp (
client_id INTEGER NOT NULL PRIMARY KEY REFERENCES clients(id),
client_address_bs58 TEXT NOT NULL UNIQUE,
derived_aes128_ctr_blake3_hmac_keys_bs58 TEXT NOT NULL
);
INSERT INTO shared_keys_tmp (client_id, client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58)
SELECT id as client_id, client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58 FROM shared_keys;
CREATE TABLE available_bandwidth_tmp (
client_id INTEGER NOT NULL PRIMARY KEY REFERENCES clients(id),
available INTEGER NOT NULL,
expiration TIMESTAMP WITHOUT TIME ZONE
);
INSERT INTO available_bandwidth_tmp
SELECT * FROM available_bandwidth;
DROP TABLE available_bandwidth;
ALTER TABLE available_bandwidth_tmp RENAME TO available_bandwidth;
CREATE TABLE received_ticket_tmp (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
client_id INTEGER NOT NULL REFERENCES clients(id),
received_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
rejected BOOLEAN
);
INSERT INTO received_ticket_tmp
SELECT * FROM received_ticket;
DROP INDEX received_ticket_index;
CREATE INDEX received_ticket_index ON received_ticket_tmp (received_at);
-- received tickets that are in the process of verifying
CREATE TABLE ticket_data_tmp (
ticket_id INTEGER NOT NULL PRIMARY KEY REFERENCES received_ticket_tmp(id),
-- serial_number, alongside the entire row, will get purged after redemption is complete
serial_number BLOB NOT NULL UNIQUE,
-- data will get purged after 80% of signers verifies it
data BLOB
);
INSERT INTO ticket_data_tmp
SELECT * FROM ticket_data;
DROP TABLE ticket_data;
ALTER TABLE ticket_data_tmp RENAME TO ticket_data;
-- result of a verification from a single signer (API)
CREATE TABLE ticket_verification_tmp (
ticket_id INTEGER NOT NULL REFERENCES received_ticket_tmp(id),
signer_id INTEGER NOT NULL,
verified_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
accepted BOOLEAN NOT NULL,
PRIMARY KEY (ticket_id, signer_id)
);
DROP INDEX ticket_verification_index;
CREATE INDEX ticket_verification_index ON ticket_verification_tmp (ticket_id);
DROP TABLE ticket_verification;
ALTER TABLE ticket_verification_tmp RENAME TO ticket_verification;
-- verified tickets that are yet to be redeemed
CREATE TABLE verified_tickets_tmp (
ticket_id INTEGER NOT NULL PRIMARY KEY REFERENCES received_ticket_tmp(id),
proposal_id INTEGER REFERENCES redemption_proposals(proposal_id)
);
DROP INDEX verified_tickets_index;
CREATE INDEX verified_tickets_index ON verified_tickets_tmp (proposal_id);
DROP TABLE verified_tickets;
ALTER TABLE verified_tickets_tmp RENAME TO verified_tickets;
DROP TABLE received_ticket;
ALTER TABLE received_ticket_tmp RENAME TO received_ticket;
DROP TABLE shared_keys;
ALTER TABLE shared_keys_tmp RENAME TO shared_keys;
+89
View File
@@ -0,0 +1,89 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use std::str::FromStr;
use crate::models::Client;
#[derive(Debug, PartialEq, sqlx::Type)]
#[sqlx(type_name = "TEXT")] // SQLite TEXT type
pub enum ClientType {
EntryMixnet,
ExitMixnet,
EntryWireguard,
ExitWireguard,
}
impl FromStr for ClientType {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"entry_mixnet" => Ok(ClientType::EntryMixnet),
"exit_mixnet" => Ok(ClientType::ExitMixnet),
"entry_wireguard" => Ok(ClientType::EntryWireguard),
"exit_wireguard" => Ok(ClientType::ExitWireguard),
_ => Err("Invalid client type"),
}
}
}
impl std::fmt::Display for ClientType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
ClientType::EntryMixnet => "entry_mixnet",
ClientType::ExitMixnet => "exit_mixnet",
ClientType::EntryWireguard => "entry_wireguard",
ClientType::ExitWireguard => "exit_wireguard",
};
write!(f, "{}", s)
}
}
#[derive(Clone)]
pub(crate) struct ClientManager {
connection_pool: sqlx::SqlitePool,
}
impl ClientManager {
/// Creates new instance of the `ClientManager` with the provided sqlite connection pool.
///
/// # Arguments
///
/// * `connection_pool`: database connection pool to use.
pub(crate) fn new(connection_pool: sqlx::SqlitePool) -> Self {
ClientManager { connection_pool }
}
/// Inserts new client to the storage, specifying its type.
///
/// # Arguments
///
/// * `client_type`: Type of the client that gets inserted
pub(crate) async fn insert_client(&self, client_type: ClientType) -> Result<i64, sqlx::Error> {
let client_id = sqlx::query!("INSERT INTO clients(client_type) VALUES (?)", client_type)
.execute(&self.connection_pool)
.await?
.last_insert_rowid();
Ok(client_id)
}
/// Tries to retrieve a particular client.
///
/// # Arguments
///
/// * `id`: The client id
pub(crate) async fn get_client(&self, id: i64) -> Result<Option<Client>, sqlx::Error> {
sqlx::query_as!(
Client,
r#"
SELECT id, client_type as "client_type: ClientType"
FROM clients
WHERE id = ?
"#,
id
)
.fetch_optional(&self.connection_pool)
.await
}
}
+27 -6
View File
@@ -3,11 +3,12 @@
use async_trait::async_trait;
use bandwidth::BandwidthManager;
use clients::{ClientManager, ClientType};
use error::StorageError;
use inboxes::InboxManager;
use models::{
PersistedBandwidth, PersistedSharedKeys, RedemptionProposal, StoredMessage, VerifiedTicket,
WireguardPeer,
Client, PersistedBandwidth, PersistedSharedKeys, RedemptionProposal, StoredMessage,
VerifiedTicket, WireguardPeer,
};
use nym_credentials_interface::ClientTicket;
use nym_gateway_requests::registration::handshake::SharedKeys;
@@ -20,6 +21,7 @@ use time::OffsetDateTime;
use tracing::{debug, error};
pub mod bandwidth;
mod clients;
pub mod error;
mod inboxes;
pub mod models;
@@ -29,7 +31,7 @@ mod wireguard_peers;
#[async_trait]
pub trait Storage: Send + Sync {
async fn get_client_id(
async fn get_mixnet_client_id(
&self,
client_address: DestinationAddressBytes,
) -> Result<i64, StorageError>;
@@ -39,7 +41,7 @@ pub trait Storage: Send + Sync {
///
/// # Arguments
///
/// * `client_address`: address of the client
/// * `client_address`: base58-encoded address of the client
/// * `shared_keys`: shared encryption (AES128CTR) and mac (hmac-blake3) derived shared keys to store.
async fn insert_shared_keys(
&self,
@@ -70,6 +72,14 @@ pub trait Storage: Send + Sync {
client_address: DestinationAddressBytes,
) -> Result<(), StorageError>;
/// Tries to retrieve a particular client.
///
/// # Arguments
///
/// * `client_id`: id of the client
#[allow(dead_code)]
async fn get_client(&self, client_id: i64) -> Result<Option<Client>, StorageError>;
/// Inserts new message to the storage for an offline client for future retrieval.
///
/// # Arguments
@@ -246,6 +256,7 @@ pub trait Storage: Send + Sync {
// note that clone here is fine as upon cloning the same underlying pool will be used
#[derive(Clone)]
pub struct PersistentStorage {
client_manager: ClientManager,
shared_key_manager: SharedKeysManager,
inbox_manager: InboxManager,
bandwidth_manager: BandwidthManager,
@@ -294,6 +305,7 @@ impl PersistentStorage {
// the cloning here are cheap as connection pool is stored behind an Arc
Ok(PersistentStorage {
client_manager: clients::ClientManager::new(connection_pool.clone()),
wireguard_peer_manager: wireguard_peers::WgPeerManager::new(connection_pool.clone()),
shared_key_manager: SharedKeysManager::new(connection_pool.clone()),
inbox_manager: InboxManager::new(connection_pool.clone(), message_retrieval_limit),
@@ -305,7 +317,7 @@ impl PersistentStorage {
#[async_trait]
impl Storage for PersistentStorage {
async fn get_client_id(
async fn get_mixnet_client_id(
&self,
client_address: DestinationAddressBytes,
) -> Result<i64, StorageError> {
@@ -321,8 +333,12 @@ impl Storage for PersistentStorage {
shared_keys: &SharedKeys,
) -> Result<i64, StorageError> {
let client_id = self
.shared_key_manager
.client_manager
.insert_client(ClientType::EntryMixnet)
.await?;
self.shared_key_manager
.insert_shared_keys(
client_id,
client_address.as_base58_string(),
shared_keys.to_base58_string(),
)
@@ -352,6 +368,11 @@ impl Storage for PersistentStorage {
Ok(())
}
async fn get_client(&self, client_id: i64) -> Result<Option<Client>, StorageError> {
let client = self.client_manager.get_client(client_id).await?;
Ok(client)
}
async fn store_message(
&self,
client_address: DestinationAddressBytes,
+6 -1
View File
@@ -6,9 +6,14 @@ use nym_credentials_interface::{AvailableBandwidth, ClientTicket, CredentialSpen
use sqlx::FromRow;
use time::OffsetDateTime;
pub struct Client {
pub id: i64,
pub client_type: crate::clients::ClientType,
}
pub struct PersistedSharedKeys {
#[allow(dead_code)]
pub id: i64,
pub client_id: i64,
#[allow(dead_code)]
pub client_address_bs58: String,
+10 -6
View File
@@ -20,12 +20,12 @@ impl SharedKeysManager {
pub(crate) async fn client_id(&self, client_address_bs58: &str) -> Result<i64, sqlx::Error> {
let client_id = sqlx::query!(
"SELECT id FROM shared_keys WHERE client_address_bs58 = ?",
"SELECT client_id FROM shared_keys WHERE client_address_bs58 = ?",
client_address_bs58
)
.fetch_one(&self.connection_pool)
.await?
.id;
.client_id;
Ok(client_id)
}
@@ -34,26 +34,30 @@ impl SharedKeysManager {
///
/// # Arguments
///
/// * `shared_keys`: shared encryption (AES128CTR) and mac (hmac-blake3) derived shared keys to store.
/// * `client_id`: The client id for which the shared keys are stored
/// * `client_address_bs58`: base58-encoded address of the client
/// * `derived_aes128_ctr_blake3_hmac_keys_bs58`: shared encryption (AES128CTR) and mac (hmac-blake3) derived shared keys to store.
pub(crate) async fn insert_shared_keys(
&self,
client_id: i64,
client_address_bs58: String,
derived_aes128_ctr_blake3_hmac_keys_bs58: String,
) -> Result<i64, sqlx::Error> {
) -> Result<(), sqlx::Error> {
// https://stackoverflow.com/a/20310838
// we don't want to be using `INSERT OR REPLACE INTO` due to the foreign key on `available_bandwidth` if the entry already exists
sqlx::query!(
r#"
INSERT OR IGNORE INTO shared_keys(client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58) VALUES (?, ?);
INSERT OR IGNORE INTO shared_keys(client_id, client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58) VALUES (?, ?, ?);
UPDATE shared_keys SET derived_aes128_ctr_blake3_hmac_keys_bs58 = ? WHERE client_address_bs58 = ?
"#,
client_id,
client_address_bs58,
derived_aes128_ctr_blake3_hmac_keys_bs58,
derived_aes128_ctr_blake3_hmac_keys_bs58,
client_address_bs58,
).execute(&self.connection_pool).await?;
self.client_id(&client_address_bs58).await
Ok(())
}
/// Tries to retrieve shared keys stored for the particular client.
+2 -2
View File
@@ -9,7 +9,7 @@ use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
use strum::{Display, EnumString, EnumVariantNames};
use strum::{Display, EnumString, VariantNames};
#[cfg(feature = "generate-ts")]
use ts_rs::{Dependency, TS};
@@ -28,7 +28,7 @@ use ts_rs::{Dependency, TS};
Clone,
Debug,
EnumString,
EnumVariantNames,
VariantNames,
PartialEq,
Eq,
JsonSchema,
+18 -4
View File
@@ -106,7 +106,7 @@ The client was removed from the peer list after 3 days of inactivity. Upon re-co
- [Feature/merge back](https://github.com/nymtech/nym/pull/4710): Merge back from the release branch the changes that fix the `nym-node` upgrades
- [Removed mixnode/gateway config migration code and disabled cli without explicit flag](https://github.com/nymtech/nym/pull/4706): `nym-gateway` and `nym-mixnode` commands now won't do anything without explicit `--force-run` to bypass the deprecation. The next step, in say a month or so, is to completely remove all `cli` related things.
- [Removed mixnode/gateway config migration code and disabled cli without explicit flag](https://github.com/nymtech/nym/pull/4706): Commands for archived / legacy binaries `nym-gateway` and `nym-mixnode` won't do anything without explicit `--force-run` to bypass the deprecation. The next step, in say a month or so, is to completely remove all `cli` related things.
~~~admonish example collapsible=true title='Testing steps performed'
- Verify that the `nym-gateway` binary and `nym-mixnode` binary commands return the _error message_ stating to update to nym-node
@@ -234,7 +234,7 @@ Tested updating an old `nym-node` version and ensuring it did not throw any erro
- Wireguard peers stay connected for longer time, re-connections are also faster
- Profit margin and operating cost values will be set to the agreed values, the values can be changed in the future through [Nym Operators governance process](https://forum.nymtech.net/t/poll-proposal-for-on-chain-minimum-profit-margin-for-all-nym-nodes/253)
- Profit margin and operating cost values are set to the values agreed by operators off-chain vote, the values can be changed in the future through [Nym Operators governance process](https://forum.nymtech.net/t/poll-proposal-for-on-chain-minimum-profit-margin-for-all-nym-nodes/253)
```admonish success title=""
- Minimum profit margin = 20%
- Maximum profit margin = 50%
@@ -250,8 +250,9 @@ Tested updating an old `nym-node` version and ensuring it did not throw any erro
- DNS resolution check, to configure see [tasklist below](#operators-tasks)
- Wireguard perfomance > 0.75, to configure see [tasklist below](#operators-tasks)
- New wallet coming out soon!
- New [Nym Wallet](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.2.14) is out!
- Vesting contract functionalities have been purged, users can only remove tokens from vesting
- Migrating from `mixnode` or `gateway` smart contracts to a new unifying `nym-node` smart contract will be available soon using Nym desktop wallet, just like you are used to for bonding and node settings. After this migration all `nym-nodes` will be able to receive delegation and rewards. We will share a step by step guide once this migration will be deployed. No action needed now.
- [Nym API Check CLI](testing/node-api-check.md) is upgraded according to the latest API endpoints, output is cleaner and more concise.
@@ -272,7 +273,6 @@ Every `nym-node` should be upgraded to the latest version! Operators can test us
- Note: On some VPS this setup may not be enough to get the correct results as some ISPs have their own security groups setup below the individual VPS. In that case a ticket to ISP will have to be issued to open the needed settings. We are working on a template for such ticket.
- Setup [reverse proxy and WSS](nodes/proxy-configuration.md) on `nym-node` (Gateways only for the time being)
- Don't forget to restart your node - or (preferably using [systemd automation](nodes/configuration.md#systemd)) reload daemon and restart the service
- Migrating from `mixnet` or `gateway` smart contracts to a new `nym-node` smart contract will be available soon with an upcoming version of Nym desktop wallet. After this migration all `nym-nodes` will be able to receive delegation. The operators will have to confirm the migration once it's deployed.
- Optional: Use [`nym-gateway-probe`](testing/gateway-probe.html) and [NymVPN CLI](https://nymtech.net/developers/nymvpn/cli.html) to test your own Gateway
- Optional: Run the script below to measure ping speed of your Gateway and share your results in [Nym Operators channel](https://matrix.to/#/#operators:nymtech.chat)
@@ -352,6 +352,20 @@ THANK YOU!
- New `nym-nodes` without a performance 24h history above 50% don't show routing properly on `nym-gateway-probe`, on Nym Harbourmaster the page may appear blank - we are working on a fix.
- Wireguard works on IPv4 only for the time being, we are working on IPv6 implementation.
- Harbourmaster *Role* column shows `nym-node --mode exit-gateway` as `EntryGateway`, we are working to fix it.
- In rare occassions Harbourmaster shows only *"panda"* without the *"smiley"* badge even for nodes, which have T&C's accepted. We are working to fix it.
- Sometimes `nym-node` running with `--wireguard-enabled true` gives this error on restart: `Serialized netlink packet .. larger than maximum size ..`
```sh
/home/ubuntu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/defguard_wireguard_rs-0.4.2/src/netlink.rs:155: Serialized netlink packet (23240 bytes) larger than maximum size 12288: NetlinkMessage.
```
From what we found out it seems that one of our [dependencies - `DefGuard` - is failing](https://github.com/DefGuard/defguard/issues/619). Based on the reading on their fix, it seems that when node operators try to re-create a wireguard interface with too many previous peers (like on Gateway restart, with restoring from storage), there's an overflow. So their fix is to just add them one by one. To be sure that bumping the dependency version fixes the problem there's still two things we'd need to check - and your feedback would help us a lot:
1. Did operators only encounter this error after a `nym-node` (Gateway) restart?
2. Reprouce this error ourselves and see if it actually fixes our problem.
**Please share your experience with us to help faster fix of this issue.**
---
## `v2024.9-topdeck`
@@ -1,11 +1,11 @@
# Reversed Proxy & Web Secure Socket
# Reverse Proxy & Web Secure Socket
It's useful to put your Nym Node behind a reversed proxy and have it accessible via `https` domain, where you can host a [landing page](../legal/landing-pages.md). The guide is right [below](#reversed-proxy).
This section will guide you in setting up a reverse proxy for serving `nym-node` HTTP requests and to set up a custom [landing page](../legal/landing-pages.md) for your node.
More advanced and secure solution is to have your node behind Web Secure Socket (WSS). Follow this [this guide](#web-secure-socket-setup) for installation.
In later sections, you will be setting up secure websocket (wss) to add additional security and encrypt connections coming to your node. Follow [this guide](#web-secure-socket-setup) for installation.
```admonish info
For both of these configurations you will need to register a DNS domain and configure a record to your VPS.
Since SSL certificates can only be issued for a domain name and not an IP address, it is essential for you to register a new domain name and configure a domain record pointing to your node's IP address
```
## Variables Explanation
@@ -13,19 +13,19 @@ For both of these configurations you will need to register a DNS domain and conf
This guide contains several variables. Substitute them with your own value, without `<>` brackets. Here is a list of variables we used below.
| Variable | Description | Syntax example |
| :--- | :--- | :--- |
| :-------------------- | :------------------------------------------------------------------------------------------ | :-------------------------------------------------------- |
| `<HOSTNAME>` | Your registered DNS domain, asigned to the VPS with `nym-node` | exit-gateway1.squad.nsl |
| `<WSS_PORT>` | Port listening to WSS, default is `9001` | 9001 |
| `<YOUR_WELCOME_TEXT>` | Any text you want to show on the landing page | Welcome to Nym Node, operator contact is example@email.me |
| `<LANDING_PAGE_PATH>` | A sub-directory located at `/var/www/<HOSTNAME>` containing html configuration files | `/var/www/exit-gateway1.squad.nsl` |
| `<NODE_ID>` | A local only `nym-node` identifier, specified by flag `--id`, default is `default-nym-node` | alice_super_node |
| `<PATH_TO>` | Specify a full path to the given file, directory or binary behind this variable | `/root/src/nym/target/release/` |
| `<ID>` | A local only `nym-node` identifier, specified by flag `--id`, default is `default-nym-node` | alice_super_node |
| `<PATH_TO>` | Specify a full path to the given file, directory or binary behind this variable | `/root/src/nym/target/release/` |
```admonish warning title=""
The commands in this setup need to be run with root permission. Either add a prefix `sudo` or execute them from a root shell.
```
## Reversed Proxy Setup
## Reverse Proxy Setup
```admonish info
This guide was created by a Nym node operator, [Avril 14th](https://avril14th.org) as a part of [Nym Operators Community Counsel](../legal/community-counsel.md), edited by Nym.
@@ -309,7 +309,7 @@ Now your html page is configured.
### `nym-node` Configuration
When done with the customization, you'll need to make sure your `nym-node` uploads the file and reference to it. This is done by opening your node configuration file located at `~/.nym/nym-nodes/<NODE_ID>/config/config.toml` and changing the value of the line `landing_page_assets_path` on the `[http]` section:
When done with the customization, you'll need to make sure your `nym-node` uploads the file and reference to it. This is done by opening your node configuration file located at `~/.nym/nym-nodes/<ID>/config/config.toml` and changing the value of the line `landing_page_assets_path` on the `[http]` section:
```
landing_page_assets_path = '<LANDING_PAGE_PATH>'
```
@@ -318,9 +318,6 @@ landing_page_assets_path = '<LANDING_PAGE_PATH>'
You may set up a [reverse proxy](https://www.nginx.com/resources/glossary/reverse-proxy-server/) in order to serve this landing page with proper SSL and DNS management, i.e. to resolve it to https://<HOSTNAME>.
The following assumes that you're owning a domain and that you've already set the Let's Encrypt certificates on your hosting, and you've copied those on your Gateway, i.e. copy the two Let's Encript pem files on your Gateway's home folder.
Else you may obtain a Let's Encrypt certificate using a [`--certonly` procedure](https://eff-certbot.readthedocs.io/en/latest/using.html#getting-certificates-and-choosing-plugins).
**Configure Nginx**
1. Install `nginx`:
@@ -328,7 +325,7 @@ Else you may obtain a Let's Encrypt certificate using a [`--certonly` procedure]
sudo apt install nginx
```
2. Setup firewall with `ufw`. `ufw` has three profile pre-configured for `nginx`, we will need the first one for `nym-node`:
1. Setup firewall with `ufw`. `ufw` has three profile pre-configured for `nginx`, we will need the first one for `nym-node`:
- `Nginx Full`: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
- `Nginx HTTP`: This profile opens only port 80 (normal, unencrypted web traffic)
@@ -345,6 +342,7 @@ ufw reload
```
3. Disable the default Nginx landing page
```
systemctl status nginx
unlink /etc/nginx/sites-enabled/default
@@ -353,80 +351,65 @@ systemctl restart nginx
4. Add your endpoint configuration to Nginx by creating file:
```sh
nano /etc/nginx/sites-available/<HOSTNAME>
```
- and changing `<HOSTNAME>` occurrences below with your domain name:
```
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name nym-exit.<HOSTNAME>;
ssl_certificate /etc/letsencrypt/live/<HOSTNAME>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<HOSTNAME>/privkey.pem;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
listen [::]:80;
if ($host = <HOSTNAME>) {
return 301 https://$host$request_uri;
}
# Replace <HOSTNAME> with your domain name
server_name <HOSTNAME>;
server_name <HOSTNAME> www.<HOSTNAME>;
return 301 https://<HOSTNAME>$request_uri;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
This guide assumes that the HTTP port used by you is `8080`. Adjust the configuration accordingly if you have defined
a custom port for your `nym-node` HTTP connections
5. Activate the configuration by creating a symlink to `/etc/nginx/sites-enabled`:
5. Activate the configuration by creating a simlink to `/etc/nginx/sites-enabled`:
```sh
ln -s /etc/nginx/sites-available/<HOSTNAME> /etc/nginx/sites-enabled
```
6. Test your configuration syntax:
```sh
nginx -t
```
Nginx must report that the config is "ok" and the test was successful.
7. Restart `nginx`:
```sh
systemctl daemon-reload && systemctl restart nginx
systemctl restart nginx
```
8. Get an `SSL` certificate using certbot:
```sh
apt install certbot python3-certbot-nginx
certbot renew --dry-run
certbot --nginx -d <HOSTNAME>
certbot --nginx --non-interactive --agree-tos --redirect -m <YOUR_EMAIL_ADDRESS> -d <HOSTNAME>
```
9. Restart your `nym-node` or if you're running your `nym-node` as a [`systemd` service](configuration.md#systemd), restart your service:
```sh
systemctl daemon-reload
service nym-node restart
systemctl daemon-reload && systemctl restart nym-node
```
10. Check for the page being served reading the service logs
9. Check for the page being served reading the service logs
```sh
journalctl -u nym-gateway.service | grep 8080
journalctl -u nym-node.service | grep 8080
# where you should see
... Started NymNodeHTTPServer on 0.0.0.0:8080
@@ -437,27 +420,19 @@ Now your `nginx` should be configured, up and running. Test it by inserting your
## Web Secure Socket Setup
For better security of transfered data, we recommend node operators to run their nodes through Secure Socket instead of be out in open. You can read more about *Secure Socket Layer* (SSL) in [here](https://www.geeksforgeeks.org/secure-socket-layer-ssl/).
We strongly recommend node operators to configure secure web sockets on their nodes. This will provide clients a more secure way to connect to your node.
Before you start, don't forget to register a DNS and configure a record for your VPS with `nym-node`.
You can read more about *Secure Socket Layer* (SSL) in [here](https://www.geeksforgeeks.org/secure-socket-layer-ssl/).
If you haven't configure reversed proxy before, start with [*Preliminary steps* chapter](#preliminary-steps) below and only then move to WSS setup. If you have reversed proxy already running and your `nym-node` can be reached via https, you can skip *Preliminary steps* and begin to setup WSS directly. Remember that there may be some unique variables and customization depending on the way your reversed proxy is done which you may have to adjust when installing WSS in order to make it work.
If you haven't configured reverse proxy before, start with [*Preliminary steps* chapter](#preliminary-steps) and only then move to WSS setup. If you have reverse proxy already running and your `nym-node` can be reached via https, you can skip *Preliminary steps* and begin to setup WSS directly.
Remember that there may be some unique variables and customization depending on the way your reverse proxy is setup which you may have to adjust when configuring WSS to ensure correct functionality
```admonish tip
To see description of used variables (noted in `<>` brackets), scroll to the top of this page, chapter [*Variables Explanation*](#variables-explanation).
```
We documented two options for node operators to setup WSS for `nym-node`:
1. [Using a script](#using-a-script)
2. [Step by step](#step-by-step)
### Preliminary Steps
Whether you choose to setup WSS manually or using the script, the preliminary steps are mandatory to begin with before you continue with the installation.
#### Firewall configuration
Make sure to open all [needed ports](vps-setup.md#configure-your-firewall), adding your `<WSS_PORT>`:
@@ -469,293 +444,18 @@ ufw allow <WSS_PORT>/tcp
# ufw allow 9001/tcp
```
#### Landing page configuration
#### WSS configuration
1. Create server block directory for your https site:
```sh
sudo mkdir -p /var/www/<HOSTNAME>
```
This section assumes that you have already configured a reverse proxy and have set it up to work over https. If not, head over to [the reverse proxy section](#reverse-proxy) to configure it.
2. Assign ownership using `$USER` environmental variable:
```sh
sudo chown -R $USER:$USER /var/www/<HOSTNAME>
```
1. Create a new Nginx configuration file called `/etc/nginx/sites-available/wss-config-nym` and paste the block below. Don't forget to insert your correct values.
3. Create a landing page in `/var/www/<HOSTNAME>`. Either configure your own page (basic [syntax example](https://www.freecodecamp.org/news/introduction-to-html-basics/) or use our [template](#html-file-customization). Alternatively you can just make a simple welcome text using this command:
```sh
echo "<h1><YOUR_WELCOME_TEXT></h1>" | sudo tee /var/www/<HOSTNAME>/index.html
```
4. When done with the customization, you'll need to make sure your `nym-node` uploads the file and reference to it. This is done by opening your node configuration file located at `~/.nym/nym-nodes/<NODE_ID>/config/config.toml` and changing the value of the line `landing_page_assets_path` on the `[http]` section:
```sh
landing_page_assets_path = '<LANDING_PAGE_PATH>'
# for example
# landing_page_assets_path = '/var/www/exit-gateway1.squad.nsl'
```
Now you are ready to set up WSS, ether using a [script](#using-a-script) or [step-by-step](#step-by-step) tutorial.
### Using a Script
Using a script is a more convenient option but it takes away some customization possibilities. If you like to have your setup fully in your hands, use [*Step by step guide*](#step-by-step-guide). Before you move on, make sure you went through [*Preliminary steps*](#preliminary-steps).
1. Create a script by copying the block below and save it on your VPS as `wss_nginx_setup.sh`.
~~~admonish example collapsible=true title="Script `wss_nginx_setup.sh`"
```bash
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "usage: sudo ./wss_nginx_setup.sh <host_name> <port_to_run_wss>"
exit 1
fi
host_name=$1
port_value=$2
# preliminary checks
config_file_path="${HOME}/.nym/nym-nodes/*/config/config.toml"
# check if the configuration file exists
if [ ! -f $config_file_path ]; then
echo "configuration file not found at $config_file_path"
exit 1
fi
# extract hostname and wss port
hostname=$(grep "hostname" $config_file_path | awk -F" = " '{print $2}' | tr -d "'")
wss_port=$(grep "announce_wss_port" $config_file_path | awk -F" = " '{print $2}' | tr -d ' ')
# check if hostname is empty
if [ -z "$hostname" ]; then
echo "hostname is empty, updating it to ${host_name}"
sed -i "s|hostname = ''|hostname = '${host_name}'|" $config_file_path
else
echo "current hostname: $hostname"
fi
# check if wss port is set to 0 and update it
if [ "$wss_port" -eq 0 ]; then
echo "wss port is 0, updating it to ${port_value}"
sed -i "s/announce_wss_port *= *0/announce_wss_port = ${port_value}/" $config_file_path
else
echo "current wss port: $wss_port"
fi
# install nginx
apt update
apt install -y nginx
# install certbot and the nginx plugin
apt install -y certbot python3-certbot-nginx
# enable nginx service
systemctl enable nginx.service
# create a consolidated nginx configuration file
nginx_config_file="/etc/nginx/sites-available/${host_name}"
cat <<EOF > $nginx_config_file
# Reversed proxy configuration for landing page
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ${host_name};
ssl_certificate /etc/letsencrypt/live/${host_name}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${host_name}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header Host \$host;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
# http configuration
server {
listen 80;
listen [::]:80;
server_name ${host_name} www.${host_name};
return 301 https://${host_name}\$request_uri;
}
# WSS configuration
server {
listen ${port_value} ssl http2;
listen [::]:${port_value} ssl http2;
server_name ${host_name};
ssl_certificate /etc/letsencrypt/live/${host_name}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${host_name}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, HEAD';
add_header 'Access-Control-Allow-Headers' '*';
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_pass http://localhost:9000;
proxy_intercept_errors on; # Enable intercepting errors from the proxy
}
}
EOF
# create a symbolic link in sites-enabled
ln -s /etc/nginx/sites-available/${host_name} /etc/nginx/sites-enabled/
# test nginx configuration
if ! nginx -t; then
echo "nginx configuration test failed"
exit 1
fi
# reload nginx service
systemctl reload nginx.service
# obtain ssl certificates using certbot
if ! certbot --nginx -d ${host_name} --non-interactive --agree-tos -m your-email@example.com; then
echo "certbot failed to obtain certificates"
exit 1
fi
# test nginx configuration again
if ! nginx -t; then
echo "nginx configuration test failed after obtaining ssl certificates"
exit 1
fi
# reload nginx service to apply the new configuration
systemctl reload nginx.service
echo "script completed successfully!"
echo "have a nice day!"
exit 0
```
~~~
2. Make the script executable:
```sh
chmod u+x wss_nginx_setup.sh
```
3. Run the script as root (with `sudo` or from the root shell):
```sh
./wss_nginx_setup.sh <HOSTNAME> <WSS_PORT>
# hostname is your domain
# wss default port is 9001
```
4. Restart your `nym-node` or if you're running your `nym-node` as a [`systemd` service](configuration.md#systemd), restart your service:
```sh
systemctl daemon-reload
service nym-node restart
```
Your `nym-node` should be configured to run over WSS now. Test it using the steps in the chapter [below](#test-wss-setup)
### Step by Step Guide
Step by step guide is more advanced than using a [script](#using-a-script), but it allows for more customisation. Before you move on, make sure you finished [*Preliminary steps*](#preliminary-steps*).
#### Nginx Configuration
1. Install `nginx`:
```sh
apt install nginx
```
2. Setup firewall with `ufw`. `ufw` has three profile pre-configured for `nginx`, we will need the first one for `nym-node`:
- `Nginx Full`: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
- `Nginx HTTP`: This profile opens only port 80 (normal, unencrypted web traffic)
- `Nginx HTTPS`: This profile opens only port 443 (TLS/SSL encrypted traffic)
```sh
ufw allow 'Nginx Full'
# you can verify by
ufw status
```
#### WSS & Landing page configuration
We made the landing page customization directory in [*Preliminary steps*](#preliminary-steps), next steps will configure that with Nginx.
3. Configure your site to work with `nginx`. Open a new text file `/etc/nginx/sites-available/<HOSTNAME>` and paste the block below. Don't forget to insert your correct values.
~~~admonish example collapsible=true title="Site configuration `/etc/nginx/sites-available/<HOSTNAME>`"
~~~admonish example collapsible=true title="Site configuration `/etc/nginx/sites-available/wss-config-nym`"
```bash
#####################################################
# EXCHANGE ALL <HOSTNAME> & <WSS_PORT> VARIABLES ! #
####################################################
# Reversed proxy configuration for landing page
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name <HOSTNAME>;
ssl_certificate /etc/letsencrypt/live/<HOSTNAME>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<HOSTNAME>/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# http configuration
server {
listen 80;
listen [::]:80;
if ($host = <HOSTNAME>) {
return 301 https://$host$request_uri;
}
server_name <HOSTNAME> www.<HOSTNAME>;
return 301 https://<HOSTNAME>$request_uri;
}
# WSS configuration
server {
listen <WSS_PORT> ssl http2;
listen [::]:<WSS_PORT> ssl http2;
@@ -770,29 +470,35 @@ server {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Ignore favicon requests
location /favicon.ico {
return 204;
access_log off;
log_not_found off;
}
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, HEAD';
add_header 'Access-Control-Allow-Headers' '*';
proxy_http_version 1.1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:9000;
proxy_intercept_errors on; # Enable intercepting errors from the proxy
proxy_intercept_errors on;
}
}
```
~~~
4. Activate the configuration by creating a simlink to `/etc/nginx/sites-enabled`:
```sh
ln -s /etc/nginx/sites-available/<HOSTNAME> /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/wss-config-nym /etc/nginx/sites-enabled
```
5. Test your configuration syntax:
@@ -802,23 +508,22 @@ nginx -t
6. Restart `nginx`:
```sh
systemctl daemon-reload && systemctl restart nginx
systemctl restart nginx
```
#### SSL Setup using certbot
7. Finally, configure your `nym-node` to announce the port you have setup. This is done by opening your node configuration file located at `~/.nym/nym-nodes/<ID>/config/config.toml` and changing the value of the line `announce_wss_port` in the `[entry_gateway]` section:
7. Get an `SSL` certificate using certbot:
```
announce_wss_port = <WSS_PORT>
```sh
apt install certbot python3-certbot-nginx
certbot renew --dry-run
certbot --nginx -d <HOSTNAME>
# example
# announce_wss_port = 9001
```
8. Restart your `nym-node` or if you're running your `nym-node` as a [`systemd` service](configuration.md#systemd), restart your service:
8. Restart your `nym-node` :
```sh
systemctl daemon-reload
service nym-node restart
systemctl restart nym-node
```
Your `nym-node` should be configured to run over WSS now. Test it using the steps in the chapter [below](#test-wss-setup).
@@ -833,9 +538,7 @@ You can do a few quick checks to test that your installation worked out and your
sudo apt install node-ws
# run
wscat -c ws://<HOSTNAME>:<WSS_PORT>
wscat -c wss://<HOSTNAME>:<WSS_PORT>
```
- Browse your `<HOSTNAME>` as URL and see your landing page.
- Check Swagger API of your node using the hostname: `https://<HOSTNAME>/api/v1/swagger/#/`
@@ -570,7 +570,11 @@ where
return Ok(InitialAuthResult::new_failed(Some(negotiated_protocol)));
};
let client_id = self.shared_state.storage.get_client_id(address).await?;
let client_id = self
.shared_state
.storage
.get_mixnet_client_id(address)
.await?;
let available_bandwidth: AvailableBandwidth = self
.shared_state
+14 -8
View File
@@ -2209,6 +2209,12 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@@ -3195,7 +3201,7 @@ dependencies = [
"nym-network-defaults",
"rand 0.8.5",
"serde",
"strum 0.25.0",
"strum 0.26.3",
"thiserror",
"time",
]
@@ -3403,7 +3409,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.8",
"strum 0.25.0",
"strum 0.26.3",
"thiserror",
"ts-rs",
"url",
@@ -5188,11 +5194,11 @@ dependencies = [
[[package]]
name = "strum"
version = "0.25.0"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [
"strum_macros 0.25.3",
"strum_macros 0.26.4",
]
[[package]]
@@ -5210,11 +5216,11 @@ dependencies = [
[[package]]
name = "strum_macros"
version = "0.25.3"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck 0.4.1",
"heck 0.5.0",
"proc-macro2",
"quote",
"rustversion",