Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f53da7456 | |||
| 2fdc0dc47b | |||
| a720c95dd7 | |||
| 013941dbaf | |||
| 1af6e1ecdd | |||
| 379c1eb0d0 | |||
| d1e91946e6 | |||
| 402c79f2f5 | |||
| 149b2f4e32 | |||
| 221e809da3 | |||
| 760ee453ea | |||
| 3f072e4e9d | |||
| aa460076f4 |
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
|
||||
[2m2024-11-20T15:53:01.702819Z[0m [32m INFO[0m [2mnym-api/src/main.rs[0m[2m:[0m[2m40[0m[2m:[0m 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>
|
||||
|
||||
@@ -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 sender’s 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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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."
|
||||
Reference in New Issue
Block a user