Install and register an AeroNyx node
Install the open-source AeroNyx node on a Linux server with the repository's quickstart command, register it with a one-time Nodeboard code, and verify network admission. Also covers relay roles, permissionless join, TEE deployment and AI-assisted installs.
This guide installs the open-source AeroNyx node software on a Linux server, registers it to your Nodeboard operator account with a one-time code, and checks that the network has admitted it. The supported path is the repository script deploy/node/aeronyx-node.sh quickstart, which is the same command Nodeboard generates for you.
- Operator console: app.aeronyx.network
- Source code (AGPL-3.0): github.com/AeroNyxNetwork/AeroNyx
Before you operate a node, read the Node Operator Policy.
Before you begin
| Item | Requirement |
|---|---|
| Operating system | Linux with systemd. The installer installs packages with apt-get (Debian, Ubuntu), dnf or yum. |
| Access | A root shell. Every command in this guide assumes sudo -i first. |
| TUN device | /dev/net/tun must exist for the VPN data plane. |
| Memory | The installer warns below 2 GB and continues. The node is compiled from source on the server, so 4 GB or more is a safer choice. |
| Disk | The installer warns below 4 GB free and continues. Allow 20 GB or more for the build cache and the release backups the upgrade workflow keeps. |
| Inbound ports | 51820/UDP (VPN listener) and 8422/TCP (signed discovery and peer API). Open them in your cloud firewall; the installer does not change inbound firewall rules. |
| Local only | 127.0.0.1:8421 is the local health and management API. Do not expose it. |
Why root: the repository lives in /root/open/AeroNyx, the installer writes /etc/aeronyx and /var/lib/aeronyx with mode 700, and server.toml with mode 600. Commands that read those paths fail for other users, and Git refuses to read a root-owned checkout from another account ("dubious ownership").
What quickstart does
quickstart runs four steps and stops before any host change until you approve:
- Prints the resolved install plan (read-only).
- Waits for you to type
INSTALL. Pressing Enter stops safely. - Runs preflight checks, installs packages and the repository-pinned Rust toolchain, writes
/etc/aeronyx/server.tomlif it does not exist (an existing file is kept), sets up IP forwarding and NAT, builds the node, installs theaeronyx-serversystemd unit, registers the node identity with your code, starts the service, and waits up to 120 seconds for network admission. - Prints
statusand ahealth --jsonsummary.
The admission wait checks that local health reports ok, that the backend returned a fresh policy (the heartbeat round trip works), that discovery has at least one validated signed peer and has completed a gossip round, and, for public nodes, that the node is listed in the public pool.
Step 1: create a registration code
- Sign in to Nodeboard and open Registration Codes.
- Select Generate Code.
- Keep the code private. It expires after 15 minutes, works once, and binds the new node to the account that created it.
Nodeboard then shows a quickstart command, step-by-step preview and install commands, a status command and an AI assistant prompt. Its Install Progress column follows the installer through not_started → planning → running → completed | failed.
The backend checks the code when the installer reaches its register step, which comes after the build. A first build on a small server can take longer than 15 minutes. If registration then fails because the code expired, generate a new code and run quickstart again; the second run reuses the build cache.
Step 2: get or update the repository
aeronyx-node.sh is not a system command. It ships in the repository. This is the clone-or-update line Nodeboard uses:
mkdir -p /root/open && cd /root/open
if [ -d AeroNyx/.git ]; then cd AeroNyx && git fetch origin main && git checkout main && git pull --ff-only origin main; else git clone https://github.com/AeroNyxNetwork/AeroNyx.git AeroNyx && cd AeroNyx; fi
git rev-parse HEAD
Always pass --repo-dir "$PWD" (or --repo-dir /root/open/AeroNyx) to the script. Without it, install, upgrade, health and status default to /opt/aeronyx/AeroNyx.
Step 3: run quickstart
Run quickstart without a code on the command line. When it runs in a terminal, it asks for the code with a hidden prompt, so the code is not echoed, not stored in shell history and not passed as a process argument:
cd /root/open/AeroNyx
./deploy/node/aeronyx-node.sh quickstart --repo-dir "$PWD" --branch main --quick \
--node-name "Example1" --region DE --public-vpn
--node-nameis the name shown in Nodeboard and in the VPN node list.--regionis an ISO 3166-1 alpha-2 country code.--public-vpnpublishes the node in the public VPN pool. Omit it to keep the node private.
At Nodeboard registration code: paste the code and press Enter. Review the plan, then type INSTALL.
About the command Nodeboard generates
Nodeboard's quickstart command puts the code inline, for example AERONYX_REGISTRATION_CODE='<code>' ./deploy/node/aeronyx-node.sh quickstart --repo-dir "$PWD" --branch main --quick. That works, but the code is saved in your shell history. If you use it:
- Check
echo "$HISTCONTROL". If it containsignorespaceorignoreboth, start the command with a space and Bash does not record it. - Otherwise remove the entry afterwards with
history -d <number>.
The code is single-use and expires after 15 minutes, which limits the exposure, but do not paste it into tickets, screenshots or chats.
Non-interactive install
For automation, preview first, then pass the code on standard input. read -rs keeps it off the screen and out of history:
cd /root/open/AeroNyx
./deploy/node/aeronyx-node.sh plan --repo-dir "$PWD" --branch main
read -rs AERONYX_CODE
printf '%s\n' "$AERONYX_CODE" | ./deploy/node/aeronyx-node.sh install \
--repo-dir "$PWD" --branch main --quick --registration-code-stdin \
--node-name "Example1" --region DE --public-vpn
unset AERONYX_CODE
install --quick does not ask for INSTALL. Use it only after you have reviewed the plan.
Step 4: verify the node
cd /root/open/AeroNyx
systemctl is-active aeronyx-server
./deploy/node/aeronyx-node.sh status --repo-dir "$PWD"
./deploy/node/aeronyx-node.sh health --repo-dir "$PWD" --json
A healthy new node shows:
aeronyx-serverisactive, andhealthreportsfail=0- the installer printed
[OK] Node admission acceptedwithhealth=ok,management=freshanddiscovery=ready(andpublic_pool=onlinefor a public node) statusprintsoperator_status=okand a next step- the final JSON line of
health --jsonhas"success":true; warnings appear underchecks
In Nodeboard, the code shows completed, and the node appears under Nodes with its name, region, visibility and a fresh heartbeat. The node detail page shows a Capacity Decision of ready, watch, blocked or waiting.
For day-to-day checks, logs, upgrades and rollback, see Run and check an AeroNyx node.
Optional: join the encrypted relay
A VPN node and an encrypted relay node are separate choices. Relay participation has three parts: a reachable public peer API, the blind ChatRelay store-and-forward role, and the no-exit OnionMiddle role. Both roles are off in the default configuration.
-
Make sure
8422/TCPis reachable from the internet. -
Edit
/etc/aeronyx/server.toml(for examplenano /etc/aeronyx/server.toml) and set these keys in the[discovery]section, using your public address:tomlpublic_endpoint = "http://203.0.113.10:8422" public_discovery = true region = "DE" -
Validate the file:
bashcd /root/open/AeroNyx ./target/release/aeronyx-server validate -c /etc/aeronyx/server.toml -
Enable ChatRelay without restarting. The helper backs up the config, asks you to type
ENABLE CHATRELAY, validates, and restores the backup if validation fails:bash./deploy/node/aeronyx-node.sh chat-relay --repo-dir "$PWD" --enable-chat-relay -
Enable OnionMiddle and restart in one guarded step. It asks you to type
ENABLE ONIONMIDDLEand refuses to restart if the node has active sessions or cannot report a session count:bash./deploy/node/aeronyx-node.sh onion-middle --repo-dir "$PWD" --enable-onion-middle --restartIf it refuses, turn on Maintenance Mode for the node in Nodeboard Settings, wait until active sessions reach zero, and run it again. Do not add
--yes: it skips the confirmation and the active-session guard. -
Check relay readiness:
bash./deploy/node/aeronyx-node.sh relay-probe --repo-dir "$PWD" --two-hop --json
Enabling a role is not the same as being used for routes. A node becomes a route candidate only after peers see it as reachable and fresh path-proof evidence exists. See Node discovery and encrypted relay.
Join without Nodeboard
join installs the node and submits its signed descriptor to a seed node for Stage-A admission, without a registration code or a Nodeboard account:
cd /root/open/AeroNyx
./deploy/node/aeronyx-node.sh join --repo-dir "$PWD" \
--seed http://SEED_PUBLIC_IP:8422 \
--public-endpoint http://YOUR_PUBLIC_IP:8422 --json
--seedtakes 1 to 8 public seed nodes; the request goes to the first one.--public-endpointis your node's reachable peer API. Both must behttporhttpsURLs with a public IP address, not a hostname.- It runs as root on Linux with systemd, and needs Python 3.11 or later, or
python3with thetomlipackage. - It sets six
[discovery]values (enabled,advertise_self,public_discovery,gossip_enabled,public_endpoint,seed_endpoints) and leaves the rest of the file untouched. - If the service is already running with different settings, it stops without changing anything.
--commit <40-hex SHA>pins the exact source commit.--dry-runprints the planned result without changes.--check-onlyverifies an already joined node without sending anything.
A successful result is "admission_stage":"stage_a_candidate" with "route_authority":false and "route_ready":false. Stage-A admission means the seed accepted your descriptor. It does not make the node routeable, list it in Nodeboard or the VPN pool, or make it eligible for payment. The seed's answer travels over plain HTTP unless the seed uses HTTPS, so it is not a cryptographic receipt.
TEE deployment with Docker
The repository also contains a container deployment for confidential VMs that run dstack (Phala Cloud or self-hosted Intel TDX): deploy/node/Dockerfile, deploy/node/compose.tee.yaml, deploy/node/server.tee.toml and deploy/node/tee-entrypoint.sh.
This role is not a VPN node:
vpn.enabled = false: no TUN device, no DNS proxy, no MemChain. The container runs with all Linux capabilities dropped andno-new-privileges.- It runs the onion relay (
advertise_onion_middle = true), ChatRelay and the anonymous mailbox, and exposes only8422. - The node identity comes from the dstack key management service (
[server_key] source = "dstack"). There is no key file. - Pinned seeds.
server.tee.tomlpins four seed nodes withdiscovery.pinned_seeds. A node without an operator snapshot has no other trust anchors, and each pin is reached only over identity-bound TLS. Keep or replace the pins; see Node Discovery and Encrypted Multi-Hop Relay.
To deploy:
- Pick a release image from
ghcr.io/aeronyxnetwork/aeronyx-node. CI buildslinux/amd64images fromnode-v*tags and attaches a build-provenance attestation. Find the digest, for example withdocker buildx imagetools inspect ghcr.io/aeronyxnetwork/aeronyx-node:<tag>. - In
compose.tee.yaml, replaceIMAGE_DIGESTwith that digest. Always pin by digest, not by tag; in a dstack VM the compose file is part of the measured deployment. - Set
AERONYX_PUBLIC_ENDPOINTto thehttps://origin that the dstack gateway assigns to port 8422. The entrypoint refuses any other scheme. - Optionally set
AERONYX_REGION(defaulttee). - For the first start only, provide
AERONYX_REGISTRATION_CODEas an encrypted secret. The entrypoint pipes it toaeronyx-server register --code-stdin. Afternode_info.jsonexists in the/var/lib/aeronyxvolume, the code is no longer needed.
The container does not include aeronyx-node.sh. Monitor a TEE node in Nodeboard and through its public discovery API.
Installing with an AI coding assistant
Terminal assistants such as Claude Code, Codex, OpenClaw or Hermes can run this procedure. Nodeboard offers a ready-made AI assistant prompt next to each code. These rules apply whichever assistant you use.
The human operator:
- provides the server and approves every host change
- types
INSTALLpersonally after reading the plan - keeps the registration code private. Nodeboard's AI prompt contains the code, so pasting it shares the code with the assistant's provider. To avoid that, let the assistant update the repository and run the code-free
plan, then runquickstartyourself and type the code at the hidden prompt. Hand back to the assistant for verification.
The assistant must:
- use only
deploy/node/aeronyx-node.shfromgithub.com/AeroNyxNetwork/AeroNyx, and pass--repo-dir - use only options the script documents (
./deploy/node/aeronyx-node.sh help). Unknown options fail; for example,--api-basestops the installer withUnknown option. - show or summarise the plan before any host change and wait for approval
- run
statusafter install or upgrade and reportoperator_status,operator_title,operator_detailandoperator_next_step, thenhealth --jsonwhen more detail is needed - report warnings as warnings, and not declare success from a running process alone
- prefer
upgrade --no-restartunless you approve a maintenance-window restart - never use
--forceor--yes, and never restart a node with active sessions, without your explicit approval - never print registration codes, private keys, API secrets, client public IPs, destinations, DNS contents, packet payloads or chat plaintext
Done means:
- the repository is on
mainand the commit is reported - quickstart or install finished with
Node admission accepted statusreportsoperator_status=ok, or each warning is explainedhealth --jsonreports"success":true- Nodeboard shows the node with a fresh heartbeat and a Capacity Decision
- Alerts / Events → Incident Closure has no unreviewed
openitem for the node - you know the node's detail page in Nodeboard
What a registered node reports
Local diagnostics (status, health, relay-probe) print aggregate values only: service state, capacity, packet counters, discovery readiness and proof outcomes.
A registered VPN node also reports each VPN session to the AeroNyx backend: session ID, the client's key (client_wallet), the tunnel's virtual IP, byte counts, timing and link quality. It does not report client public IPs, destinations, DNS contents or packet payloads. Operators can see these session records for their own nodes in Nodeboard; see the Nodeboard operator console guide. Like any VPN server, the node itself handles client traffic in the clear at the exit, so operators must follow the Node Operator Policy.
Related pages
- Run and check an AeroNyx node
- Nodeboard operator console guide
- Node discovery and encrypted relay
- Network stats and privacy boundary
Frequently asked questions
Where does aeronyx-node.sh come from?
It is a file in the AeroNyx node repository at deploy/node/aeronyx-node.sh, not a system command. Clone or update https://github.com/AeroNyxNetwork/AeroNyx into /root/open/AeroNyx and run it from there with --repo-dir "$PWD".
How do I keep the registration code out of my shell history?
Run quickstart without the code and type it at the hidden Nodeboard registration code: prompt. For scripts, read it with read -rs and pipe it to install --quick --registration-code-stdin.
Why does the script look in /opt/aeronyx/AeroNyx?
That is the script's built-in default for --repo-dir, while Nodeboard clones into /root/open/AeroNyx. Pass --repo-dir on every command so install, health, status and upgrade all use the checkout the service runs from.
What happens if my code expires during the install?
The register step fails and the installer stops before it starts the service. The code is checked after the build, so generate a new code and run quickstart again; the second run reuses the build cache.
Do I need Nodeboard to run a node?
No, join installs a node and submits it for Stage-A admission without a registration code. A joined node is not routeable, not listed in Nodeboard or the VPN pool, and not eligible for payment.
Can I run a node in a confidential VM?
Yes, the repository includes a Docker deployment for dstack confidential VMs that runs the onion relay, ChatRelay and anonymous mailbox. It does not provide VPN service and takes its identity from the dstack key management service.
<!-- faq:end -->