Skip to content

feat: support JSON balancer configs with individual node tracking#145

Open
AirP0WeR wants to merge 2 commits intokutovoys:mainfrom
AirP0WeR:main
Open

feat: support JSON balancer configs with individual node tracking#145
AirP0WeR wants to merge 2 commits intokutovoys:mainfrom
AirP0WeR:main

Conversation

@AirP0WeR
Copy link
Copy Markdown

@AirP0WeR AirP0WeR commented Apr 16, 2026

Summary

Adds support for Remnawave JSON balancer configurations, allowing xray-checker to monitor each individual node within a balancer group separately.

Problem

When a subscription uses Remnawave JSON balancers, xray-checker currently shows balancer groups (e.g. "Germany") as a single entry with a virtual host like auto-de:1234. There is no way to track the availability of individual servers within the balancer — if one of three nodes goes down, the checker still shows the group as one item.

Solution

1. Unique names for nodes within balancer groups

When a JSON config has multiple proxy outbounds under one remarks, each node now gets a unique name:

🇩🇪 Germany  | de-01.domain.com
🇩🇪 Germany  | de-02.domain.com
🇩🇪 Germany  | de-03.domain.com

Single-outbound configs keep the original remarks as the name (no change in behavior).

2. SUBSCRIPTION_JSON_FORMAT flag

Remnawave panels return different response formats depending on the client's HTTP headers. The default Xray-Checker User-Agent receives base64 share links where balancers are collapsed into virtual hosts. The new SUBSCRIPTION_JSON_FORMAT=true env var sends app-like headers so the panel returns full JSON configs with all outbounds.

environment:
  - SUBSCRIPTION_URL=https://example.com/sub
  - SUBSCRIPTION_JSON_FORMAT=true

3. Custom HTTP headers (advanced)

For full control, two additional options allow overriding request headers:

  • SUBSCRIPTION_USER_AGENT — custom User-Agent
  • SUBSCRIPTION_HEADERS — arbitrary headers (Key:Value format)

Changed files

  • config/config.go — three new config options (JSONFormat, UserAgent, Headers)
  • subscription/parser.go — unique naming logic for multi-outbound JSON configs + custom header support in fetchURLContent

Before / After

Before After (with SUBSCRIPTION_JSON_FORMAT=true)
Total configs 12 (balancers as single virtual hosts) 18 (all individual nodes)
Balancer "Germany" 1 entry: auto-de:1234 3 entries: de-01, de-02, de-03
Node-level monitoring Not possible Each node checked independently

Backward compatibility

Fully backward-compatible. Without SUBSCRIPTION_JSON_FORMAT=true, behavior is identical to the current version.

When a subscription returns JSON configs with multiple proxy outbounds
per entry (Remnawave balancers), each node now gets a unique name in
the format "remarks | server_address" instead of all sharing the same
remarks string. This fixes status tracking for individual nodes within
balancer groups.

Also adds --subscription-user-agent and --subscription-header options
to allow custom HTTP headers when fetching subscriptions, which is
needed to receive JSON format from servers that return different
content based on User-Agent.
Single flag that sends app-like HTTP headers to get JSON configs with
full balancer details from Remnawave panels, instead of requiring
users to manually configure User-Agent and X-Hwid headers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant