Files
docs/node.md
T
2026-06-14 11:44:09 +03:00

183 lines
6.9 KiB
Markdown

# 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:
```yaml
version: '3.9'
services:
node:
image: 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:
```bash
docker compose up -d
```
After successful registration, remove `REGISTRATION_CODE` and redeploy:
```bash
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). |
| `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.