This commit is contained in:
2026-06-01 02:48:06 +03:00
parent 43f24fe25f
commit ee4c6211ae
8 changed files with 165 additions and 45 deletions
+3
View File
@@ -56,6 +56,7 @@ services:
restart: unless-stopped restart: unless-stopped
environment: environment:
PORT: 3000 PORT: 3000
GRPC_PORT: 3002
DB_HOST: your-postgres-host DB_HOST: your-postgres-host
DB_PORT: 5432 DB_PORT: 5432
DB_USER: postgres DB_USER: postgres
@@ -70,6 +71,7 @@ services:
CORS_ORIGINS: https://panel.example.com CORS_ORIGINS: https://panel.example.com
ports: ports:
- "3000:3000" - "3000:3000"
- "3002:3002"
depends_on: depends_on:
- redis - redis
networks: networks:
@@ -124,6 +126,7 @@ services:
environment: environment:
PORT: 3001 PORT: 3001
CORE_URL: https://core.example.com CORE_URL: https://core.example.com
CORE_GRPC_URL: core.example.com:3002
REGISTRATION_CODE: paste-one-time-code-here REGISTRATION_CODE: paste-one-time-code-here
HEARTBEAT_INTERVAL_SEC: 30 HEARTBEAT_INTERVAL_SEC: 30
volumes: volumes:
+34 -3
View File
@@ -2,10 +2,20 @@
These routes are consumed only by the node agent and require the `x-node-auth-key` header. These routes are consumed only by the node agent and require the `x-node-auth-key` header.
## Transport
The node uses two transports to communicate with Core:
- **HTTP** — registration only (`POST /node/register`).
- **gRPC** — all other node-to-core calls: heartbeat, usage reporting, config sync, and stats. Core listens on `GRPC_PORT` (default `3002`). The node connects via `CORE_GRPC_URL`. Set `CORE_INSECURE=true` on the node to use plaintext instead of TLS.
The HTTP routes for heartbeat, usage, config, and error remain available as a fallback but the node agent uses gRPC by default.
## Authentication ## Authentication
- `POST /node/register` is the only public route in this group. - `POST /node/register` is the only public route in this group.
- All other routes require a valid node auth key. - All other HTTP routes require the `x-node-auth-key` header.
- gRPC calls pass the auth key as the `x-node-auth-key` metadata header (or in the `authKey` request field as fallback).
- The auth key is issued by Core during registration and persisted on the node side. - The auth key is issued by Core during registration and persisted on the node side.
## Route table ## Route table
@@ -91,6 +101,7 @@ The config returned by `GET /node/config/latest` has this structure:
{ {
revision: number revision: number
clientMap: Record<string, { userId: number; subscriptionId: number | null }> clientMap: Record<string, { userId: number; subscriptionId: number | null }>
mtprotoClientMap: Record<string, { userId: number; subscriptionId: number | null }>
services: { services: {
xray?: XrayServiceConfig xray?: XrayServiceConfig
mtproto?: MtProtoServiceConfig mtproto?: MtProtoServiceConfig
@@ -100,10 +111,11 @@ The config returned by `GET /node/config/latest` has this structure:
Important notes: Important notes:
- `clientMap` maps subscription link UUIDs to the user and subscription used for traffic attribution. - `clientMap` maps subscription link UUIDs to the user and subscription used for xray traffic attribution.
- `mtprotoClientMap` maps MTProto link UUIDs to the user and subscription — used for telemt traffic attribution.
- `services.xray` contains the Xray inbounds, routing, and outbounds for the node. - `services.xray` contains the Xray inbounds, routing, and outbounds for the node.
- `services.mtproto` contains MTProto inbounds for `telemt`. - `services.mtproto` contains MTProto inbounds for `telemt`.
- the node stores the current revision and client map locally after a successful apply - The node stores the current revision and client maps locally after a successful apply.
## Route semantics ## Route semantics
@@ -114,3 +126,22 @@ Important notes:
- `POST /node/config/applied` marks the node sync status as `synced`. - `POST /node/config/applied` marks the node sync status as `synced`.
- `POST /node/error` marks the node as `error` and the sync status as `failed`. - `POST /node/error` marks the node as `error` and the sync status as `failed`.
## gRPC interface (`NodeService`)
Core exposes a gRPC service that the node agent uses for all real-time communication. The service name is `nodeservice.NodeService` and is defined in `proto/node-service.proto`.
Authentication: pass `x-node-auth-key` as gRPC metadata (or in the `authKey` field of the request as fallback).
| Method | Request fields | Response fields | Notes |
| --- | --- | --- | --- |
| `Heartbeat` | `authKey`, `revision?`, `ip?` | `ok`, `needSync` | Equivalent to `POST /node/heartbeat` |
| `ReportUsage` | `authKey`, `entries[]` | `ok` | Equivalent to `POST /node/usage` |
| `ReportOutboundUsage` | `authKey`, `items[]` | `ok` | Equivalent to `POST /node/outbound-usage` |
| `GetLatestConfig` | `authKey` | `revision`, `clientMapJson`, `mtprotoClientMapJson`, `servicesJson` | Config fields are JSON-encoded strings |
| `ConfirmConfigApplied` | `authKey`, `revision` | `ok` | Equivalent to `POST /node/config/applied` |
| `ReportNodeStats` | `authKey`, system metrics fields | `ok` | Reports CPU/RAM/disk/network/xray/mtproto snapshot; stored in Redis; drives `GET /admin/nodes/:id/runtime-status` and stats history |
`ReportNodeStats` fields: `uptimeSeconds`, `cpuPercent`, `cpuCores`, `ramUsed`, `ramTotal`, `diskUsed`, `diskTotal`, `netRxPerSec`, `netTxPerSec`, `netRxTotal`, `netTxTotal`, `xrayRunning`, `xrayUptimeSeconds?`, `mtprotoJson`.
The node sends `ReportNodeStats` on every heartbeat cycle. `GET /admin/nodes/:id/runtime-status` returns the latest stored snapshot without polling the node; `?fromNode=true` forces a live HTTP fetch instead.
+69 -14
View File
@@ -20,6 +20,7 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| `POST` | `/auth/refresh` | `RefreshTokenDto` | Returns new JWT tokens | | `POST` | `/auth/refresh` | `RefreshTokenDto` | Returns new JWT tokens |
| `POST` | `/auth/telegram` | `TelegramAuthDto` | Telegram OAuth login | | `POST` | `/auth/telegram` | `TelegramAuthDto` | Telegram OAuth login |
| `GET` | `/auth/telegram/bot-id` | none | `{ botId }` | | `GET` | `/auth/telegram/bot-id` | none | `{ botId }` |
| `GET` | `/public/settings/access` | none | Public panel and subscription host/path settings |
| `GET` | `/sub/:uuid/info` | query string and request IP | Returns `SubscriptionInfo` JSON | | `GET` | `/sub/:uuid/info` | query string and request IP | Returns `SubscriptionInfo` JSON |
| `GET` | `/sub/:uuid` | `format=v2ray|clash|singbox` | Returns encoded subscription content | | `GET` | `/sub/:uuid` | `format=v2ray|clash|singbox` | Returns encoded subscription content |
@@ -37,22 +38,26 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| `GET` | `/auth/me` | none | Current user without `passwordHash` | | `GET` | `/auth/me` | none | Current user without `passwordHash` |
| `POST` | `/auth/telegram/link` | `TelegramAuthDto` | Links Telegram to the current account | | `POST` | `/auth/telegram/link` | `TelegramAuthDto` | Links Telegram to the current account |
| `DELETE` | `/auth/telegram/unlink` | none | Unlinks Telegram from the current account | | `DELETE` | `/auth/telegram/unlink` | none | Unlinks Telegram from the current account |
| `POST` | `/auth/referral-code/apply` | `{ code: string }` | Pending user self-approves via a referral code |
| `GET` | `/me` | none | Current user without `passwordHash` | | `GET` | `/me` | none | Current user without `passwordHash` |
| `PATCH` | `/me/profile` | `UpdateProfileDto` | Updates name, email, or password | | `PATCH` | `/me/profile` | `UpdateProfileDto` | Updates name, email, or password |
| `GET` | `/me/stats` | none | `UserStats` | | `GET` | `/me/stats` | none | `UserStats` |
| `GET` | `/me/traffic/daily` | none | Daily traffic series | | `GET` | `/me/traffic/daily` | none | Daily traffic series |
| `GET` | `/me/traffic/hourly-dist` | none | Hour-of-day distribution | | `GET` | `/me/traffic/hourly-dist` | none | Hour-of-day distribution |
| `GET` | `/me/traffic` | `period=30d|7d|1d|1h` | Period traffic series | | `GET` | `/me/traffic` | `period=30d|7d|1d|1h` | Period traffic series |
| `GET` | `/me/traffic/raw` | none | Raw per-minute traffic records |
| `GET` | `/me/referral/referees` | none | Users invited by the current user |
| `GET` | `/me/subscriptions/:id/usage` | `from?`, `to?` | Per-subscription usage for the current user |
| `GET` | `/me/node-protocols` | none | Available node protocols for the current user |
| `GET` | `/me/balance` | none | `{ balance }` | | `GET` | `/me/balance` | none | `{ balance }` |
| `GET` | `/me/balance/transactions` | none | User balance transaction history | | `GET` | `/me/balance/transactions` | none | User balance transaction history |
| `GET` | `/me/subscriptions` | none | User subscriptions | | `GET` | `/me/subscriptions` | none | User subscriptions |
| `GET` | `/me/links` | none | All user subscription links | | `GET` | `/me/links` | none | All user subscription links |
| `GET` | `/me/configs` | none | Available node/protocol configs for the current user | | `GET` | `/me/configs` | none | Available node/protocol configs for the current user |
| `POST` | `/me/links` | `CreateUserLinkDto` | Creates a combined link or a per-subscription link | | `POST` | `/me/links` | `CreateUserLinkDto` | Creates a combined link or a per-subscription link |
| `POST` | `/me/subscriptions` | `CreateSubscriptionLinkDto` | Legacy per-subscription link creation | | `POST` | `/me/links/:id/reset` | none | Resets the link UUID |
| `POST` | `/me/subscriptions/:id/reset` | none | Resets the selected link UUID | | `PATCH` | `/me/links/:id` | `UpdateUserLinkDto` | Renames, enables/disables, or reconfigures a link |
| `PATCH` | `/me/subscriptions/links/:id` | `UpdateSubscriptionLinkDto` | Renames or reconfigures a link | | `DELETE` | `/me/links/:id` | none | Deletes a link |
| `DELETE` | `/me/subscriptions/links/:id` | none | Deletes a link |
| `PATCH` | `/me/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew for own subscription | | `PATCH` | `/me/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew for own subscription |
## Admin routes - users ## Admin routes - users
@@ -60,10 +65,14 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| Method | Route | Input | Output / Notes | | Method | Route | Input | Output / Notes |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `GET` | `/admin/users` | `page`, `limit`, `search`, `status`, `isBlocked` | Paginated users | | `GET` | `/admin/users` | `page`, `limit`, `search`, `status`, `isBlocked` | Paginated users |
| `GET` | `/admin/users/all` | none | All users without pagination |
| `GET` | `/admin/users/short` | none | Minimal user list (id, name, email) |
| `POST` | `/admin/users` | `CreateAdminUserDto` | Creates a user account |
| `GET` | `/admin/users/:id` | none | User detail | | `GET` | `/admin/users/:id` | none | User detail |
| `GET` | `/admin/users/:id/stats` | none | User stats | | `GET` | `/admin/users/:id/stats` | none | User stats |
| `PATCH` | `/admin/users/:id` | `UpdateUserDto` | Updates email, password, role, block flag, name, comment | | `PATCH` | `/admin/users/:id` | `UpdateUserDto` | Updates email, password, role, block flag, name, comment |
| `PATCH` | `/admin/users/:id/status` | `UpdateUserStatusDto` | Approves, rejects, or restores a user | | `PATCH` | `/admin/users/:id/status` | `UpdateUserStatusDto` | Approves, rejects, or restores a user |
| `GET` | `/admin/users/:id/referees` | none | Users invited by this user |
| `DELETE` | `/admin/users/:id` | none | Deletes a user | | `DELETE` | `/admin/users/:id` | none | Deletes a user |
## Admin routes - balance ## Admin routes - balance
@@ -92,20 +101,22 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| `GET` | `/admin/subscriptions` | `page`, `limit`, `status`, `userId`, `tariffId` | Paginated subscriptions | | `GET` | `/admin/subscriptions` | `page`, `limit`, `status`, `userId`, `tariffId` | Paginated subscriptions |
| `GET` | `/admin/users/:id/subscriptions` | none | Subscriptions for a user | | `GET` | `/admin/users/:id/subscriptions` | none | Subscriptions for a user |
| `GET` | `/admin/users/:id/links` | none | All links for a user | | `GET` | `/admin/users/:id/links` | none | All links for a user |
| `GET` | `/admin/users/:id/node-protocols` | none | Available node protocols for a user |
| `GET` | `/admin/subscriptions/:id/usage` | `from?`, `to?` | Per-subscription usage (admin) |
| `POST` | `/admin/subscriptions` | `CreateSubscriptionDto` | Creates a subscription | | `POST` | `/admin/subscriptions` | `CreateSubscriptionDto` | Creates a subscription |
| `DELETE` | `/admin/subscriptions/:id` | none | Cancels a subscription | | `DELETE` | `/admin/subscriptions/:id` | none | Cancels a subscription |
| `PATCH` | `/admin/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew | | `PATCH` | `/admin/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew |
| `POST` | `/admin/users/:id/links` | `CreateUserLinkDto` | Creates a link for any user | | `POST` | `/admin/users/:id/links` | `CreateUserLinkDto` | Creates a link for any user |
| `POST` | `/admin/subscriptions/:id/links` | `CreateSubscriptionLinkDto` | Creates a link for a specific subscription | | `POST` | `/admin/links/:id/reset` | none | Resets a link UUID |
| `POST` | `/admin/subscriptions/links/:id/reset` | none | Resets a link UUID | | `PATCH` | `/admin/links/:id` | `UpdateUserLinkDto` | Updates a link |
| `PATCH` | `/admin/subscriptions/links/:id` | `UpdateSubscriptionLinkDto` | Updates a link | | `DELETE` | `/admin/links/:id` | none | Deletes a link |
| `DELETE` | `/admin/subscriptions/links/:id` | none | Deletes a link |
## Admin routes - nodes ## Admin routes - nodes
| Method | Route | Input | Output / Notes | | Method | Route | Input | Output / Notes |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `GET` | `/admin/nodes` | `page`, `limit` | Paginated nodes | | `GET` | `/admin/nodes` | `page`, `limit` | Paginated nodes |
| `GET` | `/admin/nodes/all` | none | All nodes without pagination |
| `GET` | `/admin/nodes/status` | none | Computed node status list | | `GET` | `/admin/nodes/status` | none | Computed node status list |
| `GET` | `/admin/nodes/outbound-options` | none | Node/protocol outbound options | | `GET` | `/admin/nodes/outbound-options` | none | Node/protocol outbound options |
| `GET` | `/admin/nodes/:id` | none | Node detail | | `GET` | `/admin/nodes/:id` | none | Node detail |
@@ -127,21 +138,31 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| `POST` | `/admin/nodes/:id/update-geoip` | `UpdateGeoipDto` | Updates stored geoip/geosite URLs and node files | | `POST` | `/admin/nodes/:id/update-geoip` | `UpdateGeoipDto` | Updates stored geoip/geosite URLs and node files |
| `POST` | `/admin/nodes/:id/crypto/x25519` | none | Generates x25519 keys | | `POST` | `/admin/nodes/:id/crypto/x25519` | none | Generates x25519 keys |
| `POST` | `/admin/nodes/:id/crypto/mldsa65` | none | Generates ML-DSA-65 keys | | `POST` | `/admin/nodes/:id/crypto/mldsa65` | none | Generates ML-DSA-65 keys |
| `POST` | `/admin/nodes/:id/crypto/tls-ech` | `{ serverName? }` | Generates TLS-ECH keys |
| `POST` | `/admin/nodes/:id/crypto/vlessenc` | `{ authentication? }` | Generates VLESS encryption material |
| `GET` | `/admin/nodes/xray/versions` | none | Cached xray release tags | | `GET` | `/admin/nodes/xray/versions` | none | Cached xray release tags |
| `GET` | `/admin/nodes/mtproto/versions` | none | Cached telemt release tags | | `GET` | `/admin/nodes/mtproto/versions` | none | Cached telemt release tags |
| `PATCH` | `/admin/nodes/:id/routing-config` | `UpdateNodeRoutingConfigDto` | Updates per-node routing config | | `PATCH` | `/admin/nodes/:id/routing-config` | `UpdateNodeRoutingConfigDto` | Updates per-node routing config |
| `POST` | `/admin/nodes/:id/routing-config/apply-template` | `ApplyRoutingTemplateDto` | Copies a routing template into the node config |
| `DELETE` | `/admin/nodes/:id/routing-config` | none | Clears per-node routing config | | `DELETE` | `/admin/nodes/:id/routing-config` | none | Clears per-node routing config |
| `PATCH` | `/admin/nodes/:id/observatory` | `UpdateNodeObservatoryDto` | Updates observatory (outbound health check) settings |
| `GET` | `/admin/nodes/:id/routing-balancers` | none | Node routing balancers |
| `POST` | `/admin/nodes/:id/routing-balancers` | `CreateNodeRoutingBalancerDto` | Creates a routing balancer |
| `PATCH` | `/admin/nodes/:id/routing-balancers/:balancerId` | `UpdateNodeRoutingBalancerDto` | Updates a routing balancer |
| `DELETE` | `/admin/nodes/:id/routing-balancers/:balancerId` | none | Deletes a routing balancer |
| `PUT` | `/admin/nodes/:id/nginx/site` | multipart form-data | Uploads cert/key/html for a masking site | | `PUT` | `/admin/nodes/:id/nginx/site` | multipart form-data | Uploads cert/key/html for a masking site |
| `GET` | `/admin/nodes/:id/nginx/site` | none | Returns nginx masking site status | | `GET` | `/admin/nodes/:id/nginx/site` | none | Returns nginx masking site status |
| `GET` | `/admin/nodes/:id/nginx/sites/:domain/certificate` | none | Returns certificate and domain validity info |
| `DELETE` | `/admin/nodes/:id/nginx/sites/:domain` | none | Deletes a masking site | | `DELETE` | `/admin/nodes/:id/nginx/sites/:domain` | none | Deletes a masking site |
| `POST` | `/admin/nodes/:id/install-mtproto` | body `{ version?: string }` | Installs telemt and stores the version | | `POST` | `/admin/nodes/:id/install-mtproto` | body `{ version?: string }` | Installs telemt and stores the version |
| `POST` | `/admin/nodes/:id/restart-mtproto` | none | Restarts telemt | | `POST` | `/admin/nodes/:id/restart-mtproto` | none | Restarts telemt |
| `GET` | `/admin/nodes/:id/runtime-status` | none | Live runtime status from the node | | `GET` | `/admin/nodes/:id/runtime-status` | `fromNode=true` forces a live fetch | Live runtime status from the node |
| `GET` | `/admin/nodes/:id/stats-history` | `since` (timestamp) | Node stats history since a given time |
| `GET` | `/admin/nodes/:id/outbounds` | none | Node outbounds | | `GET` | `/admin/nodes/:id/outbounds` | none | Node outbounds |
| `POST` | `/admin/nodes/:id/outbounds` | `CreateNodeOutboundDto` | Creates a node outbound | | `POST` | `/admin/nodes/:id/outbounds` | `CreateNodeOutboundDto` | Creates a node outbound |
| `PATCH` | `/admin/nodes/:id/outbounds/:outboundId` | partial `CreateNodeOutboundDto` | Updates a node outbound | | `PATCH` | `/admin/nodes/:id/outbounds/:outboundId` | partial `CreateNodeOutboundDto` | Updates a node outbound |
| `DELETE` | `/admin/nodes/:id/outbounds/:outboundId` | none | Deletes a node outbound | | `DELETE` | `/admin/nodes/:id/outbounds/:outboundId` | none | Deletes a node outbound |
| `POST` | `/admin/nodes/:id/outbounds/:outboundId/probe` | `{ probeUrl? }` | Probes a node outbound and returns latency |
| `POST` | `/admin/nodes/:id/outbounds/probe-builtin` | `{ tag, probeUrl? }` | Probes a builtin outbound (direct/block/etc.) |
| `POST` | `/admin/nodes/:id/warp/generate` | none | Registers an anonymous WARP account on the node and returns a WireGuard outbound settings object | | `POST` | `/admin/nodes/:id/warp/generate` | none | Registers an anonymous WARP account on the node and returns a WireGuard outbound settings object |
## Admin routes - routing rule sets ## Admin routes - routing rule sets
@@ -177,6 +198,26 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `POST` | `/admin/xray/parse-link` | `{ link }` | Parses a proxy link into outbound config | | `POST` | `/admin/xray/parse-link` | `{ link }` | Parses a proxy link into outbound config |
## Admin routes - settings
| Method | Route | Input | Output / Notes |
| --- | --- | --- | --- |
| `GET` | `/admin/settings/:category` | none | Returns settings for the given category (`panel`, `subscription`, `telegram`) |
| `PATCH` | `/admin/settings/panel` | `PanelSettingsDto` | Updates panel settings |
| `PATCH` | `/admin/settings/subscription` | `SubscriptionSettingsDto` | Updates subscription delivery settings |
| `PATCH` | `/admin/settings/telegram` | `TelegramSettingsDto` | Updates Telegram bot settings |
## Admin routes - broadcasts
| Method | Route | Input | Output / Notes |
| --- | --- | --- | --- |
| `POST` | `/admin/broadcasts` | `CreateBroadcastDto` | Creates a Telegram broadcast |
| `GET` | `/admin/broadcasts` | none | Broadcast list with delivery counts |
| `GET` | `/admin/broadcasts/:id` | none | Broadcast detail |
| `PATCH` | `/admin/broadcasts/:id` | `UpdateBroadcastDto` | Updates a broadcast |
| `DELETE` | `/admin/broadcasts/:id` | none | Deletes a broadcast |
| `GET` | `/admin/broadcasts/:id/deliveries` | `status?`, `page?`, `limit?` | Delivery log for a broadcast |
## DTO summary ## DTO summary
### Auth ### Auth
@@ -185,11 +226,13 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
- `RegisterDto` - `email`, `password` - `RegisterDto` - `email`, `password`
- `RefreshTokenDto` - `refreshToken` - `RefreshTokenDto` - `refreshToken`
- `TelegramAuthDto` - `tgAuthResult` - `TelegramAuthDto` - `tgAuthResult`
- `ApplyReferralCodeDto` - `code`
### Users ### Users
- `CreateAdminUserDto` - `email`, `password`, `role?`, `name?`
- `UpdateProfileDto` - `name?`, `email?`, `password?` - `UpdateProfileDto` - `name?`, `email?`, `password?`
- `UpdateUserDto` - `email?`, `password?`, `role?`, `isBlocked?`, `name?`, `comment?` - `UpdateUserDto` - `email?`, `password?`, `role?`, `isBlocked?`, `name?`, `comment?`, `allowedToInvite?`
- `UpdateUserStatusDto` - `status: 'active' | 'pending' | 'rejected'` - `UpdateUserStatusDto` - `status: 'active' | 'pending' | 'rejected'`
### Balance ### Balance
@@ -215,9 +258,8 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
### Subscriptions ### Subscriptions
- `CreateSubscriptionDto` - `userId`, `tariffId`, `startAt?` - `CreateSubscriptionDto` - `userId`, `tariffId`, `startAt?`
- `CreateSubscriptionLinkDto` - `subscriptionId`, `name?`
- `CreateUserLinkDto` - `subscriptionId?`, `name?`, `selectedNodeIds?` - `CreateUserLinkDto` - `subscriptionId?`, `name?`, `selectedNodeIds?`
- `UpdateSubscriptionLinkDto` - `name?`, `isEnabled?`, `selectedNodeIds?` - `UpdateUserLinkDto` - `name?`, `isEnabled?`, `selectedNodeIds?`
- `UpdateAutoRenewDto` - `autoRenew` - `UpdateAutoRenewDto` - `autoRenew`
### Nodes ### Nodes
@@ -244,6 +286,9 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
- `config?` - `config?`
- `targetNodeId?` - `targetNodeId?`
- `targetProtocolId?` - `targetProtocolId?`
- `UpdateNodeObservatoryDto` - observatory settings for outbound health probing
- `CreateNodeRoutingBalancerDto` - `tag`, `selector`, `strategy?`, `fallbackTag?`
- `UpdateNodeRoutingBalancerDto` - partial `CreateNodeRoutingBalancerDto`
- `CreateRoutingRuleSetDto` - `CreateRoutingRuleSetDto`
- `name` - `name`
- `description?` - `description?`
@@ -257,7 +302,6 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
- `blockCryptominers?` - `blockCryptominers?`
- `blockAdult?` - `blockAdult?`
- `UpdateNodeRoutingConfigDto` - same routing fields as above, without `name` and `description` - `UpdateNodeRoutingConfigDto` - same routing fields as above, without `name` and `description`
- `ApplyRoutingTemplateDto` - `templateId`
- `InstallXrayDto` - `version` - `InstallXrayDto` - `version`
- `UpdateGeoipDto` - `geoipUrl?`, `geositeUrl?` - `UpdateGeoipDto` - `geoipUrl?`, `geositeUrl?`
@@ -313,3 +357,14 @@ This file lists the current HTTP routes exposed by Core, grouped by access level
- `leastPing` - `leastPing`
- `leastLoad` - `leastLoad`
### Settings
- `PanelSettingsDto` - `allowedHosts?`, `rootPath?`
- `SubscriptionSettingsDto` - `allowedHosts?`, `rootPath?`, `updateInterval?`, `name?`, `supportUrl?`, `websiteUrl?`
- `TelegramSettingsDto` - `botToken?`
### Broadcasts
- `CreateBroadcastDto` - `text`, `filters?` (`{ nodeIds?: number[] }`), `scheduledAt?`
- `UpdateBroadcastDto` - partial `CreateBroadcastDto`
+20 -15
View File
@@ -16,6 +16,9 @@ This page is public operator documentation. It describes behavior, API, environm
- Routing rule sets with rules, balancers, and blocking options. - Routing rule sets with rules, balancers, and blocking options.
- External subscription source ingestion and testing. - External subscription source ingestion and testing.
- Public subscription exports for VPN clients. - Public subscription exports for VPN clients.
- Platform settings management (panel, subscription delivery, Telegram).
- Telegram broadcast messages with user filtering and delivery tracking.
- Referral system with code-based self-approval for pending users.
- Audit logs, usage queries, metrics, and health checks. - Audit logs, usage queries, metrics, and health checks.
## Environment Variables ## Environment Variables
@@ -23,6 +26,7 @@ This page is public operator documentation. It describes behavior, API, environm
| Variable | Required | Default | Description | | Variable | Required | Default | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `PORT` | No | `3000` | HTTP port. | | `PORT` | No | `3000` | HTTP port. |
| `GRPC_PORT` | No | `3002` | gRPC port for node-to-core communication. Expose this port to node servers. |
| `NODE_ENV` | No | `development` | Runtime mode. | | `NODE_ENV` | No | `development` | Runtime mode. |
| `DB_HOST` | Yes | `localhost` | Database host. | | `DB_HOST` | Yes | `localhost` | Database host. |
| `DB_PORT` | No | `5432` | Database port. | | `DB_PORT` | No | `5432` | Database port. |
@@ -63,6 +67,7 @@ services:
restart: unless-stopped restart: unless-stopped
environment: environment:
PORT: 3000 PORT: 3000
GRPC_PORT: 3002
DB_HOST: your-postgres-host DB_HOST: your-postgres-host
DB_PORT: 5432 DB_PORT: 5432
DB_USER: postgres DB_USER: postgres
@@ -77,6 +82,7 @@ services:
CORS_ORIGINS: https://panel.example.com CORS_ORIGINS: https://panel.example.com
ports: ports:
- "3000:3000" - "3000:3000"
- "3002:3002"
depends_on: depends_on:
- redis - redis
networks: networks:
@@ -155,19 +161,22 @@ Missing or unknown `format` falls back to `v2ray`.
| `GET` | `/me/links` | User subscription links. | | `GET` | `/me/links` | User subscription links. |
| `GET` | `/me/configs` | Available configs for the user. | | `GET` | `/me/configs` | Available configs for the user. |
| `POST` | `/me/links` | Create a public link. | | `POST` | `/me/links` | Create a public link. |
| `PATCH` | `/me/subscriptions/links/:id` | Rename, enable, disable, or reconfigure a link. | | `PATCH` | `/me/links/:id` | Rename, enable, disable, or reconfigure a link. |
| `DELETE` | `/me/subscriptions/links/:id` | Delete a link. | | `DELETE` | `/me/links/:id` | Delete a link. |
| `POST` | `/me/subscriptions/:id/reset` | Reset a link UUID. | | `POST` | `/me/links/:id/reset` | Reset a link UUID. |
| `PATCH` | `/me/subscriptions/:id/auto-renew` | Toggle auto-renew. | | `PATCH` | `/me/subscriptions/:id/auto-renew` | Toggle auto-renew. |
## Admin API Groups ## Admin API Groups
- `/admin/users` - users, approval status, block flag, profile fields, stats. - `/admin/users` - users, approval status, block flag, profile fields, stats, referees.
- `/admin/tariffs` - tariff CRUD. - `/admin/tariffs` - tariff CRUD.
- `/admin/subscriptions` - subscriptions and subscription links. - `/admin/subscriptions` - subscriptions and subscription links.
- `/admin/nodes` - nodes, protocols, sync, runtime operations, masking sites, outbounds. - `/admin/links` - subscription link operations (reset, update, delete).
- `/admin/nodes` - nodes, protocols, sync, runtime operations, masking sites, outbounds, observatory, routing balancers.
- `/admin/routing-rule-sets` - reusable routing templates. - `/admin/routing-rule-sets` - reusable routing templates.
- `/admin/external-subscriptions` - external source CRUD and URL testing. - `/admin/external-subscriptions` - external source CRUD and URL testing.
- `/admin/settings` - platform settings (panel, subscription delivery, Telegram).
- `/admin/broadcasts` - Telegram broadcast messages with delivery tracking.
- `/admin/logs` - audit log viewer data. - `/admin/logs` - audit log viewer data.
- `/admin/usage` - traffic usage rows. - `/admin/usage` - traffic usage rows.
- `/admin/xray/parse-link` - parse a proxy share link into outbound settings. - `/admin/xray/parse-link` - parse a proxy share link into outbound settings.
@@ -176,18 +185,14 @@ See [Core API routes](./core-routes.md) for the detailed route table.
## Node-Private API ## Node-Private API
Node agents consume the private `/node/*` API: Node agents use two transports:
- `POST /node/register` - **HTTP** — registration only (`POST /node/register`).
- `POST /node/heartbeat` - **gRPC** (`GRPC_PORT`, default `3002`) — heartbeat, usage reporting, config sync, and live stats. This is the primary node transport.
- `GET /node/config/latest`
- `POST /node/config/applied`
- `POST /node/usage`
- `POST /node/outbound-usage`
- `POST /node/session-events`
- `POST /node/error`
See [Core private node routes](./core-private-routes.md) for the payload contract. HTTP fallback routes (`/node/heartbeat`, `/node/usage`, etc.) remain available but the node agent uses gRPC by default.
See [Core private node routes](./core-private-routes.md) for the full payload contract and gRPC method table.
## Data Behavior ## Data Behavior
+2
View File
@@ -19,6 +19,7 @@ services:
restart: unless-stopped restart: unless-stopped
environment: environment:
PORT: 3000 PORT: 3000
GRPC_PORT: 3002
DB_HOST: your-postgres-host DB_HOST: your-postgres-host
DB_PORT: 5432 DB_PORT: 5432
DB_USER: postgres DB_USER: postgres
@@ -34,6 +35,7 @@ services:
# TELEGRAM_BOT_TOKEN: your-bot-token # TELEGRAM_BOT_TOKEN: your-bot-token
ports: ports:
- "3000:3000" - "3000:3000"
- "3002:3002"
depends_on: depends_on:
- redis - redis
networks: networks:
+1
View File
@@ -12,6 +12,7 @@ services:
PORT: 3001 PORT: 3001
# URL of Core — must be reachable from this server # URL of Core — must be reachable from this server
CORE_URL: https://core.example.com CORE_URL: https://core.example.com
CORE_GRPC_URL: core.example.com:3002
# One-time registration code — generate in admin panel → Nodes # One-time registration code — generate in admin panel → Nodes
# Remove this line after the node registers successfully # Remove this line after the node registers successfully
REGISTRATION_CODE: paste-one-time-code-here REGISTRATION_CODE: paste-one-time-code-here
+16 -9
View File
@@ -9,7 +9,8 @@ This page is public operator documentation. It describes setup, behavior, enviro
- One-time registration with Core. - One-time registration with Core.
- Persistent auth key storage. - Persistent auth key storage.
- Config sync by revision. - Config sync by revision.
- Xray install, restart, validation, GeoIP update, and key generation. - 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. - MTProto install and restart.
- Nginx masking site management. - Nginx masking site management.
- System status reporting with CPU, RAM, disk, network, and process state. - System status reporting with CPU, RAM, disk, network, and process state.
@@ -27,7 +28,9 @@ This page is public operator documentation. It describes setup, behavior, enviro
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `PORT` | No | `3001` | Local node agent HTTP port. | | `PORT` | No | `3001` | Local node agent HTTP port. |
| `NODE_ENV` | No | `development` | Runtime mode. | | `NODE_ENV` | No | `development` | Runtime mode. |
| `CORE_URL` | Yes | `http://localhost:3000` | Core API URL reachable from the node server. | | `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. | | `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. | | `NODE_AUTH_KEY` | No | empty | Optional fallback auth key when no key file exists. |
| `HEARTBEAT_INTERVAL_SEC` | No | `30` | Heartbeat interval in seconds. | | `HEARTBEAT_INTERVAL_SEC` | No | `30` | Heartbeat interval in seconds. |
@@ -51,6 +54,8 @@ services:
environment: environment:
PORT: 3001 PORT: 3001
CORE_URL: https://core.example.com CORE_URL: https://core.example.com
CORE_GRPC_URL: core.example.com:3002
CORE_INSECURE: "false"
REGISTRATION_CODE: paste-one-time-code-here REGISTRATION_CODE: paste-one-time-code-here
HEARTBEAT_INTERVAL_SEC: 30 HEARTBEAT_INTERVAL_SEC: 30
volumes: volumes:
@@ -114,14 +119,18 @@ All other routes require `x-node-auth-key`.
| `POST` | `/node/xray/restart` | Restart Xray. | | `POST` | `/node/xray/restart` | Restart Xray. |
| `POST` | `/node/xray/install` | Install an Xray version. | | `POST` | `/node/xray/install` | Install an Xray version. |
| `POST` | `/node/geoip/update` | Update GeoIP/geosite files. | | `POST` | `/node/geoip/update` | Update GeoIP/geosite files. |
| `POST` | `/node/xray/probe-outbound` | Test an outbound connection and return latency. |
| `POST` | `/node/crypto/x25519` | Generate X25519 keys. | | `POST` | `/node/crypto/x25519` | Generate X25519 keys. |
| `POST` | `/node/crypto/mldsa65` | Generate an ML-DSA-65 seed. | | `POST` | `/node/crypto/mldsa65` | Generate an ML-DSA-65 seed. |
| `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/restart` | Restart MTProto processes. |
| `POST` | `/node/mtproto/install` | Install an MTProto version. | | `POST` | `/node/mtproto/install` | Install an MTProto version. |
| `GET` | `/node/nginx/sites` | List masking sites. | | `GET` | `/node/nginx/sites` | List masking sites. |
| `GET` | `/node/nginx/sites/:domain` | Get one masking site. | | `GET` | `/node/nginx/sites/:domain` | Get one masking site. |
| `PUT` | `/node/nginx/sites` | Replace masking sites. | | `GET` | `/node/nginx/sites/:domain/certificate` | Get certificate and domain validity info. |
| `PUT` | `/node/nginx/site` | Upsert one masking site. | | `PUT` | `/node/nginx/sites` | Upsert one domain masking site (TLS upload or auto-issuance). |
| `PUT` | `/node/nginx/site` | Upsert legacy default masking site. |
| `GET` | `/node/nginx/site` | Get current masking site status. | | `GET` | `/node/nginx/site` | Get current masking site status. |
| `DELETE` | `/node/nginx/sites/:domain` | Delete one masking site. | | `DELETE` | `/node/nginx/sites/:domain` | Delete one masking site. |
| `DELETE` | `/node/nginx/site` | Delete current masking site. | | `DELETE` | `/node/nginx/site` | Delete current masking site. |
@@ -133,11 +142,9 @@ These endpoints are intended to be called by Core. Protect the agent port with f
## Config Sync ## Config Sync
- The node keeps the latest applied revision locally. - The node keeps the latest applied revision locally.
- Core can ask the node to apply config immediately. - 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.
- Heartbeat responses can also request sync. - Core can also push a sync trigger to the node over HTTP (`POST /node/apply-config`).
- The node pulls the latest config from Core. - 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.
- If config apply succeeds, the node confirms the applied revision.
- If config apply fails, the node reports an error and keeps the previous valid config where possible.
## Traffic and Events ## Traffic and Events
+20 -4
View File
@@ -45,12 +45,12 @@ This page is public operator documentation. It describes panel capabilities, rou
- Rotate node auth keys. - Rotate node auth keys.
- Force config sync. - Force config sync.
- Manage protocols. - Manage protocols.
- Manage outbounds for proxy chains. - Manage outbounds for proxy chains; probe outbound connectivity.
- Manage routing config and apply routing templates. - Manage routing config, routing balancers, and observatory settings.
- Manage masking sites. - Manage masking sites with TLS upload or auto-issuance; view certificate status.
- Install and restart Xray and MTProto. - Install and restart Xray and MTProto.
- Update GeoIP/geosite files. - Update GeoIP/geosite files.
- Generate X25519 and ML-DSA-65 keys. - Generate X25519, ML-DSA-65, TLS-ECH, and VLESS encryption keys.
- View live runtime status and resource usage. - View live runtime status and resource usage.
### Routing Rules ### Routing Rules
@@ -65,6 +65,18 @@ This page is public operator documentation. It describes panel capabilities, rou
- Test a source URL before attaching it to tariffs. - Test a source URL before attaching it to tariffs.
- Attach sources to tariffs so their share links are appended to subscriptions. - Attach sources to tariffs so their share links are appended to subscriptions.
### Settings
- Configure panel access settings (allowed hosts, root path).
- Configure subscription delivery settings (update interval, display name, support URL).
- Configure Telegram bot token.
### Broadcasts
- Create and schedule Telegram broadcast messages.
- Filter recipients by node.
- View per-broadcast delivery status and error log.
### Logs ### Logs
- View audit events. - View audit events.
@@ -80,6 +92,7 @@ This page is public operator documentation. It describes panel capabilities, rou
- Finance history and balance. - Finance history and balance.
- Account profile settings. - Account profile settings.
- Telegram account linking and unlinking. - Telegram account linking and unlinking.
- Referral referees list.
### Public Subscription Page ### Public Subscription Page
@@ -165,6 +178,7 @@ Admin routes:
| `/users/:id/links` | User links. | | `/users/:id/links` | User links. |
| `/users/:id/access` | User node/protocol access. | | `/users/:id/access` | User node/protocol access. |
| `/users/:id/finance` | User finance. | | `/users/:id/finance` | User finance. |
| `/users/:id/referees` | Users invited by this user. |
| `/tariffs` | Tariff management. | | `/tariffs` | Tariff management. |
| `/nodes` | Node list. | | `/nodes` | Node list. |
| `/nodes/:id` | Node overview. | | `/nodes/:id` | Node overview. |
@@ -175,6 +189,8 @@ Admin routes:
| `/subscriptions` | Subscription management. | | `/subscriptions` | Subscription management. |
| `/routing-rules` | Routing rule set management. | | `/routing-rules` | Routing rule set management. |
| `/external-subscriptions` | External source management. | | `/external-subscriptions` | External source management. |
| `/settings` | Platform settings. |
| `/broadcasts` | Telegram broadcast management. |
| `/logs` | Audit logs. | | `/logs` | Audit logs. |
| `/config-builder` | Protocol config builder. | | `/config-builder` | Protocol config builder. |