Files
2026-06-22 22:02:30 +03:00

7.1 KiB

Node

Node is the agent installed on each VPN/proxy server. It registers with Core, receives configuration revisions, applies local services, reports usage, and exposes authenticated runtime actions.

This page is public operator documentation. It describes setup, behavior, environment variables, Docker deployment, and the node HTTP API without requiring source-code access.

Capabilities

  • One-time registration with Core.
  • Persistent auth key storage.
  • Config sync by revision.
  • Xray install, restart, validation, GeoIP update, key generation, and outbound probing.
  • TLS-ECH, X25519, ML-DSA-65, and VLESS encryption key generation.
  • MTProto install and restart.
  • Nginx masking site management.
  • System status reporting with CPU, RAM, disk, network, and process state.
  • Heartbeat reporting.
  • Per-user and per-subscription traffic reporting.
  • Outbound traffic reporting for proxy chains.
  • Cloudflare WARP outbound config generation.
  • Session event reporting.
  • Runtime error reporting.
  • Crash watchdog for local services.

Environment Variables

Variable Required Default Description
PORT No 3001 Local node agent HTTP port.
NODE_ENV No development Runtime mode.
CORE_URL Yes http://localhost:3000 Core HTTP API URL reachable from the node server. Used for registration.
CORE_GRPC_URL Yes localhost:3002 Core gRPC address (host:port). Used for heartbeat, usage reporting, and config sync.
CORE_INSECURE No false Set to true to use plaintext gRPC instead of TLS (for internal/private networks).
REGISTRATION_CODE First start only empty One-time node registration code generated in the panel.
NODE_AUTH_KEY No empty Optional fallback auth key when no key file exists.
HEARTBEAT_INTERVAL_SEC No 30 Heartbeat interval in seconds.

Persistent state is stored under /var/lib/vpnnode.

Keep this directory on a persistent Docker volume. It contains the auth key, generated configs, binaries, stats state, and masking-site files.

Docker Compose

Create a docker-compose.yml on the VPN/proxy server:

version: '3.9'

services:
  node:
    image: git.kiow.ru/nexuma/node:latest
    container_name: nexuma-node
    restart: unless-stopped
    environment:
      PORT: 3001
      CORE_URL: https://core.example.com
      CORE_GRPC_URL: core.example.com:3002
      CORE_INSECURE: "false"
      REGISTRATION_CODE: paste-one-time-code-here
      HEARTBEAT_INTERVAL_SEC: 30
    volumes:
      - node_data:/var/lib/vpnnode
    ports:
      - "3001:3001"
      # Add protocol ports here, for example:
      # - "443:443"
      # - "443:443/udp"
    cap_add:
      - NET_ADMIN
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:3001/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

volumes:
  node_data:

Run:

docker compose up -d

After successful registration, remove REGISTRATION_CODE and redeploy:

docker compose up -d

Registration

  1. In the panel, open Nodes.
  2. Generate a registration code.
  3. Set CORE_URL and REGISTRATION_CODE on the node server.
  4. Start the node container.
  5. Wait until the node appears as registered.
  6. Remove REGISTRATION_CODE.
  7. Keep the node_data volume for future restarts.

If the persistent volume is deleted, the node loses its auth key and must be registered again or started with NODE_AUTH_KEY.

Local HTTP API

Public:

Method Route Purpose
GET /health Health check.

All other routes require x-node-auth-key.

Method Route Purpose
GET /node/status Runtime status and resource usage.
POST /node/apply-config Trigger config pull and apply.
POST /node/xray/restart Restart Xray.
POST /node/xray/install Install an Xray version.
POST /node/geoip/update Update GeoIP/geosite files.
POST /node/xray/probe-outbound Test an outbound connection and return latency.
POST /node/xray/tls-ping Run xray tls ping <domain>; vet a REALITY target (incl. ML-DSA-65 readiness).
GET /node/xray/inbound-preview?tag= Read one inbound from the running config.json, empty user arrays, return { config } (read-only).
POST /node/crypto/x25519 Generate X25519 keys.
POST /node/crypto/mldsa65 Generate an ML-DSA-65 seed/verify pair.
POST /node/crypto/tls-ech Generate TLS-ECH keys.
POST /node/crypto/vlessenc Generate VLESS encryption material.
POST /node/mtproto/restart Restart MTProto processes.
POST /node/mtproto/install Install an MTProto version.
GET /node/nginx/sites List masking sites.
GET /node/nginx/sites/:domain Get one masking site.
GET /node/nginx/sites/:domain/certificate Get certificate and domain validity info.
PUT /node/nginx/sites Upsert one domain masking site (TLS upload or ACME auto-issuance; keyType=ecdsa|rsa, RSA-4096 for ML-DSA-65 self-mask).
PUT /node/nginx/site Upsert legacy default masking site.
GET /node/nginx/site Get current masking site status.
DELETE /node/nginx/sites/:domain Delete one masking site.
DELETE /node/nginx/site Delete current masking site.
POST /node/nginx/restart Restart nginx.
POST /node/warp/generate Register an anonymous Cloudflare WARP account and return a WireGuard outbound config.

These endpoints are intended to be called by Core. Protect the agent port with firewall rules or private networking.

Config Sync

  • The node keeps the latest applied revision locally.
  • The node sends heartbeats to Core over gRPC (CORE_GRPC_URL). If Core's revision is ahead, the heartbeat response sets needSync: true and the node pulls the latest config immediately via gRPC.
  • Core can also push a sync trigger to the node over HTTP (POST /node/apply-config).
  • The node fetches the config from Core and applies it. On success it confirms the applied revision; on failure it reports an error and keeps the previous valid config where possible.

Traffic and Events

The node reports:

  • user traffic
  • subscription traffic attribution
  • per-protocol usage
  • outbound usage
  • online/offline session events
  • service crash and config errors

Traffic is flushed periodically. If reporting fails temporarily, the node keeps pending stats for the next flush where possible.

Status Output

GET /node/status returns operational status including:

  • system uptime
  • CPU usage and core count
  • RAM usage
  • disk usage
  • network transfer rates and totals
  • Xray running state and uptime
  • MTProto process state and connection counts

Operations

  • Use node sync from the panel after changing protocols, routing, or outbounds.
  • Open every configured inbound port in Docker and the server firewall.
  • Keep /var/lib/vpnnode persistent.
  • Keep the node agent API private.
  • Remove one-time registration codes after registration.
  • Rotate auth keys when moving or rebuilding a server.