fix(sub): randomize fresh panel subscription paths (#6375)

* fix(sub): randomize fresh panel subscription paths

Seed distinct cryptographically random paths for base64, JSON, and Clash subscriptions when a panel database is first created. Persist them so restarts keep published URLs stable while upgrades preserve existing settings.

Generated-by: OpenCode:gpt-5.6-sol

* fix(sub): regenerate paths on settings reset

Keep subscription paths unpredictable after a factory reset, close the test database on failure, and update the builder, OpenAPI, and localized docs to describe panel-specific paths instead of obsolete fixed defaults.

Generated-by: OpenCode:gpt-5.6-sol
This commit is contained in:
ilyusha
2026-09-03 17:34:37 +03:00
committed by GitHub
parent ded2aa150c
commit f9898e0b24
20 changed files with 285 additions and 158 deletions
@@ -69,8 +69,8 @@ export function SubscriptionBuilder() {
const [scheme, setScheme] = useState<'http' | 'https'>('https');
const [host, setHost] = useState('sub.example.com');
const [port, setPort] = useState('2096');
const [subPath, setSubPath] = useState('/sub/');
const [jsonPath, setJsonPath] = useState('/json/');
const [subPath, setSubPath] = useState('/your-sub-path/');
const [jsonPath, setJsonPath] = useState('/your-json-path/');
const [subId, setSubId] = useState('user-1');
const [behindProxy, setBehindProxy] = useState(false);
const [clients, setClients] = useState<ClientRow[]>(DEFAULT_CLIENTS);
@@ -95,8 +95,8 @@ export function SubscriptionBuilder() {
setScheme('https');
setHost('sub.example.com');
setPort('2096');
setSubPath('/sub/');
setJsonPath('/json/');
setSubPath('/your-sub-path/');
setJsonPath('/your-json-path/');
setSubId('user-1');
setBehindProxy(false);
setClients(DEFAULT_CLIENTS);
+6 -6
View File
@@ -18,7 +18,7 @@ panel's subscription settings:
| ------------- | ------- | --------------------------------------------------------------- |
| `subPort` | `2096` | Listen port (separate from the panel). |
| `subListen` | _(all)_ | Bind address. |
| `subPath` | `/sub/` | Base path for raw subscription URLs. |
| `subPath` | _(random per panel)_ | Base path for raw subscription URLs. |
| `subDomain` | _(none)_| Public host; if set, the server only answers for that Host. |
| `subCertFile` / `subKeyFile` | _(none)_ | TLS cert + key — when set, the server serves **HTTPS**. |
| `subEncrypt` | `true` | Base64-encode the raw subscription body. |
@@ -27,7 +27,7 @@ panel's subscription settings:
A subscription URL looks like:
```text
https://<sub-host>:<sub-port>/sub/<sub-id>
https://<sub-host>:<sub-port>/<sub-path>/<sub-id>
```
where `<sub-id>` is the client's **Sub ID**.
@@ -44,12 +44,12 @@ The **format is chosen by path**, each with its own enable toggle:
| Format | Path | Enabled by | Output |
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
| **Raw links** | `/sub/` | always (if on) | A list of `vless://`, `vmess://`, … links (base64-encoded when `subEncrypt` is on). |
| **JSON** | `/json/` | `subJsonEnable` | Full Xray client config(s). |
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | YAML profile. |
| **Raw links** | `subPath` | always (if on) | A list of `vless://`, `vmess://`, … links (base64-encoded when `subEncrypt` is on). |
| **JSON** | `subJsonPath` | `subJsonEnable` | Full Xray client config(s). |
| **Clash / Mihomo** | `subClashPath` | `subClashEnable` | YAML profile. |
Only enabled inbounds using **VLESS, VMess, Trojan, Shadowsocks, or Hysteria2**
appear in a subscription, ordered by their sub-sort index. Requesting `/sub/`
appear in a subscription, ordered by their sub-sort index. Requesting `subPath`
with an `Accept: text/html` header (or `?html=1`) returns a human-readable info
page instead of the raw body.
+10 -8
View File
@@ -264,10 +264,11 @@ _openapi:
- depth: 2
title: Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
url: '#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients'
result set as the configured subPath endpoint, but as a JSON array — no
base64. When an inbound has streamSettings.externalProxy set, one URL is
emitted per external proxy. Empty array when the subId has no enabled
clients.
url: '#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients'
- depth: 2
title: 'Return every URL for one client across all attached inbounds — the same
strings the Copy URL button copies in the panel UI. Supported protocols:
@@ -496,10 +497,11 @@ _openapi:
id: traffic-counters-for-a-client-identified-by-email
- content: Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
id: return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
result set as the configured subPath endpoint, but as a JSON array —
no base64. When an inbound has streamSettings.externalProxy set, one
URL is emitted per external proxy. Empty array when the subId has no
enabled clients.
id: return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- content: 'Return every URL for one client across all attached inbounds — the
same strings the Copy URL button copies in the panel UI. Supported
protocols: vmess, vless, trojan, shadowsocks, hysteria. If
@@ -2,9 +2,10 @@
title: Subscription Server
description: A separate HTTP/HTTPS server that serves proxy subscription links
(standard, JSON, and Clash) to clients. The server listens on its own port
(default 10882) and is configured in Settings → Subscription. Paths are
configurable; defaults are shown below. All subscription endpoints set
response headers for client apps to read traffic/expiry info.
(default 2096) and is configured in Settings → Subscription. Fresh panels
generate random path prefixes for each format; all paths remain configurable.
Every subscription endpoint sets response headers for client apps to read
traffic/expiry info.
full: true
_openapi:
preload:
@@ -15,34 +16,36 @@ _openapi:
matching the subscription ID. When the request has an Accept: text/html
header or ?html=1, renders a styled info page instead. With
?format=info, returns the page view-model as JSON (traffic, expiry,
online status; no links) for live polling. Default path: /sub/:subid.'
url: '#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-default-path-subsubid'
online status; no links) for live polling. The path prefix is configured
by subPath.'
url: '#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath'
- depth: 2
title: 'Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.'
url: '#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid'
title: Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
url: '#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath'
- depth: 2
title: 'Return subscription as a Clash/Mihomo-compatible YAML config, including
title: Return subscription as a Clash/Mihomo-compatible YAML config, including
configured global Clash routing rules. Only when Clash subscription is
enabled in settings. Default path: /clash/:subid.'
url: '#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid'
enabled in settings. The path prefix is configured by subClashPath.
url: '#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath'
structuredData:
headings:
- content: 'Return base64-encoded subscription links for all enabled clients
matching the subscription ID. When the request has an Accept:
text/html header or ?html=1, renders a styled info page instead. With
?format=info, returns the page view-model as JSON (traffic, expiry,
online status; no links) for live polling. Default path: /sub/:subid.'
id: return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-default-path-subsubid
- content: 'Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.'
id: return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
- content: 'Return subscription as a Clash/Mihomo-compatible YAML config,
including configured global Clash routing rules. Only when Clash
subscription is enabled in settings. Default path: /clash/:subid.'
id: return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
online status; no links) for live polling. The path prefix is
configured by subPath.'
id: return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- content: Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
id: return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- content: Return subscription as a Clash/Mihomo-compatible YAML config, including
configured global Clash routing rules. Only when Clash subscription is
enabled in settings. The path prefix is configured by subClashPath.
id: return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
contents: []
---
+6 -6
View File
@@ -18,7 +18,7 @@ icon: Rss
| ------------- | ------- | --------------------------------------------------------------- |
| `subPort` | `2096` | پورت گوش‌دادن (جدا از پنل). |
| `subListen` | _(همه)_ | آدرس اتصال (bind). |
| `subPath` | `/sub/` | مسیر پایه برای URLهای خام اشتراک. |
| `subPath` | _(تصادفی برای هر پنل)_ | مسیر پایه برای URLهای خام اشتراک. |
| `subDomain` | _(هیچ)_ | میزبان عمومی؛ اگر تنظیم شود، سرور فقط به همان Host پاسخ می‌دهد. |
| `subCertFile` / `subKeyFile` | _(هیچ)_ | گواهی و کلید TLS — هنگام تنظیم، سرور **HTTPS** ارائه می‌دهد. |
| `subEncrypt` | `true` | بدنه‌ی خام اشتراک را با base64 رمزگذاری می‌کند. |
@@ -27,7 +27,7 @@ icon: Rss
یک URL اشتراک به این شکل است:
```text
https://<sub-host>:<sub-port>/sub/<sub-id>
https://<sub-host>:<sub-port>/<sub-path>/<sub-id>
```
که در آن `<sub-id>` همان **Sub ID** کلاینت است.
@@ -44,13 +44,13 @@ https://<sub-host>:<sub-port>/sub/<sub-id>
| Format | Path | Enabled by | Output |
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
| **لینک‌های خام** | `/sub/` | همیشه (اگر روشن باشد) | فهرستی از لینک‌های `vless://`، `vmess://`، … (هنگام فعال‌بودن `subEncrypt` با base64 رمزگذاری می‌شود). |
| **JSON** | `/json/` | `subJsonEnable` | پیکربندی(های) کامل کلاینت Xray. |
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | پروفایل YAML. |
| **لینک‌های خام** | `subPath` | همیشه (اگر روشن باشد) | فهرستی از لینک‌های `vless://`، `vmess://`، … (هنگام فعال‌بودن `subEncrypt` با base64 رمزگذاری می‌شود). |
| **JSON** | `subJsonPath` | `subJsonEnable` | پیکربندی(های) کامل کلاینت Xray. |
| **Clash / Mihomo** | `subClashPath` | `subClashEnable` | پروفایل YAML. |
فقط ورودی‌های فعالی که از **VLESS، VMess، Trojan، Shadowsocks یا Hysteria2**
استفاده می‌کنند در یک اشتراک ظاهر می‌شوند و بر اساس شاخص sub-sort آن‌ها مرتب می‌شوند.
درخواست `/sub/` همراه با هدر `Accept: text/html` (یا `?html=1`) به‌جای بدنه‌ی خام،
درخواست `subPath` همراه با هدر `Accept: text/html` (یا `?html=1`) به‌جای بدنه‌ی خام،
یک صفحه‌ی اطلاعات خوانا برای انسان برمی‌گرداند.
### Base64 vs JSON
+11 -9
View File
@@ -311,11 +311,12 @@ _openapi:
title: >-
Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
result set as the configured subPath endpoint, but as a JSON array — no
base64. When an inbound has streamSettings.externalProxy set, one URL is
emitted per external proxy. Empty array when the subId has no enabled
clients.
url: >-
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- depth: 2
title: >-
Return every URL for one client across all attached inbounds — the same
@@ -593,11 +594,12 @@ _openapi:
- content: >-
Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
result set as the configured subPath endpoint, but as a JSON array —
no base64. When an inbound has streamSettings.externalProxy set, one
URL is emitted per external proxy. Empty array when the subId has no
enabled clients.
id: >-
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- content: >-
Return every URL for one client across all attached inbounds — the
same strings the Copy URL button copies in the panel UI. Supported
@@ -672,4 +674,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/clients/list","method":"get"},{"path":"/panel/api/clients/list/paged","method":"get"},{"path":"/panel/api/clients/get/{email}","method":"get"},{"path":"/panel/api/clients/add","method":"post"},{"path":"/panel/api/clients/update/{email}","method":"post"},{"path":"/panel/api/clients/del/{email}","method":"post"},{"path":"/panel/api/clients/{email}/attach","method":"post"},{"path":"/panel/api/clients/{email}/detach","method":"post"},{"path":"/panel/api/clients/{email}/externalLinks","method":"post"},{"path":"/panel/api/clients/resetAllTraffics","method":"post"},{"path":"/panel/api/clients/delDepleted","method":"post"},{"path":"/panel/api/clients/delOrphans","method":"post"},{"path":"/panel/api/clients/export","method":"get"},{"path":"/panel/api/clients/import","method":"post"},{"path":"/panel/api/clients/bulkAdjust","method":"post"},{"path":"/panel/api/clients/bulkEnable","method":"post"},{"path":"/panel/api/clients/bulkDisable","method":"post"},{"path":"/panel/api/clients/bulkDel","method":"post"},{"path":"/panel/api/clients/bulkCreate","method":"post"},{"path":"/panel/api/clients/groups/bulkAdd","method":"post"},{"path":"/panel/api/clients/groups/bulkRemove","method":"post"},{"path":"/panel/api/clients/bulkAttach","method":"post"},{"path":"/panel/api/clients/bulkDetach","method":"post"},{"path":"/panel/api/clients/bulkResetTraffic","method":"post"},{"path":"/panel/api/clients/groups","method":"get"},{"path":"/panel/api/clients/groups/{name}/emails","method":"get"},{"path":"/panel/api/clients/groups/create","method":"post"},{"path":"/panel/api/clients/groups/rename","method":"post"},{"path":"/panel/api/clients/groups/delete","method":"post"},{"path":"/panel/api/clients/resetTraffic/{email}","method":"post"},{"path":"/panel/api/clients/updateTraffic/{email}","method":"post"},{"path":"/panel/api/clients/ips/{email}","method":"post"},{"path":"/panel/api/clients/clearIps/{email}","method":"post"},{"path":"/panel/api/clients/onlines","method":"post"},{"path":"/panel/api/clients/onlinesByGuid","method":"post"},{"path":"/panel/api/clients/clientIpsByGuid","method":"post"},{"path":"/panel/api/clients/activeInbounds","method":"post"},{"path":"/panel/api/clients/lastOnline","method":"post"},{"path":"/panel/api/clients/traffic/{email}","method":"get"},{"path":"/panel/api/clients/subLinks/{subId}","method":"get"},{"path":"/panel/api/clients/links/{email}","method":"get"}]} showTitle />
</>
);
}
}
@@ -3,10 +3,10 @@ title: سرور اشتراک
description: >-
یک سرور HTTP/HTTPS جداگانه که لینک‌های اشتراک پراکسی (استاندارد، JSON و Clash)
را به کلاینت‌ها ارائه می‌دهد. این سرور روی پورت اختصاصی خودش (به‌صورت پیش‌فرض
10882) گوش می‌دهد و در بخش Settings ← Subscription پیکربندی می‌شود. مسیرها قابل
پیکربندی هستند؛ مقادیر پیش‌فرض در ادامه نشان داده شده‌اند. همه‌ی نقاط پایانی
اشتراک، هدرهای پاسخ را برای خواندن اطلاعات ترافیک/انقضا توسط برنامه‌های کلاینت
تنظیم می‌کنند.
2096) گوش می‌دهد و در بخش Settings ← Subscription پیکربندی می‌شود. پنل‌های جدید
برای هر قالب پیشوند مسیر تصادفی تولید می‌کنند و همه‌ی مسیرها قابل پیکربندی
می‌مانند. همه‌ی نقاط پایانی اشتراک، هدرهای پاسخ را برای خواندن اطلاعات
ترافیک/انقضا توسط برنامه‌های کلاینت تنظیم می‌کنند.
full: true
_openapi:
preload:
@@ -16,45 +16,46 @@ _openapi:
title: >-
Return base64-encoded subscription links for all enabled clients
matching the subscription ID. When the request has an Accept: text/html
header or ?html=1, renders a styled info page instead. Default path:
/sub/:subid.
header or ?html=1, renders a styled info page instead. The path prefix is
configured by subPath.
url: >-
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- depth: 2
title: >-
Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
url: >-
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- depth: 2
title: >-
Return subscription as a Clash/Mihomo-compatible YAML config, including
configured global Clash routing rules. Only when Clash subscription is
enabled in settings. Default path: /clash/:subid.
enabled in settings. The path prefix is configured by subClashPath.
url: >-
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
structuredData:
headings:
- content: >-
Return base64-encoded subscription links for all enabled clients
matching the subscription ID. When the request has an Accept:
text/html header or ?html=1, renders a styled info page instead.
Default path: /sub/:subid.
text/html header or ?html=1, renders a styled info page instead. The
path prefix is configured by subPath.
id: >-
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- content: >-
Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
id: >-
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- content: >-
Return subscription as a Clash/Mihomo-compatible YAML config,
including configured global Clash routing rules. Only when Clash
subscription is enabled in settings. Default path: /clash/:subid.
subscription is enabled in settings. The path prefix is configured by
subClashPath.
id: >-
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
contents: []
---
@@ -70,4 +71,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
</>
);
}
}
+6 -6
View File
@@ -18,7 +18,7 @@ icon: Rss
| ------------- | ------- | --------------------------------------------------------------- |
| `subPort` | `2096` | Порт прослушивания (отдельный от панели). |
| `subListen` | _(все)_ | Адрес привязки. |
| `subPath` | `/sub/` | Базовый путь для необработанных URL подписок. |
| `subPath` | _(случайный для каждой панели)_ | Базовый путь для необработанных URL подписок. |
| `subDomain` | _(нет)_ | Публичный хост; если задан, сервер отвечает только для этого Host. |
| `subCertFile` / `subKeyFile` | _(нет)_ | Сертификат + ключ TLS — когда заданы, сервер работает по **HTTPS**. |
| `subEncrypt` | `true` | Кодировать тело необработанной подписки в base64. |
@@ -27,7 +27,7 @@ icon: Rss
URL подписки выглядит так:
```text
https://<sub-host>:<sub-port>/sub/<sub-id>
https://<sub-host>:<sub-port>/<sub-path>/<sub-id>
```
где `<sub-id>` — это **Sub ID** клиента.
@@ -44,13 +44,13 @@ https://<sub-host>:<sub-port>/sub/<sub-id>
| Формат | Путь | Включается | Вывод |
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
| **Необработанные ссылки** | `/sub/` | всегда (если включён) | Список ссылок `vless://`, `vmess://`, … (закодированных в base64, когда включён `subEncrypt`). |
| **JSON** | `/json/` | `subJsonEnable` | Полные клиентские конфигурации Xray. |
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | YAML-профиль. |
| **Необработанные ссылки** | `subPath` | всегда (если включён) | Список ссылок `vless://`, `vmess://`, … (закодированных в base64, когда включён `subEncrypt`). |
| **JSON** | `subJsonPath` | `subJsonEnable` | Полные клиентские конфигурации Xray. |
| **Clash / Mihomo** | `subClashPath` | `subClashEnable` | YAML-профиль. |
В подписке появляются только включённые входящие соединения, использующие
**VLESS, VMess, Trojan, Shadowsocks или Hysteria2**, упорядоченные по их индексу
сортировки подписки. Запрос `/sub/` с заголовком `Accept: text/html` (или
сортировки подписки. Запрос `subPath` с заголовком `Accept: text/html` (или
`?html=1`) возвращает удобочитаемую информационную страницу вместо
необработанного тела.
+11 -9
View File
@@ -311,11 +311,12 @@ _openapi:
title: >-
Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
result set as the configured subPath endpoint, but as a JSON array — no
base64. When an inbound has streamSettings.externalProxy set, one URL is
emitted per external proxy. Empty array when the subId has no enabled
clients.
url: >-
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- depth: 2
title: >-
Return every URL for one client across all attached inbounds — the same
@@ -593,11 +594,12 @@ _openapi:
- content: >-
Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, hy2://) for clients matching the subscription ID. Same
result set as /sub/<subId>, but as a JSON array — no base64. When an
inbound has streamSettings.externalProxy set, one URL is emitted per
external proxy. Empty array when the subId has no enabled clients.
result set as the configured subPath endpoint, but as a JSON array —
no base64. When an inbound has streamSettings.externalProxy set, one
URL is emitted per external proxy. Empty array when the subId has no
enabled clients.
id: >-
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- content: >-
Return every URL for one client across all attached inbounds — the
same strings the Copy URL button copies in the panel UI. Supported
@@ -672,4 +674,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/clients/list","method":"get"},{"path":"/panel/api/clients/list/paged","method":"get"},{"path":"/panel/api/clients/get/{email}","method":"get"},{"path":"/panel/api/clients/add","method":"post"},{"path":"/panel/api/clients/update/{email}","method":"post"},{"path":"/panel/api/clients/del/{email}","method":"post"},{"path":"/panel/api/clients/{email}/attach","method":"post"},{"path":"/panel/api/clients/{email}/detach","method":"post"},{"path":"/panel/api/clients/{email}/externalLinks","method":"post"},{"path":"/panel/api/clients/resetAllTraffics","method":"post"},{"path":"/panel/api/clients/delDepleted","method":"post"},{"path":"/panel/api/clients/delOrphans","method":"post"},{"path":"/panel/api/clients/export","method":"get"},{"path":"/panel/api/clients/import","method":"post"},{"path":"/panel/api/clients/bulkAdjust","method":"post"},{"path":"/panel/api/clients/bulkEnable","method":"post"},{"path":"/panel/api/clients/bulkDisable","method":"post"},{"path":"/panel/api/clients/bulkDel","method":"post"},{"path":"/panel/api/clients/bulkCreate","method":"post"},{"path":"/panel/api/clients/groups/bulkAdd","method":"post"},{"path":"/panel/api/clients/groups/bulkRemove","method":"post"},{"path":"/panel/api/clients/bulkAttach","method":"post"},{"path":"/panel/api/clients/bulkDetach","method":"post"},{"path":"/panel/api/clients/bulkResetTraffic","method":"post"},{"path":"/panel/api/clients/groups","method":"get"},{"path":"/panel/api/clients/groups/{name}/emails","method":"get"},{"path":"/panel/api/clients/groups/create","method":"post"},{"path":"/panel/api/clients/groups/rename","method":"post"},{"path":"/panel/api/clients/groups/delete","method":"post"},{"path":"/panel/api/clients/resetTraffic/{email}","method":"post"},{"path":"/panel/api/clients/updateTraffic/{email}","method":"post"},{"path":"/panel/api/clients/ips/{email}","method":"post"},{"path":"/panel/api/clients/clearIps/{email}","method":"post"},{"path":"/panel/api/clients/onlines","method":"post"},{"path":"/panel/api/clients/onlinesByGuid","method":"post"},{"path":"/panel/api/clients/clientIpsByGuid","method":"post"},{"path":"/panel/api/clients/activeInbounds","method":"post"},{"path":"/panel/api/clients/lastOnline","method":"post"},{"path":"/panel/api/clients/traffic/{email}","method":"get"},{"path":"/panel/api/clients/subLinks/{subId}","method":"get"},{"path":"/panel/api/clients/links/{email}","method":"get"}]} showTitle />
</>
);
}
}
@@ -3,10 +3,10 @@ title: Сервер подписок
description: >-
Отдельный HTTP/HTTPS-сервер, который отдаёт клиентам ссылки на подписки
прокси (стандартные, JSON и Clash). Сервер слушает на собственном порту (по
умолчанию 10882) и настраивается в разделе Settings → Subscription. Пути
настраиваемы; значения по умолчанию показаны ниже. Все конечные точки подписок
устанавливают заголовки ответа, по которым клиентские приложения считывают
информацию о трафике и сроке действия.
умолчанию 2096) и настраивается в разделе Settings → Subscription. Новые
панели генерируют случайные префиксы путей для каждого формата; все пути можно
изменить. Все конечные точки подписок устанавливают заголовки ответа, по
которым клиентские приложения считывают информацию о трафике и сроке действия.
full: true
_openapi:
preload:
@@ -16,45 +16,46 @@ _openapi:
title: >-
Return base64-encoded subscription links for all enabled clients
matching the subscription ID. When the request has an Accept: text/html
header or ?html=1, renders a styled info page instead. Default path:
/sub/:subid.
header or ?html=1, renders a styled info page instead. The path prefix is
configured by subPath.
url: >-
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- depth: 2
title: >-
Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
url: >-
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- depth: 2
title: >-
Return subscription as a Clash/Mihomo-compatible YAML config, including
configured global Clash routing rules. Only when Clash subscription is
enabled in settings. Default path: /clash/:subid.
enabled in settings. The path prefix is configured by subClashPath.
url: >-
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
structuredData:
headings:
- content: >-
Return base64-encoded subscription links for all enabled clients
matching the subscription ID. When the request has an Accept:
text/html header or ?html=1, renders a styled info page instead.
Default path: /sub/:subid.
text/html header or ?html=1, renders a styled info page instead. The
path prefix is configured by subPath.
id: >-
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- content: >-
Return subscription as a JSON array of proxy configs (one per enabled
client). Only when JSON subscription is enabled in settings. Default
path: /json/:subid.
client). Only when JSON subscription is enabled in settings. The path
prefix is configured by subJsonPath.
id: >-
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- content: >-
Return subscription as a Clash/Mihomo-compatible YAML config,
including configured global Clash routing rules. Only when Clash
subscription is enabled in settings. Default path: /clash/:subid.
subscription is enabled in settings. The path prefix is configured by
subClashPath.
id: >-
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
contents: []
---
@@ -70,4 +71,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
</>
);
}
}
+6 -6
View File
@@ -14,7 +14,7 @@ icon: Rss
| ------------- | ------- | --------------------------------------------------------------- |
| `subPort` | `2096` | 监听端口(与面板分开)。 |
| `subListen` | _(全部)_ | 绑定地址。 |
| `subPath` | `/sub/` | 原始订阅 URL 的基础路径。 |
| `subPath` | _(每个面板随机生成)_ | 原始订阅 URL 的基础路径。 |
| `subDomain` | _(无)_ | 公开主机名;若设置,服务器仅响应该 Host。 |
| `subCertFile` / `subKeyFile` | _(无)_ | TLS 证书 + 密钥 —— 设置后,服务器以 **HTTPS** 提供服务。 |
| `subEncrypt` | `true` | 对原始订阅内容进行 base64 编码。 |
@@ -23,7 +23,7 @@ icon: Rss
一个订阅 URL 形如:
```text
https://<sub-host>:<sub-port>/sub/<sub-id>
https://<sub-host>:<sub-port>/<sub-path>/<sub-id>
```
其中 `<sub-id>` 是客户端的 **Sub ID**。
@@ -38,11 +38,11 @@ https://<sub-host>:<sub-port>/sub/<sub-id>
| 格式 | 路径 | 启用方式 | 输出 |
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
| **原始链接** | `/sub/` | 始终(若已开启) | 一组 `vless://`、`vmess://` 等链接的列表(当 `subEncrypt` 开启时进行 base64 编码)。 |
| **JSON** | `/json/` | `subJsonEnable` | 完整的 Xray 客户端配置。 |
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | YAML 配置文件。 |
| **原始链接** | `subPath` | 始终(若已开启) | 一组 `vless://`、`vmess://` 等链接的列表(当 `subEncrypt` 开启时进行 base64 编码)。 |
| **JSON** | `subJsonPath` | `subJsonEnable` | 完整的 Xray 客户端配置。 |
| **Clash / Mihomo** | `subClashPath` | `subClashEnable` | YAML 配置文件。 |
只有使用 **VLESS、VMess、Trojan、Shadowsocks 或 Hysteria2** 的已启用入站才会出现在订阅中,并按其订阅排序索引排列。使用 `Accept: text/html` 头(或 `?html=1`)请求 `/sub/` 会返回一个人类可读的信息页面,而非原始内容。
只有使用 **VLESS、VMess、Trojan、Shadowsocks 或 Hysteria2** 的已启用入站才会出现在订阅中,并按其订阅排序索引排列。使用 `Accept: text/html` 头(或 `?html=1`)请求 `subPath` 会返回一个人类可读的信息页面,而非原始内容。
### Base64 与 JSON
@@ -255,11 +255,11 @@ _openapi:
- depth: 2
title: >-
返回与该订阅 ID 匹配的客户端的每个协议 URLvless://、vmess://、trojan://、ss://、
hysteria://、hy2://)。结果集与 /sub/<subId> 相同,但以 JSON 数组形式返回——不含
hysteria://、hy2://)。结果集与配置的 subPath 端点相同,但以 JSON 数组形式返回——不含
base64。当某入站设置了 streamSettings.externalProxy 时,每个外部代理会发出一条 URL。
当该 subId 没有已启用的客户端时返回空数组。
url: >-
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- depth: 2
title: >-
返回单个客户端在所有挂载入站上的每个 URL——与面板 UI 中“复制 URL”按钮所复制的字符串
@@ -477,11 +477,11 @@ _openapi:
id: traffic-counters-for-a-client-identified-by-email
- content: >-
返回与该订阅 ID 匹配的客户端的每个协议 URLvless://、vmess://、trojan://、ss://、
hysteria://、hy2://)。结果集与 /sub/<subId> 相同,但以 JSON 数组形式返回——不含
hysteria://、hy2://)。结果集与配置的 subPath 端点相同,但以 JSON 数组形式返回——不含
base64。当某入站设置了 streamSettings.externalProxy 时,每个外部代理会发出一条 URL。
当该 subId 没有已启用的客户端时返回空数组。
id: >-
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-the-configured-subpath-endpoint-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- content: >-
返回单个客户端在所有挂载入站上的每个 URL——与面板 UI 中“复制 URL”按钮所复制的字符串
相同。支持的协议:vmess、vless、trojan、shadowsocks、hysteria。若设置了
@@ -529,4 +529,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/clients/list","method":"get"},{"path":"/panel/api/clients/list/paged","method":"get"},{"path":"/panel/api/clients/get/{email}","method":"get"},{"path":"/panel/api/clients/add","method":"post"},{"path":"/panel/api/clients/update/{email}","method":"post"},{"path":"/panel/api/clients/del/{email}","method":"post"},{"path":"/panel/api/clients/{email}/attach","method":"post"},{"path":"/panel/api/clients/{email}/detach","method":"post"},{"path":"/panel/api/clients/{email}/externalLinks","method":"post"},{"path":"/panel/api/clients/resetAllTraffics","method":"post"},{"path":"/panel/api/clients/delDepleted","method":"post"},{"path":"/panel/api/clients/delOrphans","method":"post"},{"path":"/panel/api/clients/export","method":"get"},{"path":"/panel/api/clients/import","method":"post"},{"path":"/panel/api/clients/bulkAdjust","method":"post"},{"path":"/panel/api/clients/bulkEnable","method":"post"},{"path":"/panel/api/clients/bulkDisable","method":"post"},{"path":"/panel/api/clients/bulkDel","method":"post"},{"path":"/panel/api/clients/bulkCreate","method":"post"},{"path":"/panel/api/clients/groups/bulkAdd","method":"post"},{"path":"/panel/api/clients/groups/bulkRemove","method":"post"},{"path":"/panel/api/clients/bulkAttach","method":"post"},{"path":"/panel/api/clients/bulkDetach","method":"post"},{"path":"/panel/api/clients/bulkResetTraffic","method":"post"},{"path":"/panel/api/clients/groups","method":"get"},{"path":"/panel/api/clients/groups/{name}/emails","method":"get"},{"path":"/panel/api/clients/groups/create","method":"post"},{"path":"/panel/api/clients/groups/rename","method":"post"},{"path":"/panel/api/clients/groups/delete","method":"post"},{"path":"/panel/api/clients/resetTraffic/{email}","method":"post"},{"path":"/panel/api/clients/updateTraffic/{email}","method":"post"},{"path":"/panel/api/clients/ips/{email}","method":"post"},{"path":"/panel/api/clients/clearIps/{email}","method":"post"},{"path":"/panel/api/clients/onlines","method":"post"},{"path":"/panel/api/clients/onlinesByGuid","method":"post"},{"path":"/panel/api/clients/clientIpsByGuid","method":"post"},{"path":"/panel/api/clients/activeInbounds","method":"post"},{"path":"/panel/api/clients/lastOnline","method":"post"},{"path":"/panel/api/clients/traffic/{email}","method":"get"},{"path":"/panel/api/clients/subLinks/{subId}","method":"get"},{"path":"/panel/api/clients/links/{email}","method":"get"}]} showTitle />
</>
);
}
}
@@ -2,7 +2,7 @@
title: 订阅服务器
description: >-
一个独立的 HTTP/HTTPS 服务器,用于向客户端提供代理订阅链接(标准、JSON 和 Clash)。该服务器监听自己的端口(默认
10882),并在“设置 → 订阅”中进行配置。路径可自定义;下方展示的是默认值。所有订阅端点都会设置响应头,供客户端应用读取流量/到期信息。
2096),并在“设置 → 订阅”中进行配置。新面板会为每种格式生成随机路径前缀,所有路径仍可自定义。所有订阅端点都会设置响应头,供客户端应用读取流量/到期信息。
full: true
_openapi:
preload:
@@ -11,36 +11,36 @@ _openapi:
- depth: 2
title: >-
返回与该订阅 ID 匹配的所有已启用客户端的 base64 编码订阅链接。当请求带有 Accept: text/html
头或 ?html=1 时,改为渲染一个带样式的信息页面。默认路径:/sub/:subid
头或 ?html=1 时,改为渲染一个带样式的信息页面。路径前缀由 subPath 配置
url: >-
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- depth: 2
title: >-
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。默认路径:/json/:subid
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。路径前缀由 subJsonPath 配置
url: >-
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- depth: 2
title: >-
以兼容 Clash/Mihomo 的 YAML 配置形式返回订阅,其中包含已配置的全局 Clash 路由规则。仅在设置中启用 Clash
订阅时可用。默认路径:/clash/:subid
订阅时可用。路径前缀由 subClashPath 配置
url: >-
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
structuredData:
headings:
- content: >-
返回与该订阅 ID 匹配的所有已启用客户端的 base64 编码订阅链接。当请求带有 Accept:
text/html 头或 ?html=1 时,改为渲染一个带样式的信息页面。默认路径:/sub/:subid
text/html 头或 ?html=1 时,改为渲染一个带样式的信息页面。路径前缀由 subPath 配置
id: >-
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-with-formatinfo-returns-the-page-view-model-as-json-traffic-expiry-online-status-no-links-for-live-polling-the-path-prefix-is-configured-by-subpath
- content: >-
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。默认路径:/json/:subid
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。路径前缀由 subJsonPath 配置
id: >-
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subjsonpath
- content: >-
以兼容 Clash/Mihomo 的 YAML 配置形式返回订阅,其中包含已配置的全局 Clash 路由规则。仅在设置中启用 Clash
订阅时可用。默认路径:/clash/:subid
订阅时可用。路径前缀由 subClashPath 配置
id: >-
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-the-path-prefix-is-configured-by-subclashpath
contents: []
---
@@ -56,4 +56,4 @@ export default function Layout(props) {
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
</>
);
}
}
+5 -5
View File
@@ -3512,7 +3512,7 @@
},
{
"name": "Subscription Server",
"description": "A separate HTTP/HTTPS server that serves proxy subscription links (standard, JSON, and Clash) to clients. The server listens on its own port (default 10882) and is configured in Settings → Subscription. Paths are configurable; defaults are shown below. All subscription endpoints set response headers for client apps to read traffic/expiry info."
"description": "A separate HTTP/HTTPS server that serves proxy subscription links (standard, JSON, and Clash) to clients. The server listens on its own port (default 2096) and is configured in Settings → Subscription. Fresh panels generate random path prefixes for each format; all paths remain configurable. Every subscription endpoint sets response headers for client apps to read traffic/expiry info."
},
{
"name": "WebSocket",
@@ -8731,7 +8731,7 @@
"tags": [
"Clients"
],
"summary": "Return every protocol URL (vless://, vmess://, trojan://, ss://, hysteria://, hy2://) for clients matching the subscription ID. Same result set as /sub/<subId>, but as a JSON array — no base64. When an inbound has streamSettings.externalProxy set, one URL is emitted per external proxy. Empty array when the subId has no enabled clients.",
"summary": "Return every protocol URL (vless://, vmess://, trojan://, ss://, hysteria://, hy2://) for clients matching the subscription ID. Same result set as the configured subPath endpoint, but as a JSON array — no base64. When an inbound has streamSettings.externalProxy set, one URL is emitted per external proxy. Empty array when the subId has no enabled clients.",
"operationId": "get_panel_api_clients_subLinks_subId",
"parameters": [
{
@@ -12639,7 +12639,7 @@
"tags": [
"Subscription Server"
],
"summary": "Return base64-encoded subscription links for all enabled clients matching the subscription ID. When the request has an Accept: text/html header or ?html=1, renders a styled info page instead. With ?format=info, returns the page view-model as JSON (traffic, expiry, online status; no links) for live polling. Default path: /sub/:subid.",
"summary": "Return base64-encoded subscription links for all enabled clients matching the subscription ID. When the request has an Accept: text/html header or ?html=1, renders a styled info page instead. With ?format=info, returns the page view-model as JSON (traffic, expiry, online status; no links) for live polling. The path prefix is configured by subPath.",
"operationId": "get_subPath_subid",
"parameters": [
{
@@ -12698,7 +12698,7 @@
"tags": [
"Subscription Server"
],
"summary": "Return subscription as a JSON array of proxy configs (one per enabled client). Only when JSON subscription is enabled in settings. Default path: /json/:subid.",
"summary": "Return subscription as a JSON array of proxy configs (one per enabled client). Only when JSON subscription is enabled in settings. The path prefix is configured by subJsonPath.",
"operationId": "get_jsonPath_subid",
"parameters": [
{
@@ -12748,7 +12748,7 @@
"tags": [
"Subscription Server"
],
"summary": "Return subscription as a Clash/Mihomo-compatible YAML config, including configured global Clash routing rules. Only when Clash subscription is enabled in settings. Default path: /clash/:subid.",
"summary": "Return subscription as a Clash/Mihomo-compatible YAML config, including configured global Clash routing rules. Only when Clash subscription is enabled in settings. The path prefix is configured by subClashPath.",
"operationId": "get_clashPath_subid",
"parameters": [
{