Skip to content

Subscriptions and response rules

Response rules decide what the panel returns for every subscription request. A client app needs its configs, a browser deserves a nice page, and a stranger script walking through stolen links is best served a 404 and nothing else. The module shows the current state on one screen, applies ready-made rule sets and enables per-device subscription binding. Everything changes through the panel API, no configs are edited by hand.

Ready-made rule sets

“Clients and browsers” for a regular setup, the strict “Happ and INCY + devices” for selling subscriptions, and “Allow everyone” as a single rule to roll back.

Device binding

Happ, INCY, FlClashX, Koala Clash and Prizrak-Box report the device identifier to the panel. With the device limit on, a leaked link stops working on stranger phones: they receive a refusal instead of configs.

Backup copies

Before every rule replacement the current set is saved to a file. The ten latest copies are kept, any of them can be restored from the same menu.

The panel evaluates every subscription request by its headers: which app sent it and from which device. A rule combines header conditions with a response type. Rules are checked top to bottom, the first match wins, and its response type goes to the client.

Response rulesfirst matching rule winsHapp/INCY + x-hwidknown appsMozilla in user-agentnothing matchedHapp · INCYx-hwid: device idOther appsv2rayN · V2Box…Browseropens the linkStranger requestlink guessingXray JSONfull configBase64server listSubscription pageHTML404as if nothing hereDevice limit · N devicesthe panel reads request headers and answers by the first matching rule

Device binding works alongside the rules. Happ and INCY send an x-hwid header with the device identifier. When the limit is on, a user’s subscription is served to at most N devices, the rest receive a polite message instead of configs. The list of occupied slots is visible in the user’s card in the panel, a lost device can be removed there to free its slot. Individual users can have their own limit or none at all, that is done in the panel.

Everything is stored in the panel, the same settings are available in its web UI in the subscriptions section. The module is a convenience wrapper: it changes values through the API, shows the result and keeps copies. If you use the panel’s external squads, keep in mind that response rules take priority over their settings.

The response type in a rule decides what exactly the client receives. The module’s rule sets use some of the types, custom rules in the panel can be built from the full list.

Response type What the client receives
Xray JSON The complete Xray config as one file, with routing rules. This is how Happ, INCY and v2rayN work
Base64 The plain server list Base64-encoded. Every app understands it, a safe default choice
Mihomo, Clash, Stash, Sing-box A config in the format of that client family
Browser page The subscription HTML page with the server list and instructions
Block 403, 404, 451 An empty refusal. For stranger requests 404 looks the most natural: as if nothing ever lived at this address
Socket drop The panel silently drops the connection, without a status code
  1. Open item 5 “Subscriptions: rules and page” of the main menu and pick “Subscriptions and response rules”:

    root@server: ~
    REMNAWAVE REVERSE-PROXY by eGames
    Version: 3.8.1
    Wiki: https://wiki.egam.es/
    
    5.Subscriptions: rules and page
    
    6.WARP Native
    
    8.Xray Checker — subscription monitoring
    0.Exit
    
    Select action (0-13):5
    root@server: ~
    Subscriptions: rules and page
    
    1.Subscriptions and response rules
        which config each client receives, the device limit, JSON and paths
    2.Subscription page
        the Orion template and restoring the stock page
    
    0.Exit
    
    Select action (0-2):1
  2. The module shows the state right away: which rules are active, whether the device limit is on, what the base path serves. The actions are below:

    root@server: ~
    Subscriptions and response rules
     Details in the wiki: https://wiki.egam.es/configuration/subscription-rules/
    
     Response rules: not configured
       recent panel versions answer 403 to subscription requests until rules are set, apply a preset below
     ✗ HWID device limit: disabled
     JSON at the subscription base path: disabled
     Extra paths /json, /stash, /mihomo: open
    
    1.Show rules in detail
    2.Preset “Clients and browsers”
        browsers get the subscription page, every app gets Base64 configs
    3.Preset “Strict: Happ and INCY + devices”
        configs go only to Happ/INCY with device binding and to known apps, everyone else gets 404
    4.Allow everyone with a single rule
    5.HWID device limit: enable
    6.JSON at base path: enable
    7.Extra paths /json, /stash, /mihomo: close
    8.Restore saved rules
    
    0.Exit
    
    Select action (0-8):2
  3. The “Clients and browsers” preset suits most setups: the browser gets the subscription page, every app receives its configs as Base64, the format every client understands:

    root@server: ~
    [?] Replace the current rules (0) with preset “Clients and browsers” of 2 rules? The current rules will be saved to a file. (y/n):y
    Current rules saved: rules-20261009-143210.json
    Preset applied
     Changes apply immediately. Apps pick them up on the next subscription update.
  4. The state screen refreshes. Item 1 shows every rule with its conditions:

    root@server: ~
     Response rules: 2
       1. ✓ Browsers → browser page
       2. ✓ Everyone else → Base64
     ✗ HWID device limit: disabled
    
    Select action (0-8):1
    
     ✓ 1. Browsers [AND → browser page]
       user-agent CONTAINS "Mozilla"  (case-insensitive)
     ✓ 2. Everyone else [AND → Base64]
       no conditions, the rule matches every request
    
    Press any key to go back…

The “Strict: Happ and INCY + devices” preset is built for selling subscriptions. It hands configs only to verified requests and returns 404 to everything else. The rule set looks like this:

Who asks Condition What they receive
Happ, INCY and RenoarX user-agent starts with Happ/, INCY/ or RenoarX/, a valid x-hwid is present The complete Xray JSON config
Clash clients user-agent starts with FlClashX/, koala-clash/, prizrak-box/, rabbithole/, clash-mi/, Flowvy/ or ClodClash/, a valid x-hwid is present The Mihomo config for their Clash core
Sing-box clients user-agent starts with Karing/, InHive/, Throne/ or DeskBox/, a valid x-hwid is present The Sing-box config
Known apps user-agent starts with a name from the list: v2rayN, v2rayNG, v2RayTun, V2Box, Streisand, Shadowrocket, sing-box, Karing, FlClash, Flowvy, prizrak-box, Koala Clash, Clod Clash, RenoarX, Throne, DeskBox, sfa, sfi, sfm, sft, rabbithole The Base64 list
Browser user-agent contains Mozilla The subscription page
Everyone else no conditions 404
root@server: ~
 Response rules: 6
   1. ✓ Xray JSON clients with device → Xray JSON
   2. ✓ Clash clients with device   → Mihomo
   3. ✓ Sing-box clients with device → Sing-box
   4. ✓ Known apps                   → Base64
   5. ✓ Browsers → browser page
   6. ✓ Everyone else → 404

The strict preset makes sense together with the device limit: a stolen link then stays useless even with a faked app name, because the stranger device will not pass the limit. Clash and Sing-box clients, RenoarX, Happ and INCY report the device identifier to the panel: with the limit on they pass the check and receive the config in their own format.

Enabled by item 5. The panel asks how many devices per user are allowed and shows a warning:

root@server: ~
[?] Device limit per user (1-20, Enter will keep 3):3
Clients without the x-hwid header (v2rayN, v2rayNG, FlClash, Stash) will not be able to fetch the subscription. For such users the limit is disabled per user in the panel.
[?] Enable the device limit: up to 3 per user? (y/n):y
Device limit enabled: up to 3 per user
 Changes apply immediately. Apps pick them up on the next subscription update.

What the panel knows about a device:

Header What it carries Example
x-hwid The device identifier, required for the limit UE42LJXu4DbiCaBv
x-device-os The device system iOS or Android
x-ver-os The system version 18.3
x-device-model The device model iPhone 14 Pro Max

Happ, INCY, RenoarX, DeskBox, v2RayTun, Flowvy, Clod Clash and the Clash clients send these headers on their own. Throne, Shadowrocket, Clash Mi and Karing support the binding too, but send the header only after it is enabled in the app settings. Left without the header are v2rayN, v2rayNG, FlClash, Stash and the official sing-box apps: with the limit on, their users will not receive the subscription. Such a user gets the limit disabled individually in their panel card, the restriction keeps working for everyone else.

The limit counts distinct devices. When a user changes phones and the old one holds a slot, the extra device is removed from the card list and the new one passes right away.

Before every rule replacement the module stores the current set in /usr/local/remnawave_reverse/subscription-rules/ with a timestamp. Item 8 lists the copies, the picked one returns to the panel, and the state at restore time is saved as well. The ten latest copies are kept.

root@server: ~
Restoring rules from a copy

1.2026-10-09 14:32:10 · rules: 4
2.2026-10-09 14:20:03 · rules: 2

0.Exit

Select action (0-2):1

[?] Restore rules from rules-20261009-143210.json (4 rules)? (y/n):y
Current rules saved: rules-20261009-144502.json
Rules restored