Skip to content

Commit

Permalink
NS Agent auth with NS API (#5127)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
dynco-nym authored Nov 21, 2024
1 parent aa46007 commit 3f072e4
Show file tree
Hide file tree
Showing 27 changed files with 669 additions and 235 deletions.
28 changes: 20 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ syn = "1"
sysinfo = "0.30.13"
tap = "1.0.1"
tar = "0.4.42"
tempfile = "3.5.0"
tempfile = "3.14"
thiserror = "1.0.64"
time = "0.3.30"
tokio = "1.39"
Expand Down
4 changes: 3 additions & 1 deletion common/cosmwasm-smart-contracts/vesting-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-co
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true, optional = true}
# without this feature, cargo clippy emits a ton of incompatibility warnings
# https://docs.rs/ts-rs/latest/ts_rs/#serde-compatability
ts-rs = { workspace = true, optional = true, features = ["no-serde-warnings"] }

[features]
schema = ["cw2"]
Expand Down
3 changes: 3 additions & 0 deletions common/models/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ rust-version.workspace = true
readme.workspace = true

[dependencies]
anyhow = { workspace = true }
bincode = { workspace = true }
nym-crypto = { path = "../crypto", features = ["asymmetric", "serde"] }
serde = { workspace = true, features = ["derive"] }
94 changes: 94 additions & 0 deletions common/models/src/ns_api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,101 @@
use nym_crypto::asymmetric::ed25519::{PublicKey, Signature, SignatureError};
use serde::{Deserialize, Serialize};

pub mod get_testrun {
use super::*;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Payload {
pub agent_public_key: PublicKey,
pub timestamp: i64,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GetTestrunRequest {
pub payload: Payload,
pub signature: Signature,
}

impl SignedRequest for GetTestrunRequest {
type Payload = Payload;

fn public_key(&self) -> &PublicKey {
&self.payload.agent_public_key
}

fn signature(&self) -> &Signature {
&self.signature
}

fn payload(&self) -> &Self::Payload {
&self.payload
}
}
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TestrunAssignment {
pub testrun_id: i64,
pub assigned_at_utc: i64,
pub gateway_identity_key: String,
}

pub mod submit_results {
use super::*;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Payload {
pub probe_result: String,
pub agent_public_key: PublicKey,
pub assigned_at_utc: i64,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SubmitResults {
pub payload: Payload,
pub signature: Signature,
}

impl SignedRequest for SubmitResults {
type Payload = Payload;

fn public_key(&self) -> &PublicKey {
&self.payload.agent_public_key
}

fn signature(&self) -> &Signature {
&self.signature
}

fn payload(&self) -> &Self::Payload {
&self.payload
}
}
}

pub trait SignedRequest {
type Payload: serde::Serialize;

fn public_key(&self) -> &PublicKey;
fn signature(&self) -> &Signature;
fn payload(&self) -> &Self::Payload;
}

pub trait VerifiableRequest: SignedRequest {
type Error: From<bincode::Error> + From<SignatureError>;

fn verify_signature(&self) -> Result<(), Self::Error> {
bincode::serialize(self.payload())
.map_err(Self::Error::from)
.and_then(|serialized| {
self.public_key()
.verify(serialized, self.signature())
.map_err(Self::Error::from)
})
}
}

impl<T> VerifiableRequest for T
where
T: SignedRequest,
{
type Error = anyhow::Error;
}
1 change: 1 addition & 0 deletions nym-node-status-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nym-gateway-probe
keys/
10 changes: 9 additions & 1 deletion nym-node-status-agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[package]
name = "nym-node-status-agent"
version = "0.1.6"
version = "1.0.0-rc.1"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
Expand All @@ -16,12 +16,20 @@ readme.workspace = true

[dependencies]
anyhow = { workspace = true}
bincode = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive", "env"] }
nym-bin-common = { path = "../common/bin-common", features = ["models"]}
nym-common-models = { path = "../common/models" }
nym-crypto = { path = "../common/crypto", features = ["asymmetric", "rand"] }
rand = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "process"] }
tokio-util = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
reqwest = { workspace = true, features = ["json"] }
serde = { workspace = true }
serde_json = { workspace = true }

[dev-dependencies]
tempfile = { workspace = true }
4 changes: 4 additions & 0 deletions nym-node-status-agent/gen_keypair.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

mkdir -p keys
cargo run --package nym-node-status-agent -- generate-keypair --path keys/private
39 changes: 21 additions & 18 deletions nym-node-status-agent/run.sh
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
#!/bin/bash

set -eu
export ENVIRONMENT=${ENVIRONMENT:-"sandbox"}

environment="qa"

source ../envs/${environment}.env

export RUST_LOG="debug"
probe_git_ref="nym-vpn-core-v1.0.0-rc.6"

crate_root=$(dirname $(realpath "$0"))
gateway_probe_src=$(dirname $(dirname "$crate_root"))/nym-vpn-client/nym-vpn-core
monorepo_root=$(dirname "${crate_root}")
echo "Expecting nym-vpn-client repo at a sibling level of nym monorepo dir"
gateway_probe_src=$(dirname "${monorepo_root}")/nym-vpn-client/nym-vpn-core
echo "gateway_probe_src=$gateway_probe_src"
echo "crate_root=$crate_root"

set -a
source "${monorepo_root}/envs/${ENVIRONMENT}.env"
set +a

export RUST_LOG="info"
export NODE_STATUS_AGENT_SERVER_ADDRESS="http://127.0.0.1"
export NODE_STATUS_AGENT_SERVER_PORT="8000"
export NODE_STATUS_AGENT_PROBE_PATH="$crate_root/nym-gateway-probe"
export NODE_STATUS_AGENT_AUTH_KEY="BjyC9SsHAZUzPRkQR4sPTvVrp4GgaquTh5YfSJksvvWT"

workers=${1:-1}
echo "Running $workers workers in parallel"

# build & copy over GW probe
function copy_gw_probe() {
pushd $gateway_probe_src
git switch main
git pull
git fetch -a
git checkout $probe_git_ref
cargo build --release --package nym-gateway-probe
cp target/release/nym-gateway-probe "$crate_root"
$crate_root/nym-gateway-probe --version
Expand All @@ -32,11 +42,8 @@ function build_agent() {

function swarm() {
local workers=$1
echo "Running $workers in parallel"

build_agent

for ((i = 1; i <= $workers; i++)); do
for ((i = 1; i <= workers; i++)); do
../target/release/nym-node-status-agent run-probe &
done

Expand All @@ -45,11 +52,7 @@ function swarm() {
echo "All agents completed"
}

export NODE_STATUS_AGENT_SERVER_ADDRESS="http://127.0.0.1"
export NODE_STATUS_AGENT_SERVER_PORT="8000"

copy_gw_probe
build_agent

swarm 8

# cargo run -- run-probe
swarm $workers
Loading

0 comments on commit 3f072e4

Please sign in to comment.