Compare commits

..

13 Commits

Author SHA1 Message Date
Dinko Zdravac 1f53da7456 Fix env var name (#5165) 2024-11-22 15:41:16 +00:00
Jon Häggblad 2fdc0dc47b Add strum::EnumIter for TicketType (#5164) 2024-11-22 16:33:23 +01:00
Fran Arbanas a720c95dd7 feat: add env vars to NNM (#5163)
* feat: add env vars to NNM

* update version to testfran

* add ip and port for locust connection as variables

* bump version

* bump version, fix env variable names

* bump version to correct one
2024-11-22 14:32:58 +00:00
mx 013941dbaf patch curl command for network_tunnel_man.sh (#5160) 2024-11-21 20:28:22 +00:00
benedetta davico 1af6e1ecdd Create network_tunnel_manager.sh (#5156)
* Create network_tunnel_manager.sh

* update link for network tunnel manager script

* updating 2 more links
2024-11-21 20:11:28 +00:00
Mark Sinclair 379c1eb0d0 Update push-network-monitor.yaml 2024-11-21 16:11:59 +00:00
Mark Sinclair d1e91946e6 Update push-network-monitor.yaml 2024-11-21 16:07:12 +00:00
Mark Sinclair 402c79f2f5 Update push-network-monitor.yaml 2024-11-21 15:59:41 +00:00
Mark Sinclair 149b2f4e32 Update Cargo.toml for nym-network-monitor 2024-11-21 15:52:56 +00:00
Mark Sinclair 221e809da3 Update push-network-monitor.yaml 2024-11-21 15:52:11 +00:00
Mark Sinclair 760ee453ea Update nym-network-monitor.dockerfile 2024-11-21 15:25:38 +00:00
Dinko Zdravac 3f072e4e9d NS Agent auth with NS API (#5127)
* Agents authenticate with NSAPI

* /submit with better auth
- also adjust agent run script to authenticate, even in parallel

* /request better authentication
- moved agent API calls to Client struct

* Replay protection

* Fix testrun cleanup bug
- introduce a new column last_assigned which is different than
  created_at so that stale testruns get cleaned up based on
  last_assigned
- created_at is still useful for determining the "oldest" testrun
  to be picked up

* Uniform request authentication

* Suppress ts-rs serde warnings

* Update cargo version

* All agents use the same key
- remove assigned_agent column
- remove logic which would stop agents with
  the same key to connect
- as a safety measure, add cap to total no. of agents
2024-11-21 14:32:15 +01:00
mx aa460076f4 Max/surb doc update lifetime (#5154)
* updated surbs page with lifetimes info + attacks + diagram

* component build update

* update rewrites
2024-11-21 10:37:31 +00:00
19 changed files with 456 additions and 52 deletions
+14 -18
View File
@@ -25,31 +25,27 @@ jobs:
git config --global user.email "lawrence@nymtech.net"
git config --global user.name "Lawrence Stalder"
- name: Get version from package.json
uses: sergeysova/jq-action@v2
- name: Get version from cargo.toml
uses: mikefarah/yq@v4.44.5
id: get_version
with:
cmd: jq -r '.version' ${{ env.WORKING_DIRECTORY }}/package.json
- name: Check if tag exists
run: |
if git rev-parse ${{ steps.get_version.outputs.value }} >/dev/null 2>&1; then
echo "Tag ${{ steps.get_version.outputs.value }} already exists"
fi
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml
- name: Remove existing tag if exists
run: |
if git rev-parse ${{ steps.get_version.outputs.value }} >/dev/null 2>&1; then
git push --delete origin ${{ steps.get_version.outputs.value }}
git tag -d ${{ steps.get_version.outputs.value }}
echo "Checking if tag ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} exists..."
if git rev-parse ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
echo "Tag ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} already exists"
git push --delete origin ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
git tag -d ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
fi
- name: Create tag
run: |
git tag -a ${{ steps.get_version.outputs.value }} -m "Version ${{ steps.get_version.outputs.value }}"
git push origin ${{ steps.get_version.outputs.value }}
git tag -a ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} -m "Version ${{ steps.get_version.outputs.result }}"
git push origin ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
- name: BuildAndPushImageOnHarbor
run: |
docker build -f nym-network-monitor.dockerfile ${{ env.WORKING_DIRECTORY }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.value }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
docker build -f nym-network-monitor.dockerfile ${{ env.WORKING_DIRECTORY }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.result }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
Generated
+2 -2
View File
@@ -5868,7 +5868,7 @@ dependencies = [
[[package]]
name = "nym-network-monitor"
version = "0.1.0"
version = "1.0.2"
dependencies = [
"anyhow",
"axum 0.7.7",
@@ -6074,7 +6074,7 @@ dependencies = [
[[package]]
name = "nym-node-status-api"
version = "1.0.0-rc.1"
version = "1.0.0-rc.2"
dependencies = [
"anyhow",
"axum 0.7.7",
+9 -1
View File
@@ -221,7 +221,15 @@ impl From<PayInfo> for NymPayInfo {
}
#[derive(
Copy, Clone, Debug, PartialEq, Serialize, Deserialize, strum::Display, strum::EnumString,
Copy,
Clone,
Debug,
PartialEq,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
strum::EnumIter,
)]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
@@ -1 +1 @@
Tuesday, November 19th 2024, 11:34:21 UTC
Wednesday, November 20th 2024, 15:53:00 UTC
@@ -1,4 +1,5 @@
```sh
2024-11-20T15:53:01.702819Z  INFO nym-api/src/main.rs:40: Starting nym api...
Usage: nym-api [OPTIONS] <COMMAND>
Commands:
@@ -9,9 +10,9 @@ Commands:
Options:
-c, --config-env-file <CONFIG_ENV_FILE>
Path pointing to an env file that configures the Nym API
Path pointing to an env file that configures the Nym API [env: NYMAPI_CONFIG_ENV_FILE_ARG=]
--no-banner
A no-op flag included for consistency with other binaries (and compatibility with nymvisor, oops)
A no-op flag included for consistency with other binaries (and compatibility with nymvisor, oops) [env: NYMAPI_NO_BANNER_ARG=]
-h, --help
Print help
-V, --version
@@ -44,6 +44,8 @@ Options:
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: `0.0.0.0: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>
@@ -52,14 +54,14 @@ Options:
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
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=]
--verloc-bind-address <VERLOC_BIND_ADDRESS>
Socket address this node will use for binding its verloc API. default: `0.0.0.0: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: `0.0.0.0:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=]
--announce-ws-port <ANNOUNCE_WS_PORT>
+12
View File
@@ -772,6 +772,18 @@ const config = {
permanent: true,
basePath: false,
},
{
source: "/operators/troubleshooting/nodes.html",
destination: "/docs/operators/troubleshooting/nodes",
permanent: true,
basePath: false,
},
{
source: "/operators/nodes/manual-upgrade.html",
destination: "/docs/operators/nodes/maintenance/manual-upgrade",
permanent: true,
basePath: false,
},
{
source: "/developers/faq/general-faq.html",
destination: "/docs/operators/faq/general-faq",
@@ -14,4 +14,4 @@ MultiSURBs were implemented in `v1.1.4`. Clients, when sending a message to anot
If a reply is too large still (i.e. it would use more space than the available combined payload of the SURBs sent with the original message), the receiver will use a SURB to ask the sender for more SURBs.
You can read more about SURBs in §4.5 of the [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf) as well as the [SURB format page](../traffic/anonymous-replies).
You can read more about SURBs in §4.5 of the [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf) as well as the [SURB traffic page](../traffic/anonymous-replies) to learn more about how SURBs are used in the Mixnet, known attacks relying on SURBs, etc.
@@ -1,13 +0,0 @@
# Anonymous Replies with SURBs
> SURBs are the Sphinx equivalent of "onion addresses" in Tor, with the caveat that a SURB can only
be used once (to prevent replay attacks) and within its epoch of validity (the mix node public keys used to
prepare the SURB are only valid for a limited period).
> ...
> A SURB effectively contains: (1) the encrypted headers of a Sphinx message that, if sent to the mixnet, will be routed back to the original sender; (2) the address of the first-layer mix node where the message should be sent; and (3) a cryptographic key to encrypt the reply payload.
>
> [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf) §4.6
As outlined in the [concepts](../concepts/anonymous-replies) section, SURBs are layer encrypted sets of Sphinx headers detailing a reply path ending in the sending client's [Nym address](../traffic/addressing-system). Clients receiving messages with SURBs attached are able to write a payload to the provided headers without ever learning about anything other than the first hop back into the Mixnet - the Gateway they are currently connected to.
There is a balance to be struck between the amount of SURBs to compute to send along with messages (which takes computation resources) and not sending enough SURBs initially, thus having to wait for a SURB to be sent from the receiver to the sender, requesting more SURBs be sent.
@@ -0,0 +1,78 @@
import { Callout } from 'nextra/components'
# Anonymous Replies with SURBs
> SURBs are pre-computed Sphinx packet headers encoding a mixnet route that ends in the participant that created the SURB. A sender can generate one or more SURBs and include them in their Sphinx message to a recipient. The recipient can use the SURBs as Sphinx headers to send back replies or acknowledgements that anonymously reach back the original sender after going through the mixnet.
>
> SURBs are the Sphinx equivalent of "onion addresses" in Tor, with the caveat that a SURB can only be used once (to prevent replay attacks) and within its epoch of validity (the mix node public keys used to prepare the SURB are only valid for a limited period). SURB headers are encrypted by the sender, so the recipient sending it back cannot infer from it any information about the message route, the per-hop latency, or the senders address, which is encoded in the innermost (last) routing layer of the SURB. SURBs ('Single Use Reply Blocks') allow clients to reply to incoming messages anonymously.
>
> ...
>
> A SURB effectively contains: (1) the encrypted headers of a Sphinx message that, if sent to the mixnet, will be routed back to the original sender; (2) the address of the first-layer mix node where the message should be sent; and (3) a cryptographic key to encrypt the reply payload.
> [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf) §4.5
As outlined in the [concepts](../concepts/anonymous-replies) section, SURBs are layer encrypted sets of Sphinx headers detailing a reply path ending in the sending client's [Nym address](../traffic/addressing-system). Clients receiving messages with SURBs attached are able to write a payload to the provided headers without ever learning about anything other than the first hop back into the Mixnet - the Gateway they (the sender of the reply) are currently registered with.
Put simply, client A sends client B a request of some kind. Before sending the request through the Mixnet, it creates a number of SURBs and sends those along with the request. Client B writes the response to the request to the payload of the SURBs, and then sends these through the Mixnet. Since Sphinx packets are multiply route-encrypted, the first destination of the packet is the `nym-node` running as an Entry Gateway that client B has registered with already, so no information regarding either the path through the Mixnet or the destination of the SURBs (aka the Nym address of client A) is revealed to client B.
## Anatomy of a SURB
Diagramatic representation coming soon™️.
## Sender Tags
For a session between two clients, the sending client generates a random alphanumeric string, referred to as a `sender tag` which is sent along with the SURBs to the receiver of its message(s). The `sender tag` is generated randomly, and does not refer in any way to any identifiers of the sending client.
This is done so that receiving clients have some way of differentiating incoming SURBs from multiple clients and can split them into different 'buckets' in order to facilitate concurrent anonymous replies.
## Replenishing SURBs
Since each SURB is just a pre-computed Sphinx packet header, and Sphinx packets only have a finite payload size, then the size of a possible reply for the amount of SURBs sent with a request is `# SURBs * payload size in bytes`. However it is often the case that replies may be variable in size and larger than the alloted payload size, and/or the sending client did not want to compute many Sphinx headers to send with its initial request.
As such, when a client is running out of SURBs to use for replying, it will use a SURB to send a request to the initial sending client. This request is a request for more SURBs to be sent to it.
```mermaid
---
config:
theme: neo-dark
layout: elk
---
sequenceDiagram
participant Nym Client (Sender)
participant Mixnet Nodes
participant Nym Client (Receiver)
Nym Client (Sender) ->> Nym Client (Sender): Create Sphinx packets with request payload & Sphinx packets with N SURBs
Nym Client (Sender) ->> Mixnet Nodes: Sphinx packets (with payload + with SURBs)
Mixnet Nodes ->> Nym Client (Receiver): Sphinx packets (with payload + with SURBs)
Nym Client (Receiver) ->> Nym Client (Receiver): Decrypt packets
Nym Client (Receiver) ->> Nym Client (Receiver): Perform computation
Nym Client (Receiver) ->> Nym Client (Receiver): Prepare response - problem! Response requires > N * SURB payloads
Nym Client (Receiver) ->> Mixnet Nodes: Sphinx packets (SURB request)
Mixnet Nodes ->> Nym Client (Sender): Sphinx packets (SURB request)
Nym Client (Sender) ->> Nym Client (Sender): Create more SURBs
Nym Client (Sender) ->> Mixnet Nodes: Sphinx packets (SURBs)
Mixnet Nodes ->> Nym Client (Receiver): Sphinx packets (SURBs)
Nym Client (Receiver) ->> Nym Client (Receiver): Write response to SURB payloads
Nym Client (Receiver) ->> Mixnet Nodes: SURBs with payload
Mixnet Nodes ->> Nym Client (Sender): SURBs with payload
Nym Client (Sender) ->> Nym Client (Sender): Decrypt - anonymous response received
```
There is a balance to be struck between the amount of SURBs to compute to send along with messages (aka the sending client A spending computation resources) and not sending enough SURBs initially, thus having to wait for a SURB to be sent from the receiving client B to client A requesting more SURBs be sent, which themselves have to be then sent through the Mixnet to client B to be written to and sent back through the Mixnet again.
If you are able to spend the extra resources upfront and send a lot of SURBs, fewer trips through the Mixnet are required for traffic to go back and forth. However, bear in mind that SURBs in the future will have a finite lifespan (see the section below) so precomputing a very large number to send with the initial message (assuming you are expecting a large reponse, or several messages back and forth) will not work. Furthermore, sending huge amounts of SURBs might open your app up to [possible attacks](#anatomy-of-a-surb).
## SURB Lifetimes
<Callout type="warning">
At the time of writing, SURBs themselves are valid indefinitely, but clients purge their local DB of SURBs that are older than a day on restart. SURBs are valid between topology changes over epochs as `nym-nodes` have a single static publick key, so unless a node goes offline, SURBs will still work even after a topology change.
We still have a few features to add to the Mixnet to add some extra security which will dramatically limit the amount of time SURBs are valid for, but will increase the overall security of the network, so do **not** build with the current status in mind. Instead, check out the information below, and build with this in mind.
</Callout>
Once node key rotation (part of the larger [forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy) work) and [replay protection](https://www.kaspersky.com/resource-center/definitions/replay-attack) is implemented, SURBs will only be valid for the length of the key epoch (aka for the length of time a `nym-node` retains a particular public key between rotations). The length of the key epoch is still to be decided.
Although this means that there will probably be more back-and-forth between clients sending large volumes of traffic, this will make the network more secure overall.
## Known Attacks Using SURBs
There is a known attack in which a malicious service provider / client continually requests that a sending client sends more and more SURBs to them, accruing a large number of them. The attacker then sends all SURBs back to the sending clients at once in order to try and see permutations in the traffic exiting the Mixnet to the sending client, in order to work out which Gateway they are using as their Entry Gateway.
This attack however relies upon the attacker already being able to actively scan all `nym-node`s running as Gateways and capture that traffic, as well as (once the [zk-nym scheme]() is enabled, spend money to send that traffic through the Mixnet. Furthermore, this is an _active attack_ and requires a client to be either be running a malicious service, or be in a position to request multiple bundles of SURBs from clients via some service.
@@ -1309,7 +1309,7 @@ Every `nym-node` should be upgraded to the latest version! Operators can test us
**`nym-node`**
- Make sure to fill in basic description info, into the file located at `.nym/nym-nodes/<ID>/data/description.toml` (all nodes)
- Configure wireguard routing with new [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) following [these steps](nodes/configuration.md#routing-configuration) (Gateways only for the time being)
- Configure wireguard routing with new [`network_tunnel_manager.sh`](https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh) following [these steps](nodes/configuration.md#routing-configuration) (Gateways only for the time being)
- Enable Wireguard with `--wireguard-enabled true` flag included in your run command (Gateways only for the time being)
- 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)
@@ -1551,9 +1551,9 @@ ufw status
**Step 2: Download and Prepare the Network Tunnel Manager Script**
1. Download the [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) script:
1. Download the [`network_tunnel_manager.sh`](https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh) script:
```bash
curl -L -o network_tunnel_manager.sh https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/3c0a38c1416f8fdf22906c013299dd08d1497183/network_tunnel_manager.sh
curl -L -o network_tunnel_manager.sh https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh
```
2. Make the script executable:
@@ -268,7 +268,7 @@ Make sure to keep your IPv4 address enabled while setting up IPv6, as the majori
### Routing Configuration
While we're working on Rust implementation to have these settings as a part of the binary build, to solve these connectivity requirements in the meantime we wrote a script [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) to support operators to configure their servers and address all the connectivity requirements.
While we're working on Rust implementation to have these settings as a part of the binary build, to solve these connectivity requirements in the meantime we wrote a script [`network_tunnel_manager.sh`](https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh) to support operators to configure their servers and address all the connectivity requirements.
Networking configuration across different ISPs and various operation systems does not have a generic solution. If the provided configuration setup doesn't solve your problem check out [IPv6 troubleshooting](../../troubleshooting/vps-isp.mdx#ipv6-troubleshooting) page. Be aware that you may have to do more research, customised adjustments or contact your ISP to change settings for your VPS.
@@ -285,7 +285,7 @@ The script should be used in a context where `nym-node` is running to fully util
###### 1. Download `network_tunnel_manager.sh`, make executable and run:
```sh
curl -L https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/74241cc06492b955e582052939090f57a285a65e/network_tunnel_manager.sh -o network_tunnel_manager.sh && \
curl -L https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/network_tunnel_manager.sh -o network_tunnel_manager.sh && \
chmod +x network_tunnel_manager.sh && \
./network_tunnel_manager.sh
```
+1
View File
@@ -6,6 +6,7 @@ RUN cargo build --release
FROM locustio/locust
EXPOSE 8089
EXPOSE 8080
COPY --from=builder /usr/src/nym/target/release/nym-network-monitor /bin/nym-network-monitor
COPY --from=builder /usr/src/nym/nym-network-monitor/locustfile.py locustfile.py
COPY --from=builder /usr/src/nym/nym-network-monitor/entrypoint.sh entrypoint.sh
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-network-monitor"
version = "0.1.0"
version = "1.0.2"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -13,7 +13,7 @@ license.workspace = true
[dependencies]
anyhow = { workspace = true }
axum = { workspace = true, features = ["json"] }
clap = { workspace = true, features = ["derive"] }
clap = { workspace = true, features = ["derive", "env"] }
dashmap = { workspace = true }
futures = { workspace = true }
log = { workspace = true }
+1 -1
View File
@@ -15,7 +15,7 @@ nnm_pid=$!
sleep 10
python -m locust -H http://127.0.0.1:8080 --processes "${processes}" --autostart --autoquit 60 -u "${users}" -t "${timeout}"s &
python -m locust -H http://${NYM_NETWORK_MONITOR_HOST}:${NYM_NETWORK_MONITOR_PORT} --processes "${processes}" --autostart --autoquit 60 -u "${users}" -t "${timeout}"s &
locust_pid=$!
wait $locust_pid
+2 -2
View File
@@ -107,11 +107,11 @@ struct Args {
client_lifetime: u64,
/// Port to listen on
#[arg(long, default_value_t = 8080)]
#[arg(long, default_value_t = 8080, env = "NYM_NETWORK_MONITOR_PORT")]
port: u16,
/// Host to listen on
#[arg(long, default_value = "127.0.0.1")]
#[arg(long, default_value = "127.0.0.1", env = "NYM_NETWORK_MONITOR_HOST")]
host: String,
/// Path to the topology file
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-node-status-api"
version = "1.0.0-rc.1"
version = "1.0.0-rc.2"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
+1 -1
View File
@@ -77,7 +77,7 @@ pub(crate) struct Cli {
#[clap(
long,
default_value_t = 40,
env = "NYM_NODE_STATUS_API_NYM_HTTP_CACHE_TTL"
env = "NYM_NODE_STATUS_API_MAX_AGENT_COUNT"
)]
pub(crate) max_agent_count: i64,
}
+319
View File
@@ -0,0 +1,319 @@
#!/bin/bash
network_device=$(ip route show default | awk '/default/ {print $5}')
tunnel_interface="nymtun0"
wg_tunnel_interface="nymwg"
if ! dpkg -s iptables-persistent >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y iptables-persistent
else
echo "iptables-persistent is already installed."
fi
fetch_ipv6_address_nym_tun() {
ipv6_global_address=$(ip -6 addr show $tunnel_interface scope global | grep inet6 | awk '{print $2}' | head -n 1)
if [[ -z "$ipv6_global_address" ]]; then
echo "no globally routable IPv6 address found on $tunnel_interface. please configure IPv6 or check your network settings."
exit 1
else
echo "using IPv6 address: $ipv6_global_address"
fi
}
fetch_and_display_ipv6() {
ipv6_address=$(ip -6 addr show ${network_device} scope global | grep inet6 | awk '{print $2}')
if [[ -z "$ipv6_address" ]]; then
echo "no global IPv6 address found on ${network_device}."
else
echo "IPv6 address on ${network_device}: $ipv6_address"
fi
}
adjust_ip_forwarding() {
ipv6_forwarding_setting="net.ipv6.conf.all.forwarding=1"
ipv4_forwarding_setting="net.ipv4.ip_forward=1"
echo "$ipv6_forwarding_setting" | sudo tee -a /etc/sysctl.conf
echo "$ipv4_forwarding_setting" | sudo tee -a /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
}
apply_iptables_rules_wg() {
echo "applying IPtables rules..."
echo "network device: ${network_device}"
echo "tunnel_interface: ${wg_tunnel_interface}"
sleep 2
sudo iptables -A FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables -A FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
}
remove_iptables_rules_wg() {
echo "removing IPtables rules..."
echo "network device: ${network_device}"
echo "tunnel_interface: ${wg_tunnel_interface}"
sleep 2
# IPv4 rules removal wg
sudo iptables -D FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables -D FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
# IPv6 rules removal wg
sudo ip6tables -t nat -D POSTROUTING -o "$network_device" -j MASQUERADE
sudo ip6tables -D FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -D FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
}
apply_iptables_rules() {
echo "applying IPtables rules..."
echo "network device: ${network_device}"
echo "tunnel_interface: ${tunnel_interface}"
sleep 2
sudo iptables -t nat -A POSTROUTING -o "$network_device" -j MASQUERADE
sudo iptables -A FORWARD -i "$tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables -A FORWARD -i "$network_device" -o "$tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -t nat -A POSTROUTING -o "$network_device" -j MASQUERADE
sudo ip6tables -A FORWARD -i "$network_device" -o "$tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -A FORWARD -i "$tunnel_interface" -o "$network_device" -j ACCEPT
adjust_ip_forwarding
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
}
remove_iptables_rules() {
echo "removing IPtables rules..."
echo "network device: ${network_device}"
echo "tunnel_interface: ${tunnel_interface}"
sleep 2
# IPv4 rules removal
sudo iptables -t nat -D POSTROUTING -o "$network_device" -j MASQUERADE
sudo iptables -D FORWARD -i "$tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables -D FORWARD -i "$network_device" -o "$tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
# IPv6 rules removal
sudo ip6tables -t nat -D POSTROUTING -o "$network_device" -j MASQUERADE
sudo ip6tables -D FORWARD -i "$network_device" -o "$tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -D FORWARD -i "$tunnel_interface" -o "$network_device" -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
}
check_ipv6_ipv4_forwarding() {
result_ipv4=$(cat /proc/sys/net/ipv4/ip_forward)
result_ipv6=$(cat /proc/sys/net/ipv6/conf/all/forwarding)
echo "IPv4 forwarding is $([ "$result_ipv4" == "1" ] && echo "enabled" || echo "not enabled")."
echo "IPv6 forwarding is $([ "$result_ipv6" == "1" ] && echo "enabled" || echo "not enabled")."
}
check_nymtun_iptables() {
echo "network Device: $network_device"
echo "---------------------------------------"
echo
echo "inspecting IPv4 firewall rules..."
iptables -L FORWARD -v -n | awk -v dev="$network_device" '/^Chain FORWARD/ || /nymtun0/ && dev || dev && /nymtun0/ || /ufw-reject-forward/'
echo "---------------------------------------"
echo
echo "inspecting IPv6 firewall rules..."
ip6tables -L FORWARD -v -n | awk -v dev="$network_device" '/^Chain FORWARD/ || /nymtun0/ && dev || dev && /nymtun0/ || /ufw6-reject-forward/'
}
joke_through_the_mixnet() {
echo "checking Internet and mixnet connectivity (IPv4) via nymtun0..."
ipv4_address=$(ip addr show nymtun0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)
if [ -z "$ipv4_address" ]; then
echo
echo "no IPv4 address found on nymtun0."
echo "please ensure IPv4 is configured correctly on your device."
echo "unfortunately, there's no joke for you :( and you might not be able to route IPv4 traffic through your gateway to the internet."
else
joke=$(curl -s -H "Accept: application/json" --interface "$ipv4_address" https://icanhazdadjoke.com/ | jq -c .joke)
if [ -z "$joke" ] || [ "$joke" = "null" ]; then
echo "failed to fetch a joke. there might be an issue with the Internet connectivity or the joke service."
else
echo "joke fetched successfully:"
echo "$joke"
fi
fi
echo "checking Internet and mixnet connectivity (IPv6) via nymtun0..."
ipv6_address=$(ip addr show nymtun0 | grep 'inet6 ' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^fe80:')
if [ -z "$ipv6_address" ]; then
echo
echo "no globally routable IPv6 address found on nymtun0."
echo "please ensure IPv6 is enabled on your VPS or configure your security groups/firewall settings appropriately."
echo "unfortunately there's no joke fo you :( and you can't route ipv6 traffic through your gateway to the internet"
else
joke=$(curl -s -H "Accept: application/json" --interface "$ipv6_address" https://icanhazdadjoke.com/ | jq -c .joke)
if [ -z "$joke" ] || [ "$joke" = "null" ]; then
echo "failed to fetch a joke. there might be an issue with the Internet connectivity or the joke service."
else
echo "joke fetched successfully:"
echo "$joke"
fi
fi
}
check_ip6_ipv4_routing() {
echo "---------------------------------------"
echo "examining IPv4 routing table..."
ip route
echo "---------------------------------------"
echo
echo "examining IPv6 routing table..."
ip -6 route
echo
}
perform_ipv4_ipv6_pings() {
echo "---------------------------------------"
echo "checking IPv4 connectivity (example: google.com)..."
ping -c 4 google.com
echo "---------------------------------------"
echo
echo "checking IPv6 connectivity (example: google.com)..."
ping6 -c 4 google.com
echo
}
configure_dns_and_icmp_wg() {
echo "allowing icmp (ping)..."
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
echo "allowing dns over udp (port 53)..."
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
echo "allowing dns over tcp (port 53)..."
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
echo "saving iptables rules..."
sudo iptables-save > /etc/iptables/rules.v4
echo "dns and icmp configuration completed."
}
joke_through_wg_tunnel() {
echo "checking nymwg tunnel status..."
tunnel_status=$(ip link show nymwg | grep -o "state [A-Z]*")
if [[ $tunnel_status == "state UNKNOWN" ]]; then
echo "nymwg tunnel is up."
else
echo "nymwg tunnel is down."
echo "please check your nymwg tunnel configuration."
return
fi
echo "checking internet and mixnet connectivity (ipv4) via nymwg..."
ipv4_address=$(ip addr show nymwg | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)
if [ -z "$ipv4_address" ]; then
echo
echo "no ipv4 address found on nymwg."
echo "please ensure ipv4 is configured correctly on your device."
echo "unfortunately, there's no joke for you :( and you might not be able to route ipv4 traffic through your gateway to the internet."
else
joke=$(curl -s -H "accept: application/json" --interface "$ipv4_address" https://icanhazdadjoke.com/ | jq -c .joke)
if [ -z "$joke" ] || [ "$joke" = "null" ]; then
echo "failed to fetch a joke. there might be an issue with the internet connectivity or the joke service."
else
echo "joke fetched successfully:"
echo "$joke"
fi
fi
echo "checking internet and mixnet connectivity (ipv6) via nymwg..."
ipv6_address=$(ip addr show nymwg | grep 'inet6 ' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^fe80:')
if [ -z "$ipv6_address" ]; then
echo
echo "no globally routable ipv6 address found on nymwg."
echo "please ensure ipv6 is enabled on your vps or configure your security groups/firewall settings appropriately."
echo "unfortunately, there's no joke for you :( and you can't route ipv6 traffic through your gateway to the internet."
else
joke=$(curl -s -H "accept: application/json" --interface "$ipv6_address" https://icanhazdadjoke.com/ | jq -c .joke)
if [ -z "$joke" ] || [ "$joke" = "null" ]; then
echo "failed to fetch a joke. there might be an issue with the internet connectivity or the joke service."
else
echo "joke fetched successfully:"
echo "$joke"
fi
fi
}
case "$1" in
fetch_ipv6_address_nym_tun)
fetch_ipv6_address_nym_tun
;;
fetch_and_display_ipv6)
fetch_and_display_ipv6
;;
check_nymtun_iptables)
check_nymtun_iptables
;;
apply_iptables_rules)
apply_iptables_rules
;;
remove_iptables_rules)
remove_iptables_rules
;;
check_ipv6_ipv4_forwarding)
check_ipv6_ipv4_forwarding
;;
check_ip6_ipv4_routing)
check_ip6_ipv4_routing
;;
perform_ipv4_ipv6_pings)
perform_ipv4_ipv6_pings
;;
joke_through_the_mixnet)
joke_through_the_mixnet
;;
apply_iptables_rules_wg)
apply_iptables_rules_wg
;;
joke_through_wg_tunnel)
joke_through_wg_tunnel
;;
configure_dns_and_icmp_wg)
configure_dns_and_icmp_wg
;;
*)
echo "usage: $0 [command]"
echo "commands:"
echo " fetch_ipv6_address_nym_tun - Fetches the IPv6 address assigned to the '$tunnel_interface'."
echo " fetch_and_display_ipv6 - Displays the IPv6 address on the default network device."
echo " apply_iptables_rules - Applies necessary IPv4 and IPv6 iptables rules."
echo " apply_iptables_rules_wg - Applies iptable rules for IPv4 and IPv6 for Wireguard."
echo " remove_iptables_rules - Removes applied IPv4 and IPv6 iptables rules."
echo " remove_iptables_rules_wg - Removes applied IPv4 and IPv6 iptables rules for Wireguard."
echo " check_ipv6_ipv4_forwarding - Checks if IPv4 and IPv6 forwarding are enabled."
echo " check_nymtun_iptables - Check nymtun0 device."
echo " perform_ipv4_ipv6_pings - Perform IPv4 and IPv6 pings to google."
echo " check_ip6_ipv4_routing - Check IPv6 and IPv4 routing."
echo " joke_through_the_mixnet - Run a joke through the mixnet via IPv4 and IPv6."
echo " joke_through_wg_tunnel - Run a wg test, and get a joke through the wg tunnel."
echo " configure_dns_and_icmp_wg - Allows icmp ping tests for probes alongside configuring dns"
echo "please provide one of the above commands."
exit 1
;;
esac
echo "operation $1 completed successfully."