mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-07 10:47:15 +00:00
0f6e1ae8d7
* fix(sub): bind JSON local inbounds to 127.0.0.1 and keep mux.cool off Vision outbounds The JSON subscription's local SOCKS/HTTP inbounds had no listen address, so every client that runs the profile verbatim bound an unauthenticated proxy on 0.0.0.0, and iOS packet-tunnel clients could not reach it at all (Happ iOS: CONNECTED with zero traffic, same symptom as #6379 — on the same device the mixed inbound also worked once bound to 127.0.0.1). Bind both to loopback, which is what every client's own generated config does. The global subJsonMux was also applied to VLESS outbounds carrying xtls-rprx-vision. XTLS flows do not support mux.cool: Xray answers the mux handshake with "common/mux: unexpected network TCP" and the tunnel passes nothing, on every platform (verified with Happ iOS/Android/macOS, V2Box iOS and desktop Xray 26.6.27 against a 3x-ui 3.7.0 box with per-client traffic counters). Skip the mux block whenever the outbound carries a flow. Refs #6379 * fix(sub): keep XUDP settings when disabling TCP mux on Vision outbounds Clearing the whole mux object also dropped xudpConcurrency, xudpProxyUDP443 and any per-host muxParams override. Xray reads those only under mux.enabled, so set concurrency to -1 instead: TCP mux.cool (which XTLS flows reject) is off, XUDP and the UDP/443 policy stay. The test now decodes each outbound into a fresh map. --------- Co-authored-by: Farhan Zare <farhan.zare@openscreen.com>
87 lines
4.1 KiB
Plaintext
87 lines
4.1 KiB
Plaintext
---
|
|
title: Subscription
|
|
description: Run the 3x-ui subscription server — base64/JSON/Clash formats, ports and paths, TLS, response headers, and custom templates.
|
|
icon: Rss
|
|
---
|
|
|
|
A **subscription** is a single URL that returns all of a client's
|
|
configurations. Client apps refresh it periodically, so when you change an
|
|
inbound, clients pick up the change automatically. The subscription server runs
|
|
as a **separate** server from the panel.
|
|
|
|
## Enable and configure
|
|
|
|
The subscription server is **on by default** (`subEnable`). Configure it in the
|
|
panel's subscription settings:
|
|
|
|
| Setting | Default | Meaning |
|
|
| ------------- | ------- | --------------------------------------------------------------- |
|
|
| `subPort` | `2096` | Listen port (separate from the panel). |
|
|
| `subListen` | _(all)_ | Bind address. |
|
|
| `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. |
|
|
| `subUpdates` | `12` | Suggested refresh interval (hours) sent to clients. |
|
|
|
|
A subscription URL looks like:
|
|
|
|
```text
|
|
https://<sub-host>:<sub-port>/<sub-path>/<sub-id>
|
|
```
|
|
|
|
where `<sub-id>` is the client's **Sub ID**.
|
|
|
|
The same Sub ID is served in several formats on different paths — the **Base64**
|
|
list at `subPath` and the **JSON** (Xray-json) config at the JSON path. Build the
|
|
URLs and preview both bodies here:
|
|
|
|
<SubscriptionBuilder />
|
|
|
|
## Output formats
|
|
|
|
The **format is chosen by path**, each with its own enable toggle:
|
|
|
|
| Format | Path | Enabled by | Output |
|
|
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
|
|
| **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 `subPath`
|
|
with an `Accept: text/html` header (or `?html=1`) returns a human-readable info
|
|
page instead of the raw body.
|
|
|
|
### Base64 vs JSON
|
|
|
|
The **Base64** body is just the newline-joined share links, standard-base64
|
|
encoded (toggle with `subEncrypt`). The **JSON** body wraps each client in a
|
|
complete Xray client config — a fixed skeleton (local SOCKS/HTTP inbounds bound to 127.0.0.1, DNS,
|
|
routing, policy) plus a `proxy` outbound pointing at the inbound. 3x-ui emits a
|
|
**single config object for one client and an array for several**, uses the flat
|
|
outbound `settings` form (`address`/`port`/`id`, `level: 8`), and strips
|
|
`sockopt` from `streamSettings`.
|
|
|
|
## Response headers
|
|
|
|
Subscriptions return standard headers that compatible apps read:
|
|
|
|
- **`Subscription-Userinfo`** — `upload`, `download`, `total` (bytes; `total=0`
|
|
means unlimited) and `expire` (Unix seconds).
|
|
- **`Profile-Update-Interval`** — refresh interval in hours (`subUpdates`).
|
|
- **`Profile-Title`**, **`Support-Url`**, **`Profile-Web-Page-Url`**,
|
|
**`Announce`** — optional branding shown by some clients.
|
|
|
|
## Custom page templates
|
|
|
|
Point `subThemeDir` at a folder containing a custom info-page template to brand
|
|
the HTML subscription page. The per-client remark on each link is fully
|
|
templated — see [Share links → remark variables](/docs/config/share-links#remark-template-variables).
|
|
|
|
<Callout type="info">
|
|
Put the subscription server behind TLS (set `subCertFile`/`subKeyFile`, or a
|
|
[reverse proxy](/docs/operations/reverse-proxy)) so subscription contents
|
|
aren't exposed in transit.
|
|
</Callout>
|