From ee4c6211ae682d75f7c8bd285567188a7c7377ee Mon Sep 17 00:00:00 2001 From: Kiow Date: Mon, 1 Jun 2026 02:48:06 +0300 Subject: [PATCH] v15 --- README.md | 3 ++ core-private-routes.md | 37 ++++++++++++++++-- core-routes.md | 83 ++++++++++++++++++++++++++++++++++------- core.md | 35 +++++++++-------- docker-compose.base.yml | 2 + docker-compose.node.yml | 1 + node.md | 25 ++++++++----- panel.md | 24 ++++++++++-- 8 files changed, 165 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 641c839..74eca60 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ services: restart: unless-stopped environment: PORT: 3000 + GRPC_PORT: 3002 DB_HOST: your-postgres-host DB_PORT: 5432 DB_USER: postgres @@ -70,6 +71,7 @@ services: CORS_ORIGINS: https://panel.example.com ports: - "3000:3000" + - "3002:3002" depends_on: - redis networks: @@ -124,6 +126,7 @@ services: environment: PORT: 3001 CORE_URL: https://core.example.com + CORE_GRPC_URL: core.example.com:3002 REGISTRATION_CODE: paste-one-time-code-here HEARTBEAT_INTERVAL_SEC: 30 volumes: diff --git a/core-private-routes.md b/core-private-routes.md index cb33dbf..e232e92 100644 --- a/core-private-routes.md +++ b/core-private-routes.md @@ -2,10 +2,20 @@ 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 - `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. ## Route table @@ -91,6 +101,7 @@ The config returned by `GET /node/config/latest` has this structure: { revision: number clientMap: Record + mtprotoClientMap: Record services: { xray?: XrayServiceConfig mtproto?: MtProtoServiceConfig @@ -100,10 +111,11 @@ The config returned by `GET /node/config/latest` has this structure: 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.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 @@ -114,3 +126,22 @@ Important notes: - `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`. +## 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. + diff --git a/core-routes.md b/core-routes.md index 482be97..9f547e1 100644 --- a/core-routes.md +++ b/core-routes.md @@ -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/telegram` | `TelegramAuthDto` | Telegram OAuth login | | `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` | `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` | | `POST` | `/auth/telegram/link` | `TelegramAuthDto` | Links Telegram to 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` | | `PATCH` | `/me/profile` | `UpdateProfileDto` | Updates name, email, or password | | `GET` | `/me/stats` | none | `UserStats` | | `GET` | `/me/traffic/daily` | none | Daily traffic series | | `GET` | `/me/traffic/hourly-dist` | none | Hour-of-day distribution | | `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/transactions` | none | User balance transaction history | | `GET` | `/me/subscriptions` | none | User subscriptions | | `GET` | `/me/links` | none | All user subscription links | | `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/subscriptions` | `CreateSubscriptionLinkDto` | Legacy per-subscription link creation | -| `POST` | `/me/subscriptions/:id/reset` | none | Resets the selected link UUID | -| `PATCH` | `/me/subscriptions/links/:id` | `UpdateSubscriptionLinkDto` | Renames or reconfigures a link | -| `DELETE` | `/me/subscriptions/links/:id` | none | Deletes a link | +| `POST` | `/me/links/:id/reset` | none | Resets the link UUID | +| `PATCH` | `/me/links/:id` | `UpdateUserLinkDto` | Renames, enables/disables, or reconfigures a link | +| `DELETE` | `/me/links/:id` | none | Deletes a link | | `PATCH` | `/me/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew for own subscription | ## 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 | | --- | --- | --- | --- | | `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/stats` | none | User stats | | `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 | +| `GET` | `/admin/users/:id/referees` | none | Users invited by this user | | `DELETE` | `/admin/users/:id` | none | Deletes a user | ## 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/users/:id/subscriptions` | none | Subscriptions 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 | | `DELETE` | `/admin/subscriptions/:id` | none | Cancels a subscription | | `PATCH` | `/admin/subscriptions/:id/auto-renew` | `UpdateAutoRenewDto` | Toggles auto-renew | | `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/subscriptions/links/:id/reset` | none | Resets a link UUID | -| `PATCH` | `/admin/subscriptions/links/:id` | `UpdateSubscriptionLinkDto` | Updates a link | -| `DELETE` | `/admin/subscriptions/links/:id` | none | Deletes a link | +| `POST` | `/admin/links/:id/reset` | none | Resets a link UUID | +| `PATCH` | `/admin/links/:id` | `UpdateUserLinkDto` | Updates a link | +| `DELETE` | `/admin/links/:id` | none | Deletes a link | ## Admin routes - nodes | Method | Route | Input | Output / Notes | | --- | --- | --- | --- | | `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/outbound-options` | none | Node/protocol outbound options | | `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/crypto/x25519` | none | Generates x25519 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/mtproto/versions` | none | Cached telemt release tags | | `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 | +| `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 | | `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 | | `POST` | `/admin/nodes/:id/install-mtproto` | body `{ version?: string }` | Installs telemt and stores the version | | `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 | | `POST` | `/admin/nodes/:id/outbounds` | `CreateNodeOutboundDto` | Creates 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 | +| `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 | ## 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 | +## 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 ### Auth @@ -185,11 +226,13 @@ This file lists the current HTTP routes exposed by Core, grouped by access level - `RegisterDto` - `email`, `password` - `RefreshTokenDto` - `refreshToken` - `TelegramAuthDto` - `tgAuthResult` +- `ApplyReferralCodeDto` - `code` ### Users +- `CreateAdminUserDto` - `email`, `password`, `role?`, `name?` - `UpdateProfileDto` - `name?`, `email?`, `password?` -- `UpdateUserDto` - `email?`, `password?`, `role?`, `isBlocked?`, `name?`, `comment?` +- `UpdateUserDto` - `email?`, `password?`, `role?`, `isBlocked?`, `name?`, `comment?`, `allowedToInvite?` - `UpdateUserStatusDto` - `status: 'active' | 'pending' | 'rejected'` ### Balance @@ -215,9 +258,8 @@ This file lists the current HTTP routes exposed by Core, grouped by access level ### Subscriptions - `CreateSubscriptionDto` - `userId`, `tariffId`, `startAt?` -- `CreateSubscriptionLinkDto` - `subscriptionId`, `name?` - `CreateUserLinkDto` - `subscriptionId?`, `name?`, `selectedNodeIds?` -- `UpdateSubscriptionLinkDto` - `name?`, `isEnabled?`, `selectedNodeIds?` +- `UpdateUserLinkDto` - `name?`, `isEnabled?`, `selectedNodeIds?` - `UpdateAutoRenewDto` - `autoRenew` ### Nodes @@ -244,6 +286,9 @@ This file lists the current HTTP routes exposed by Core, grouped by access level - `config?` - `targetNodeId?` - `targetProtocolId?` +- `UpdateNodeObservatoryDto` - observatory settings for outbound health probing +- `CreateNodeRoutingBalancerDto` - `tag`, `selector`, `strategy?`, `fallbackTag?` +- `UpdateNodeRoutingBalancerDto` - partial `CreateNodeRoutingBalancerDto` - `CreateRoutingRuleSetDto` - `name` - `description?` @@ -257,7 +302,6 @@ This file lists the current HTTP routes exposed by Core, grouped by access level - `blockCryptominers?` - `blockAdult?` - `UpdateNodeRoutingConfigDto` - same routing fields as above, without `name` and `description` -- `ApplyRoutingTemplateDto` - `templateId` - `InstallXrayDto` - `version` - `UpdateGeoipDto` - `geoipUrl?`, `geositeUrl?` @@ -313,3 +357,14 @@ This file lists the current HTTP routes exposed by Core, grouped by access level - `leastPing` - `leastLoad` +### Settings + +- `PanelSettingsDto` - `allowedHosts?`, `rootPath?` +- `SubscriptionSettingsDto` - `allowedHosts?`, `rootPath?`, `updateInterval?`, `name?`, `supportUrl?`, `websiteUrl?` +- `TelegramSettingsDto` - `botToken?` + +### Broadcasts + +- `CreateBroadcastDto` - `text`, `filters?` (`{ nodeIds?: number[] }`), `scheduledAt?` +- `UpdateBroadcastDto` - partial `CreateBroadcastDto` + diff --git a/core.md b/core.md index bdaafc6..465a87e 100644 --- a/core.md +++ b/core.md @@ -16,6 +16,9 @@ This page is public operator documentation. It describes behavior, API, environm - Routing rule sets with rules, balancers, and blocking options. - External subscription source ingestion and testing. - 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. ## Environment Variables @@ -23,6 +26,7 @@ This page is public operator documentation. It describes behavior, API, environm | Variable | Required | Default | Description | | --- | --- | --- | --- | | `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. | | `DB_HOST` | Yes | `localhost` | Database host. | | `DB_PORT` | No | `5432` | Database port. | @@ -63,6 +67,7 @@ services: restart: unless-stopped environment: PORT: 3000 + GRPC_PORT: 3002 DB_HOST: your-postgres-host DB_PORT: 5432 DB_USER: postgres @@ -77,6 +82,7 @@ services: CORS_ORIGINS: https://panel.example.com ports: - "3000:3000" + - "3002:3002" depends_on: - redis networks: @@ -155,19 +161,22 @@ Missing or unknown `format` falls back to `v2ray`. | `GET` | `/me/links` | User subscription links. | | `GET` | `/me/configs` | Available configs for the user. | | `POST` | `/me/links` | Create a public link. | -| `PATCH` | `/me/subscriptions/links/:id` | Rename, enable, disable, or reconfigure a link. | -| `DELETE` | `/me/subscriptions/links/:id` | Delete a link. | -| `POST` | `/me/subscriptions/:id/reset` | Reset a link UUID. | +| `PATCH` | `/me/links/:id` | Rename, enable, disable, or reconfigure a link. | +| `DELETE` | `/me/links/:id` | Delete a link. | +| `POST` | `/me/links/:id/reset` | Reset a link UUID. | | `PATCH` | `/me/subscriptions/:id/auto-renew` | Toggle auto-renew. | ## 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/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/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/usage` - traffic usage rows. - `/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 agents consume the private `/node/*` API: +Node agents use two transports: -- `POST /node/register` -- `POST /node/heartbeat` -- `GET /node/config/latest` -- `POST /node/config/applied` -- `POST /node/usage` -- `POST /node/outbound-usage` -- `POST /node/session-events` -- `POST /node/error` +- **HTTP** — registration only (`POST /node/register`). +- **gRPC** (`GRPC_PORT`, default `3002`) — heartbeat, usage reporting, config sync, and live stats. This is the primary node transport. -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 diff --git a/docker-compose.base.yml b/docker-compose.base.yml index 2f8c348..46c9172 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -19,6 +19,7 @@ services: restart: unless-stopped environment: PORT: 3000 + GRPC_PORT: 3002 DB_HOST: your-postgres-host DB_PORT: 5432 DB_USER: postgres @@ -34,6 +35,7 @@ services: # TELEGRAM_BOT_TOKEN: your-bot-token ports: - "3000:3000" + - "3002:3002" depends_on: - redis networks: diff --git a/docker-compose.node.yml b/docker-compose.node.yml index 562f7d6..ea33967 100644 --- a/docker-compose.node.yml +++ b/docker-compose.node.yml @@ -12,6 +12,7 @@ services: PORT: 3001 # URL of Core — must be reachable from this server CORE_URL: https://core.example.com + CORE_GRPC_URL: core.example.com:3002 # One-time registration code — generate in admin panel → Nodes # Remove this line after the node registers successfully REGISTRATION_CODE: paste-one-time-code-here diff --git a/node.md b/node.md index 573193f..b31e3c8 100644 --- a/node.md +++ b/node.md @@ -9,7 +9,8 @@ This page is public operator documentation. It describes setup, behavior, enviro - One-time registration with Core. - Persistent auth key storage. - 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. - Nginx masking site management. - 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. | | `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. | | `NODE_AUTH_KEY` | No | empty | Optional fallback auth key when no key file exists. | | `HEARTBEAT_INTERVAL_SEC` | No | `30` | Heartbeat interval in seconds. | @@ -51,6 +54,8 @@ services: 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: @@ -114,14 +119,18 @@ All other routes require `x-node-auth-key`. | `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/crypto/x25519` | Generate X25519 keys. | | `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/install` | Install an MTProto version. | | `GET` | `/node/nginx/sites` | List masking sites. | | `GET` | `/node/nginx/sites/:domain` | Get one masking site. | -| `PUT` | `/node/nginx/sites` | Replace masking sites. | -| `PUT` | `/node/nginx/site` | Upsert 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 auto-issuance). | +| `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. | @@ -133,11 +142,9 @@ These endpoints are intended to be called by Core. Protect the agent port with f ## Config Sync - The node keeps the latest applied revision locally. -- Core can ask the node to apply config immediately. -- Heartbeat responses can also request sync. -- The node pulls the latest config from Core. -- 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. +- 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 diff --git a/panel.md b/panel.md index 1d5d678..40b30f0 100644 --- a/panel.md +++ b/panel.md @@ -45,12 +45,12 @@ This page is public operator documentation. It describes panel capabilities, rou - Rotate node auth keys. - Force config sync. - Manage protocols. -- Manage outbounds for proxy chains. -- Manage routing config and apply routing templates. -- Manage masking sites. +- Manage outbounds for proxy chains; probe outbound connectivity. +- Manage routing config, routing balancers, and observatory settings. +- Manage masking sites with TLS upload or auto-issuance; view certificate status. - Install and restart Xray and MTProto. - 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. ### 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. - 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 - View audit events. @@ -80,6 +92,7 @@ This page is public operator documentation. It describes panel capabilities, rou - Finance history and balance. - Account profile settings. - Telegram account linking and unlinking. +- Referral referees list. ### Public Subscription Page @@ -165,6 +178,7 @@ Admin routes: | `/users/:id/links` | User links. | | `/users/:id/access` | User node/protocol access. | | `/users/:id/finance` | User finance. | +| `/users/:id/referees` | Users invited by this user. | | `/tariffs` | Tariff management. | | `/nodes` | Node list. | | `/nodes/:id` | Node overview. | @@ -175,6 +189,8 @@ Admin routes: | `/subscriptions` | Subscription management. | | `/routing-rules` | Routing rule set management. | | `/external-subscriptions` | External source management. | +| `/settings` | Platform settings. | +| `/broadcasts` | Telegram broadcast management. | | `/logs` | Audit logs. | | `/config-builder` | Protocol config builder. |