feat(veil-core): add Veil VPN protocol module alongside Xray#38
Draft
Rxflex wants to merge 1 commit into
Draft
Conversation
Adds first-class support for the Veil server (https://github.com/redstone-md/veil) to Remnawave Node. The implementation mirrors the existing xray-core module so the panel side can drive Veil through the same start / stop / healthcheck shape it already uses for Xray, no panel-side special cases. What ships ========== * New REST surface under /node/veil: POST /node/veil/start — push server.yaml + start daemon GET /node/veil/stop — graceful stop GET /node/veil/healthcheck — node + daemon liveness * libs/contract/commands/veil — Zod schemas for the three commands. StartVeilCommand carries: - serverConfig: the full server.yaml as a string (panel side stays the source of truth for transport topology, decoy origin, transports, etc.) - internals.configHash: SHA-256 the node uses to short-circuit a restart when the running config already matches. - adminAddr: optional override for the embedded admin API address the node probes for liveness; defaults to 127.0.0.1:9090. * src/modules/veil-core/veil.service.ts: - supervisord-controlled veil process - hash-based no-op restart (matches XrayService's behaviour) - admin-API liveness probe via fetch to /api/version (replaces Xray's gRPC stats probe; Veil is HTTP-only) - veil --version detection with VEIL_CORE_VERSION env override - identical onModuleDestroy cleanup pathway as XrayModule * supervisord.conf: new [program:veil] block, autostart=false / autorestart=false (panel manages lifecycle, same as Xray). * Dockerfile: - dedicated builder stage that pulls the platform-matching `veil` static binary (linux/amd64 + linux/arm64) from the upstream release, COPIed into the runtime image - vlogs / verrors aliases mirroring xlogs / xerrors Why this shape ============== Mirroring XrayModule was deliberate. Operators running mixed Xray + Veil fleets get one mental model: the panel speaks the same verbs to both daemons, and the node takes care of binary-specific lifecycle. Diverging architectures here would push that complexity into the panel where it doesn't belong. The serverConfig string is opaque to the node (parsed by veil itself at start time) so a future server.yaml schema bump in upstream doesn't require a node-side rebuild — only the veil binary in the image moves forward. Tests ===== Existing repo has no unit-test harness for service classes (there is no tests/ tree at all today), so this PR adds none. Manual verification: - docker build . # multi-arch, both stages green - cli mode + supervisord ctl cli veil:start --hash <h> --addr 127.0.0.1:9090 < server.yaml cli veil:health cli veil:stop - end-to-end: panel → POST /node/veil/start → supervisord starts veil → veil binds reality:443 / wss:8443 / quic:8444 → admin /api/version answers → healthcheck returns isVeilOnline=true. Backwards compat ================ Pure addition: no existing controller / contract / supervisord program touched. Operators not running Veil see zero behavioural change; the binary is bundled in the image but never starts. Marked Draft because: 1. Panel-side counterpart (panel/src/.../veil) is a separate PR not yet open. 2. Veil itself is pre-alpha (v0.1.0-alpha.1) and pending its first external audit; we don't want operators landing on this without that context.
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds first-class support for the Veil VPN server to Remnawave Node. The implementation mirrors the existing
xray-coremodule so the panel can drive Veil through the samestart/stop/healthcheckshape it already uses for Xray — no panel-side special cases.What ships
REST surface under
/node/veil, mirroring/node/xray:POST/node/veil/startserver.yaml+ start the daemonGET/node/veil/stopGET/node/veil/healthcheckContracts (
libs/contract/{api,commands}/veil/):StartVeilCommandcarries:serverConfig— the fullserver.yamlas a string. The node never parses it; veil itself does at start time. Future schema bumps don't require a node-side rebuild.internals.configHash— SHA-256 the node uses to short-circuit a restart when the running config matches.adminAddr— optional override for the admin API the node probes; defaults to127.0.0.1:9090.Service (
src/modules/veil-core/veil.service.ts):veilprocess (same pattern asXrayService)fetch /api/versionagainst the embedded admin API (Veil is HTTP-only; no gRPC stats analogue)veil --versiondetection withVEIL_CORE_VERSIONenv overrideonModuleDestroycleanup asXrayModulesupervisord.conf — new
[program:veil]block,autostart=false/autorestart=false(panel manages lifecycle, same as Xray).Dockerfile — dedicated
veilbuilder stage that pulls the platform-matching binary (linux/amd64 + linux/arm64) from the upstream release, plusvlogs/verrorslog aliases mirroringxlogs/xerrors.Why this shape
Mirroring
XrayModulewas deliberate. Operators running mixed Xray + Veil fleets get one mental model: the panel speaks the same verbs to both daemons, and the node takes care of binary-specific lifecycle. Diverging architectures here would push that complexity into the panel where it doesn't belong.The
serverConfigstring is intentionally opaque to the node so a futureserver.yamlschema bump in upstream doesn't require a node-side rebuild — only theveilbinary in the image moves forward.Backwards compat
Pure addition. No existing controller / contract / supervisord program is touched. Operators not running Veil see zero behavioural change; the binary is bundled in the image but never starts unless the panel explicitly issues
POST /node/veil/start.Test plan
The repo doesn't ship a unit-test harness for service classes today (no
tests/tree), so this PR adds none either. Manual verification I ran:docker buildx build --platform linux/amd64,linux/arm64 .— both stages greenPOST /node/veil/start→ supervisord startsveil/api/versionanswers/node/veil/healthcheckreturnsisVeilOnline=trueOut-of-scope (follow-ups)
StartVeilCommandshape this PR introduces. Tracked separately; not opening it until this side has API approval./api/users); wiring those into Remnawave's stats pipeline is a follow-up. Today's PR ships only lifecycle + liveness.File map
Notes for reviewers
@common/@libsimport groups, same asxray-core.xray-corealready imports (@kastov/node-supervisord,p-retry,enhanced-ms,semver,table,pkg-types).fetch, noundici/axiosdep.