Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
a54eee8
initial commit - add prereqs install script
serinko Jul 24, 2025
1e1ca65
add env vars prompt
serinko Jul 24, 2025
22af8a0
automate latest binary url env var
serinko Jul 24, 2025
167fe2a
add install node script
serinko Jul 24, 2025
0d85a5d
add modes to nym-node install script
serinko Jul 25, 2025
8eb1b67
start main cli framework
serinko Jul 31, 2025
3fcc8cc
adding branch var for easier deployment and testing
serinko Jul 31, 2025
f2c35d0
add systemd config
serinko Aug 6, 2025
76e9e0a
add proxy and wss setup script
serinko Aug 6, 2025
fb131de
add landing page stub and fix nginx script
serinko Aug 6, 2025
bc4fd0d
add nginx setup
serinko Aug 6, 2025
637cf26
fix typo
serinko Aug 6, 2025
4e2ce80
add checks for existing dir and wg prompt
serinko Aug 7, 2025
fb2f84c
add nginx commands
serinko Aug 7, 2025
13d1756
add service file check
serinko Aug 7, 2025
0caea54
add service file check
serinko Aug 7, 2025
170a8f2
convention alignment
serinko Aug 7, 2025
ca1da38
add checks to nginx setup
serinko Aug 7, 2025
e462448
cleanup old code
serinko Aug 7, 2025
cbaa3e0
add bonding prompt and nym node run fns
serinko Aug 7, 2025
eb3bcf2
fix syntax
serinko Aug 7, 2025
9e1979e
fix syntax
serinko Aug 7, 2025
7afe7d9
fix syntax
serinko Aug 7, 2025
e518b6f
fix syntax
serinko Aug 7, 2025
274125e
fix syntax
serinko Aug 7, 2025
225fa61
fix syntax
serinko Aug 7, 2025
6c43f6b
fix syntax
serinko Aug 7, 2025
e9a4441
fix syntax
serinko Aug 7, 2025
770fadf
add service script to init
serinko Aug 7, 2025
1535c1f
fix syntax
serinko Aug 7, 2025
e5b236c
fix syntax
serinko Aug 7, 2025
176c2e4
add chmod
serinko Aug 7, 2025
06adf09
fix script logic
serinko Aug 8, 2025
4e1b5da
syntax fix
serinko Aug 8, 2025
279b6c9
syntax fix
serinko Aug 8, 2025
d119c20
silent mode trial
serinko Aug 8, 2025
33bafc5
fix evn prompt script
serinko Aug 8, 2025
66b9899
make scripts interactive
serinko Aug 8, 2025
a308b84
indent fix
serinko Aug 8, 2025
a66c38d
correct node-install script
serinko Aug 8, 2025
3cee2b1
initial mixnode setup working - gws need more love
serinko Aug 8, 2025
26283ca
fix bonding function
serinko Aug 14, 2025
f57dc44
syntax fix
serinko Aug 14, 2025
151589a
improve run noide as service script
serinko Aug 14, 2025
6132b44
improve service script
serinko Aug 14, 2025
3076b24
improve run service fn
serinko Aug 14, 2025
3b95fa1
fix logic
serinko Aug 14, 2025
be4193b
beautify
serinko Aug 14, 2025
cc6febd
beautify
serinko Aug 14, 2025
c9e8cec
create run node as service script
serinko Aug 14, 2025
2416ac0
syntax fix
serinko Aug 14, 2025
de96a3c
attempt to resolve memory running out issue
serinko Aug 14, 2025
1419b3d
attempt to resolve memory running out issue
serinko Aug 14, 2025
b8e5765
attempt to resolve memory running out issue
serinko Aug 14, 2025
7197b48
attempt to resolve memory running out issue
serinko Aug 14, 2025
251d7e0
attempt to resolve memory running out issue
serinko Aug 14, 2025
6996b0e
attempt to resolve memory running out issue
serinko Aug 14, 2025
bc539bc
attempt to resolve memory running out issue
serinko Aug 14, 2025
00bdc8e
attempt to resolve memory running out issue
serinko Aug 14, 2025
082bb66
setting wireguard
serinko Aug 14, 2025
0d5ea68
solved memory issues
serinko Aug 14, 2025
458a88c
rename landing page template
serinko Aug 15, 2025
2d00461
modify wireguard enabled fn
serinko Aug 15, 2025
12236bb
layout change
serinko Aug 15, 2025
036dd27
syntax fix
serinko Aug 15, 2025
e5464d7
modify node setup script
serinko Aug 15, 2025
5e7a7b0
sync up envs
serinko Aug 15, 2025
0699f4f
return missing function
serinko Aug 15, 2025
c0ceed4
fix urls
serinko Aug 15, 2025
268bb35
fix network manager script execution
serinko Aug 15, 2025
ac0cecf
fix wss and nginx
serinko Aug 15, 2025
5db2044
fix layout
serinko Aug 15, 2025
d3088c1
tweak WG contion
serinko Aug 15, 2025
ad3c2f6
syntax fix
serinko Aug 15, 2025
5737ca1
add init placeholder
serinko Aug 15, 2025
65e7355
syntax fix
serinko Aug 15, 2025
9a70795
redefine wireguard check logic
serinko Aug 18, 2025
12a5cb7
check if node exists
serinko Aug 18, 2025
12823c4
add argparse and dev option
serinko Aug 18, 2025
11f9164
styling
serinko Aug 18, 2025
5932ae9
add panic
serinko Aug 18, 2025
99434d1
add error message
serinko Aug 18, 2025
f19abb8
improve logic
serinko Aug 18, 2025
a0d64be
improve logic
serinko Aug 18, 2025
3ebbfd0
add arg
serinko Aug 18, 2025
2f93305
add dev arg for all levels
serinko Aug 18, 2025
2a0b969
add confirmation loop
serinko Aug 18, 2025
4adc9d6
styling
serinko Aug 18, 2025
4dc0644
fix bonding question
serinko Aug 18, 2025
16ed2fc
syntax edit
serinko Aug 18, 2025
d79e3cf
syntax edit
serinko Aug 18, 2025
2f76239
syntax edit
serinko Aug 18, 2025
7e021f6
refactor for already bonded nodes
serinko Aug 19, 2025
ed8712f
add default branch on top and define metavar
serinko Aug 19, 2025
652904d
fix node install script
serinko Aug 19, 2025
886bca9
clean and prepare for review
serinko Aug 19, 2025
53a8d9a
indentation fix
serinko Aug 19, 2025
952879d
fix nginx setup
serinko Aug 19, 2025
37e01b4
fix nginx setup
serinko Aug 19, 2025
8a258f1
style cleanup
serinko Aug 19, 2025
0430663
fix try error logic
serinko Aug 19, 2025
e528bdf
tune --dev option to run before command correctly
serinko Aug 19, 2025
b49ef43
fix y/n convention across the modules
serinko Aug 20, 2025
d8cc093
add explorer URL to the message
serinko Aug 21, 2025
9df652a
minor layout fixes
serinko Aug 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions scripts/nym-node-setup/landing-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nym Node</title>
<style>
body {
font-family: sans-serif;
text-align: center;
padding: 2em;
background-color: #111;
color: #0ff;
}
h1 {
margin-bottom: 0.5em;
}
</style>
</head>
<body>
<h1>Nym Node</h1>
<p>This is a devrel testing placeholder page for Nym Node landing page.</p>
</body>
</html>
637 changes: 637 additions & 0 deletions scripts/nym-node-setup/nym-node-cli.py

Large diffs are not rendered by default.

227 changes: 227 additions & 0 deletions scripts/nym-node-setup/nym-node-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#!/bin/bash
set -euo pipefail

echo -e "\n* * * Ensuring ~/nym-binaries exists * * *"
mkdir -p "$HOME/nym-binaries"

# Load env.sh via absolute path if provided, else try ./env.sh
if [[ -n "${ENV_FILE:-}" && -f "${ENV_FILE}" ]]; then
set -a
# shellcheck disable=SC1090
. "${ENV_FILE}"
set +a
elif [[ -f "./env.sh" ]]; then
set -a
# shellcheck disable=SC1091
. ./env.sh
set +a
fi

# check for existing node config and optionally reset
NODE_CONFIG_DIR="$HOME/.nym/nym-nodes/default-nym-node"

check_existing_config() {
# proceed only if dir exists AND has any entries inside
if [[ -d "$NODE_CONFIG_DIR" ]] && find "$NODE_CONFIG_DIR" -mindepth 1 -maxdepth 1 | read -r _; then
echo
echo "Nym node configuration already exist at $NODE_CONFIG_DIR"
echo
echo "Initialising nym-node again will NOT overwrite your existing private keys, only adjust your preferences (like mode, wireguard optionality etc)."
echo
echo "If you want to remove your current node configuration and all data files including nodes keys type 'RESET' and press enter."
echo
read -r -p "To keep your existing node and just change its preferences press enter: " resp

if [[ "${resp}" =~ ^([Rr][Ee][Ss][Ee][Tt])$ ]]; then
echo
read -r -p "We are going to remove the existing node with configuration $NODE_CONFIG_DIR and replace it with a fresh one, do you want to back up the old one first? (y/n) " backup_ans
if [[ "${backup_ans}" =~ ^[Yy]$ ]]; then
ts="$(date +%Y%m%d-%H%M%S)"
backup_dir="$HOME/.nym/backup/$(basename "$NODE_CONFIG_DIR")-$ts"
echo "Backing up to: $backup_dir"
mkdir -p "$(dirname "$backup_dir")"
cp -a "$NODE_CONFIG_DIR" "$backup_dir"
fi
echo "Removing $NODE_CONFIG_DIR ..."
rm -rf "$NODE_CONFIG_DIR"
echo "Old node removed. Proceeding with fresh initialization..."
else
echo "Keeping existing node configuration. Proceeding to re-configure."
export ASK_WG="1"
fi
fi
}

# run the check before any initialization
check_existing_config

echo -e "\n* * * Resolving latest release tag URL * * *"
LATEST_TAG_URL="$(curl -sI -L -o /dev/null -w '%{url_effective}' https://github.com/nymtech/nym/releases/latest)"
# expected example: https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.13-emmental

if [[ -z "${LATEST_TAG_URL}" || "${LATEST_TAG_URL}" != *"/releases/tag/"* ]]; then
echo "ERROR: Could not resolve latest tag URL from GitHub." >&2
exit 1
fi

DOWNLOAD_URL="${LATEST_TAG_URL/tag/download}/nym-node"
NYM_NODE="$HOME/nym-binaries/nym-node"

# if binary already exists, ask to overwrite; if yes, remove first
if [[ -e "${NYM_NODE}" ]]; then
echo
echo -e "\n* * * A nym-node binary already exists at: ${NYM_NODE}"
read -r -p "Overwrite with the latest release? (y/n): " ow_ans
if [[ "${ow_ans}" =~ ^[Yy]$ ]]; then
echo "Removing existing binary to avoid 'text file busy'..."
rm -f "${NYM_NODE}"
else
echo "Keeping existing binary."
fi
fi

echo -e "\n* * * Downloading nym-node from:"
echo " ${DOWNLOAD_URL}"
# only download if file is missing (or we just removed it)
if [[ ! -e "${NYM_NODE}" ]]; then
curl -fL "${DOWNLOAD_URL}" -o "${NYM_NODE}"
fi

echo -e "\n * * * Making binary executable * * *"
chmod +x "${NYM_NODE}"

echo "---------------------------------------------------"
echo "Nym node binary downloaded:"
"${NYM_NODE}" --version || true
echo "---------------------------------------------------"

# check that MODE is set (after sourcing env.sh)
if [[ -z "${MODE:-}" ]]; then
echo "ERROR: Environment variable MODE is not set."
echo "Please export MODE as one of: mixnode, entry-gateway, exit-gateway"
exit 1
fi

# determine public IP (fallback if ifconfig.me fails)
echo -e "\n* * * Discovering public IP (IPv4) * * *"
if ! PUBLIC_IP="$(curl -fsS -4 https://ifconfig.me)"; then
PUBLIC_IP="$(curl -fsS https://api.ipify.org || echo '')"
fi
if [[ -z "${PUBLIC_IP}" ]]; then
echo "WARNING: Could not determine public IP automatically."
fi

# respect existing WIREGUARD; for gateways: prompt if unset OR if we kept config and ASK_WG=1
WIREGUARD="${WIREGUARD:-}"
if [[ ( "$MODE" == "entry-gateway" || "$MODE" == "exit-gateway" ) && ( -n "${ASK_WG:-}" || -z "$WIREGUARD" ) ]]; then
echo
echo "Gateways can also route WireGuard in NymVPN."
echo "Enabling it means your node may be listed as both entry and exit in the app."
# show current default in the prompt if present
def_hint=""
[[ -n "${WIREGUARD}" ]] && def_hint=" [current: ${WIREGUARD}]"
read -r -p "Enable WireGuard support? (y/n)${def_hint}: " answer || true
case "${answer:-}" in
[Yy]* ) WIREGUARD="true" ;;
[Nn]* ) WIREGUARD="false" ;;
* ) : ;; # keep existing value if user just pressed enter
esac
fi
# final default only if still empty
WIREGUARD="${WIREGUARD:-false}"

# persist WIREGUARD to the same env file Python CLI uses
ENV_PATH="${ENV_FILE:-./env.sh}"
if [[ -n "$ENV_PATH" ]]; then
mkdir -p "$(dirname "$ENV_PATH")"
if [[ -f "$ENV_PATH" ]]; then
# replace existing export or append
if grep -qE '^[[:space:]]*export[[:space:]]+WIREGUARD=' "$ENV_PATH"; then
sed -i -E 's|^[[:space:]]*export[[:space:]]+WIREGUARD=.*$|export WIREGUARD="'"$WIREGUARD"'"|' "$ENV_PATH"
else
printf '\nexport WIREGUARD="%s"\n' "$WIREGUARD" >> "$ENV_PATH"
fi
else
printf 'export WIREGUARD="%s"\n' "$WIREGUARD" > "$ENV_PATH"
fi
echo "WIREGUARD=${WIREGUARD} persisted to $ENV_PATH"
fi

# helpers: ensure optional env vars exist (avoid -u issues)
HOSTNAME="${HOSTNAME:-}"
LOCATION="${LOCATION:-}"
EMAIL="${EMAIL:-}"
MONIKER="${MONIKER:-}"
DESCRIPTION="${DESCRIPTION:-}"

# initialize node config
case "${MODE}" in
mixnode)
echo -e "\n* * * Initialising nym-node in mode: mixnode * * *"
"${NYM_NODE}" run \
--mode mixnode \
${PUBLIC_IP:+--public-ips "$PUBLIC_IP"} \
${HOSTNAME:+--hostname "$HOSTNAME"} \
${LOCATION:+--location "$LOCATION"} \
-w \
--init-only
;;
entry-gateway)
echo -e "\n* * * Initialising nym-node in mode: entry-gateway * * *"
"${NYM_NODE}" run \
--mode entry-gateway \
${PUBLIC_IP:+--public-ips "$PUBLIC_IP"} \
${HOSTNAME:+--hostname "$HOSTNAME"} \
${LOCATION:+--location "$LOCATION"} \
--wireguard-enabled "${WIREGUARD}" \
${HOSTNAME:+--landing-page-assets-path "/var/www/${HOSTNAME}"} \
-w \
--init-only
;;
exit-gateway)
echo -e "\n* * * Initialising nym-node in mode: exit-gateway * * *"
if [[ -z "${HOSTNAME:-}" || -z "${LOCATION:-}" ]]; then
echo "ERROR: HOSTNAME and LOCATION must be exported for exit-gateway."
exit 1
fi
"${NYM_NODE}" run \
--mode exit-gateway \
${PUBLIC_IP:+--public-ips "$PUBLIC_IP"} \
--hostname "$HOSTNAME" \
--location "$LOCATION" \
--wireguard-enabled "${WIREGUARD:-false}" \
--announce-wss-port 9001 \
--landing-page-assets-path "/var/www/${HOSTNAME}" \
-w \
--init-only
;;
*)
echo "ERROR: Unsupported MODE: '${MODE}'"
echo "Valid values: mixnode, entry-gateway, exit-gateway"
exit 1
;;
esac

echo
echo "* * * nym-node initialised. Config path should be:"
echo " $HOME/.nym/nym-nodes/default-nym-node/"

# setup description.toml (if init created the dir)
DESC_DIR="$HOME/.nym/nym-nodes/default-nym-node/data"
DESC_FILE="$DESC_DIR/description.toml"

if [[ -d "$DESC_DIR" ]]; then
echo -e "\n* * * Writing node description: $DESC_FILE * * *"
mkdir -p "$DESC_DIR"
cat > "$DESC_FILE" <<EOF
moniker = "${MONIKER}"
website = "${HOSTNAME}"
security_contact = "${EMAIL}"
details = "${DESCRIPTION}"
EOF
echo "* * * Node description saved * * *"
echo "You can edit it later at: $DESC_FILE (restart node to apply)."
else
echo "NOTE: Description directory not found yet ($DESC_DIR)."
echo " It will exist after a full init; you can create the file later."
fi
29 changes: 29 additions & 0 deletions scripts/nym-node-setup/nym-node-prereqs-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# update, upgrade & install dependencies
echo -e "\n* * * Installing needed prerequisities * * *"

apt update -y && apt --fix-broken install
apt upgrade
apt install apt ca-certificates jq curl wget ufw jq tmux pkg-config build-essential libssl-dev git ntp ntpdate neovim tree tmux tig nginx -y
apt install ufw --fix-missing



# enable & setup firewall
echo -e "\n* * * Setting up firewall using ufw * * * "
echo "Please enable the firewall in the next prompt for node proper routing!"
echo
ufw enable
ufw allow 22/tcp # SSH - you're in control of these ports
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 1789/tcp # Nym specific
ufw allow 1790/tcp # Nym specific
ufw allow 8080/tcp # Nym specific - nym-node-api
ufw allow 9000/tcp # Nym Specific - clients port
ufw allow 9001/tcp # Nym specific - wss port
ufw allow 51822/udp # WireGuard
ufw allow 'Nginx Full' && \
ufw reload && \
ufw status
75 changes: 75 additions & 0 deletions scripts/nym-node-setup/setup-env-vars.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# setup_env.sh

# set -euo pipefail

echo -e "\n* * * Setting up environmental variables to ./env.sh * * *"

# detect if we're being sourced
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
__SOURCED=1
else
__SOURCED=0
fi

while true; do
# prompt user
read -rp "Enter hostname (if you don't use a DNS, press enter): " HOSTNAME
read -rp "Enter node location (country code or name): " LOCATION
read -rp "Enter your email: " EMAIL
read -rp "Enter node public moniker (visible in the explorer and NymVPN app): " MONIKER
read -rp "Enter node public description: " DESCRIPTION

# show summary table
echo -e "\nPlease confirm the values you entered:"
echo "---------------------------------------"
printf "%-20s %s\n" "HOSTNAME:" "$HOSTNAME"
printf "%-20s %s\n" "LOCATION:" "$LOCATION"
printf "%-20s %s\n" "EMAIL:" "$EMAIL"
printf "%-20s %s\n" "MONIKER:" "$MONIKER"
printf "%-20s %s\n" "DESCRIPTION:" "$DESCRIPTION"
echo "---------------------------------------"

read -rp "Are these correct? (y/n): " CONFIRM

case "$CONFIRM" in
[Yy]* ) break ;; # confirmed, exit loop
[Nn]* ) echo -e "\nLet's try again...\n" ;; # loop restarts
* ) echo "Please answer y or n." ;;
esac
done

# try to get the latest binary URL (non-fatal if missing)
LATEST_BINARY=$(
curl -fsSL https://github.com/nymtech/nym/releases/latest \
| grep -Eo 'href="/nymtech/nym/releases/download/[^"]+/nym-node"' \
| head -n1 \
| cut -d'"' -f2
)
if [[ -z "${LATEST_BINARY:-}" ]]; then
echo "WARNING: Could not determine latest nym-node binary URL right now. The installer will resolve it later."
fi

PUBLIC_IP=$(curl -fsS -4 https://ifconfig.me || true)
PUBLIC_IP=${PUBLIC_IP:-""}

# write env.sh
{
[[ -n "${LATEST_BINARY:-}" ]] && echo "export LATEST_BINARY=\"https://github.com${LATEST_BINARY}\""
echo "export HOSTNAME=\"${HOSTNAME}\""
echo "export LOCATION=\"${LOCATION}\""
echo "export EMAIL=\"${EMAIL}\""
echo "export MONIKER=\"${MONIKER}\""
echo "export DESCRIPTION=\"${DESCRIPTION}\""
echo "export PUBLIC_IP=\"${PUBLIC_IP}\""
} > env.sh

echo -e "\nVariables saved to ./env.sh"

if [[ $__SOURCED -eq 1 ]]; then
# shellcheck disable=SC1091
. ./env.sh
echo "Loaded into current shell (because you sourced this script)."
else
echo "To load them into your current shell, run: source ./env.sh"
fi
Loading