mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-09 06:06:08 +00:00
docs: vendor the documentation site into the monorepo
Fold the standalone 3x-ui-docs project (Next.js 16 + Fumadocs, deployed to docs.sanaei.dev) into docs/ so the panel and its documentation share a single source of truth, the way sing-box keeps its docs in-tree. The old repo becomes redundant and can be retired. - Import the full site under docs/ (app, components, content, lib, public, scripts, config). The self-contained pnpm project sits alongside the existing engineering notes with no filename collisions. - Re-point "Edit on GitHub" links from MHSanaei/3x-ui-docs to this repo's docs/content/docs path (docs/lib/shared.ts, docs/app/.../page.tsx). - Add docs-ci.yml and docs-deploy.yml under .github/workflows/, scoped to docs/** and run with working-directory: docs, since GitHub only runs workflows from the repo-root .github/. deploy-static.yml's GitHub Pages publish (CNAME docs.sanaei.dev) carries over unchanged. Follow-up (outside this commit): attach the docs.sanaei.dev custom domain to this repository's Pages (or set the Vercel project's root directory to docs), confirm the site is live from the monorepo, then delete MHSanaei/3x-ui-docs.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: Clients
|
||||
description: Manage 3x-ui clients — credentials, traffic and expiry limits, IP limits, groups, bulk actions, external links, and online status.
|
||||
icon: Users
|
||||
---
|
||||
|
||||
A **client** is a single user, identified by a unique **email**. In the current
|
||||
panel, clients are first-class records that can be attached to **multiple
|
||||
inbounds** at once, with per-client traffic accounting.
|
||||
|
||||
## Client fields
|
||||
|
||||
| Field | Applies to | Meaning |
|
||||
| -------------- | --------------------- | ------------------------------------------------------------------ |
|
||||
| **Email** | all | Unique identifier used for accounting and lookups. |
|
||||
| **ID (UUID)** | VLESS, VMess | The client credential. |
|
||||
| **Password** | Trojan, Shadowsocks | The client credential. |
|
||||
| **Auth** | Hysteria2 | The client credential. |
|
||||
| **Flow** | VLESS | XTLS flow, e.g. `xtls-rprx-vision`. |
|
||||
| **Limit IP** | all | Max simultaneous source IPs (enforced via Fail2ban). |
|
||||
| **Total (GB)** | all | Traffic quota; the client is disabled when exhausted. |
|
||||
| **Expiry** | all | Date after which the client stops working. |
|
||||
| **Reset** | all | Auto-renew period in **days** (rolls the quota over). |
|
||||
| **Telegram ID**| all | Links the client to a Telegram user for self-service/notifications.|
|
||||
| **Sub ID** | all | Subscription identifier grouping this client's links. |
|
||||
| **Group** | all | Optional client group for organization and bulk filtering. |
|
||||
| **Comment** | all | Free-text note. |
|
||||
|
||||
<Callout type="info">
|
||||
Reaching the **traffic** or **expiry** limit disables the client; the panel can
|
||||
restart Xray automatically when clients are auto-disabled
|
||||
(`restartXrayOnClientDisable`, on by default).
|
||||
</Callout>
|
||||
|
||||
## Limits and IP control
|
||||
|
||||
- **Traffic / expiry** caps disable the client when hit; a **Reset** period
|
||||
auto-renews the quota.
|
||||
- **Limit IP** caps simultaneous source IPs. Enforcement relies on Fail2ban —
|
||||
see [Security](/docs/operations/security). You can view a client's recent IPs
|
||||
and clear them from the client's actions.
|
||||
- **Online status** and **last-online** times are tracked per client (and per
|
||||
node in multi-node setups).
|
||||
|
||||
## Share links and external links
|
||||
|
||||
Every client has share links and a QR code for its inbounds, plus a combined
|
||||
[subscription](/docs/config/subscription). You can also attach **external
|
||||
links** to a client — extra `vless://`, `vmess://`, `trojan://`, `ss://`,
|
||||
`hysteria2://`, or `wireguard://` links, or a remote subscription URL — so they
|
||||
appear alongside the panel-generated ones in the client's subscription.
|
||||
|
||||
To inspect exactly what a link contains, paste it into the
|
||||
[share-link inspector](/docs/config/share-links).
|
||||
|
||||
## Bulk actions
|
||||
|
||||
For managing many clients at once, the panel supports bulk **create, enable,
|
||||
disable, delete, attach/detach** (to inbounds), **reset traffic**, and
|
||||
**adjust** (add days / add bytes / set flow). Maintenance actions also let you
|
||||
delete **depleted** clients (quota/expiry exhausted) and **orphaned** clients
|
||||
(not attached to any inbound).
|
||||
|
||||
<Callout type="warn">
|
||||
A client's share link contains its credential. Treat links and QR codes like
|
||||
passwords, and rotate the credential if one leaks.
|
||||
</Callout>
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Inbounds & Protocols
|
||||
description: Create inbounds in 3x-ui — protocols, transports, traffic reset and expiry, and fallbacks that serve multiple protocols on one port.
|
||||
icon: ArrowDownToLine
|
||||
---
|
||||
|
||||
An **inbound** is a listener that accepts client connections on a port using a
|
||||
particular protocol and transport. Most of your day-to-day work is creating and
|
||||
managing inbounds and the clients inside them.
|
||||
|
||||
## Create an inbound
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Add an inbound
|
||||
|
||||
Open **Inbounds → Add**, give it a remark, pick a **protocol**, and choose a
|
||||
**port** and listen address.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Choose a transport and security
|
||||
|
||||
Pick the transport (TCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, …) and the security
|
||||
layer (none, TLS, or REALITY). See [Transports](/docs/config/transports) and
|
||||
[REALITY](/docs/config/reality).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Add clients
|
||||
|
||||
Add one or more clients, each with its own credential, limits, and share link.
|
||||
See [Clients](/docs/config/clients).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Set traffic limit, expiry, and reset
|
||||
|
||||
Optionally cap total traffic and set an expiry date for the inbound, and choose a
|
||||
periodic **traffic reset** schedule: `never` (default), `hourly`, `daily`,
|
||||
`weekly`, or `monthly`.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Supported protocols
|
||||
|
||||
The inbound editor accepts these protocols:
|
||||
|
||||
| Protocol | Notes |
|
||||
| ---------------------- | ------------------------------------------------------------------------ |
|
||||
| **VLESS** | Lightweight; the basis for REALITY + XTLS-Vision. Recommended. |
|
||||
| **VMess** | Older but very widely supported by clients. |
|
||||
| **Trojan** | TLS-based; supports XTLS and fallbacks. |
|
||||
| **Shadowsocks** | Includes Shadowsocks-2022 (`2022-blake3-*`) ciphers. |
|
||||
| **WireGuard** | Modern tunnel. |
|
||||
| **Hysteria2** | Selected as `hysteria`; the panel emits `hysteria2://` links. |
|
||||
| **HTTP** | HTTP proxy. |
|
||||
| **Mixed (SOCKS/HTTP)** | A combined SOCKS + HTTP listener. |
|
||||
| **Dokodemo-door / Tunnel** | Port forwarding / traffic redirect. |
|
||||
| **MTProto** | Telegram MTProto proxy, served by a bundled `mtg` process (not Xray). |
|
||||
|
||||
<Callout type="info">
|
||||
Hysteria2 isn't a separate protocol internally — it's the `hysteria` protocol
|
||||
with the transport version set to 2, and the panel generates `hysteria2://`
|
||||
share links for it.
|
||||
</Callout>
|
||||
|
||||
## Fallbacks — multiple protocols on one port
|
||||
|
||||
Fallbacks let a single TLS port (e.g. `443`) serve more than one protocol — for
|
||||
example VLESS **and** Trojan — by routing unmatched handshakes to a child
|
||||
inbound. In 3x-ui, fallbacks are managed in the panel (a master inbound's
|
||||
**Fallbacks** list) rather than hand-written into JSON.
|
||||
|
||||
Fallbacks are available only when the master inbound is:
|
||||
|
||||
- **VLESS** or **Trojan**,
|
||||
- on the raw **TCP** transport,
|
||||
- with **TLS** or **REALITY** security.
|
||||
|
||||
Each fallback rule targets a child inbound and can match on `path`, `alpn`, and
|
||||
`dest`. Client share links for a fallback child are automatically rewritten to
|
||||
advertise the master's address, port, and TLS.
|
||||
|
||||
## Not sure which to pick?
|
||||
|
||||
Use the wizard to get a recommendation based on your goals and clients:
|
||||
|
||||
<ProtocolWizard />
|
||||
|
||||
<Callout type="info">
|
||||
For censorship resistance with modern clients, **VLESS + REALITY +
|
||||
XTLS-Vision** is the usual best choice — continue to
|
||||
[REALITY](/docs/config/reality).
|
||||
</Callout>
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "Configuration",
|
||||
"icon": "Settings",
|
||||
"pages": [
|
||||
"panel",
|
||||
"ssl-certificates",
|
||||
"inbounds",
|
||||
"reality",
|
||||
"transports",
|
||||
"clients",
|
||||
"subscription",
|
||||
"share-links"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Panel Settings
|
||||
description: Every 3x-ui panel setting — web server, TLS, display, security, and notifications — with defaults from the source.
|
||||
icon: SlidersHorizontal
|
||||
---
|
||||
|
||||
**Panel Settings** controls how the panel itself is served and secured (separate
|
||||
from your inbounds and clients). Settings are stored as key/value pairs; the
|
||||
defaults below come straight from the panel source. Secrets (tokens, passwords)
|
||||
are shown only as a "set / not set" indicator and are never returned to the
|
||||
browser in full.
|
||||
|
||||
## Web server
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
||||
| `webPort` | `2053` | Panel port (1–65535). The `XUI_PORT` env var overrides it at runtime. |
|
||||
| `webListen` | _(all interfaces)_ | Bind the panel to a specific IP. |
|
||||
| `webBasePath` | `/` | URL path the panel is served under (always normalized to `/…/`). |
|
||||
| `webCertFile` / `webKeyFile` | _(none)_ | TLS certificate + key. When both are set, the panel serves **HTTPS**. |
|
||||
| `sessionMaxAge` | `360` | Session lifetime in **minutes** (default 6 hours). |
|
||||
| `trustedProxyCIDRs` | `127.0.0.1/32,::1/128` | IPs/CIDRs whose forwarded headers (real client IP) are trusted. |
|
||||
| `panelOutbound` | _(none)_ | Route the panel's own egress (update checks, Telegram, geo/sub fetches) through a named Xray outbound. |
|
||||
|
||||
After changing the port or base path, the panel URL becomes
|
||||
`http(s)://<server>:<port><web-base-path>`. You can preset the base path on first
|
||||
launch with [`XUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars).
|
||||
|
||||
### TLS
|
||||
|
||||
Serving the panel over HTTPS protects your credentials in transit. Either set
|
||||
`webCertFile` + `webKeyFile` — the [`x-ui` SSL menu](/docs/config/ssl-certificates)
|
||||
can obtain a Let's Encrypt certificate for you — or terminate TLS at a
|
||||
[reverse proxy](/docs/operations/reverse-proxy).
|
||||
|
||||
<Callout type="warn">
|
||||
Never expose the panel over plain HTTP on the public internet. Use TLS, a
|
||||
non-default port, and a long random web base path.
|
||||
</Callout>
|
||||
|
||||
## Display
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ---------------- | ------------------------------------------------ | ------------------------------------------------------------- |
|
||||
| `pageSize` | `25` | Rows per page in lists (`0` disables pagination). |
|
||||
| `expireDiff` | `0` | Days before expiry to start warning. |
|
||||
| `trafficDiff` | `0` | Percent of quota remaining at which to start warning. |
|
||||
| `remarkTemplate` | `{{INBOUND}}-{{EMAIL}}\|📊{{TRAFFIC_LEFT}}\|⏳{{DAYS_LEFT}}D` | Default client remark template (see [Share links](/docs/config/share-links#remark-template-variables)). |
|
||||
| `timeLocation` | `Local` | Time zone for stats and expiry. |
|
||||
| `datepicker` | `gregorian` | Calendar for date inputs (Gregorian or Jalali/Persian). |
|
||||
|
||||
## Security & authentication
|
||||
|
||||
Credentials, two-factor auth, the brute-force limiter, sessions, and LDAP are
|
||||
covered in [First login](/docs/guide/first-login) and
|
||||
[Security](/docs/operations/security). In short:
|
||||
|
||||
- Passwords are stored as **bcrypt** hashes; changing them logs out all sessions.
|
||||
- **2FA (TOTP)** can be required at login.
|
||||
- An **LDAP** fallback can authenticate users when the local password check fails.
|
||||
- API access uses **API tokens** managed under Panel Settings (see the
|
||||
[API reference](/docs/reference/api/api-tokens)).
|
||||
|
||||
## Notifications & subscription
|
||||
|
||||
These have their own settings groups and pages:
|
||||
|
||||
<Cards>
|
||||
<Card title="Telegram bot" href="/docs/operations/telegram-bot" description="Token, chat IDs, alerts, and reports." />
|
||||
<Card title="Subscription" href="/docs/config/subscription" description="Subscription server, formats, and paths." />
|
||||
<Card title="Security" href="/docs/operations/security" description="2FA, IP limits, and hardening." />
|
||||
</Cards>
|
||||
|
||||
<Callout type="info">
|
||||
Email (SMTP) notifications are also configurable (host, port, encryption,
|
||||
recipients) with the same event types as the Telegram bot.
|
||||
</Callout>
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
title: REALITY
|
||||
description: Set up a VLESS + REALITY inbound with XTLS-Vision in 3x-ui — keys, short IDs, SNI, fingerprints, and common pitfalls.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
**REALITY** is an Xray transport security that disguises your proxy as ordinary
|
||||
traffic to a real, popular website. Unlike classic TLS, your server needs **no
|
||||
certificate of its own** — it borrows the TLS handshake of the target site
|
||||
(`dest`). Combined with the **XTLS-Vision** flow, it is fast and resistant to
|
||||
deep-packet inspection.
|
||||
|
||||
REALITY is used with **VLESS** (and Trojan). The recommended flow is
|
||||
`xtls-rprx-vision`.
|
||||
|
||||
## Key settings
|
||||
|
||||
When you choose **REALITY** as the security mode on a VLESS inbound, 3x-ui
|
||||
exposes these fields:
|
||||
|
||||
| Field | What it is |
|
||||
| ------------------------ | ------------------------------------------------------------------ |
|
||||
| **Dest (target)** | A real TLS site to impersonate, e.g. `www.microsoft.com:443`. |
|
||||
| **SNI / Server Names** | The hostname(s) clients send; must match the target's certificate. |
|
||||
| **Public / Private key** | An **x25519** keypair. The private key stays on the server. |
|
||||
| **Short IDs** | Hex strings used to authenticate clients (you can have several). |
|
||||
| **Flow** | Set to `xtls-rprx-vision`. |
|
||||
| **Fingerprint (uTLS)** | The client TLS fingerprint to mimic, e.g. `chrome`. |
|
||||
|
||||
The private key is generated with Xray's `x25519` utility (the panel can
|
||||
generate the pair for you):
|
||||
|
||||
```bash title="generate an x25519 keypair"
|
||||
xray x25519
|
||||
```
|
||||
|
||||
## Set it up in the panel
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Create a VLESS inbound
|
||||
|
||||
Add a new inbound, choose protocol **VLESS**, and set **Security** to
|
||||
**reality**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Choose a target (dest) and SNI
|
||||
|
||||
Pick a reputable site that supports TLS 1.3 and HTTP/2 and is reachable from your
|
||||
server and your clients (for example `www.microsoft.com:443`). Set the server
|
||||
names / SNI to match that site's certificate.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Generate keys and short IDs
|
||||
|
||||
Generate the x25519 keypair and one or more short IDs. Keep the **private key**
|
||||
secret; clients only ever receive the **public key**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Set the flow and fingerprint
|
||||
|
||||
Use the `xtls-rprx-vision` flow and a common uTLS fingerprint such as `chrome`.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Add a client and share the link
|
||||
|
||||
Create a client, then use its share link or QR code in a compatible app
|
||||
(v2rayNG, Hiddify, Mihomo, and others).
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## What the configuration looks like
|
||||
|
||||
On the server, a REALITY inbound's `streamSettings` looks roughly like this:
|
||||
|
||||
```json title="server inbound (excerpt)"
|
||||
{
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "www.microsoft.com:443",
|
||||
"serverNames": ["www.microsoft.com"],
|
||||
"privateKey": "<x25519 private key>",
|
||||
"shortIds": ["<hex short id>"],
|
||||
"fingerprint": "chrome"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The matching client share link carries the **public** parameters:
|
||||
|
||||
```text title="vless:// (excerpt)"
|
||||
vless://<uuid>@<server>:443?security=reality&pbk=<public-key>&sid=<short-id>&sni=www.microsoft.com&fp=chrome&spx=%2F&flow=xtls-rprx-vision#my-reality
|
||||
```
|
||||
|
||||
- `pbk` — REALITY **public** key
|
||||
- `sid` — short ID (matches one on the server)
|
||||
- `sni` — server name (matches the target's certificate)
|
||||
- `fp` — client fingerprint
|
||||
- `spx` — spiderX path
|
||||
- `flow` — `xtls-rprx-vision`
|
||||
|
||||
## Common pitfalls
|
||||
|
||||
<Callout type="warn">
|
||||
|
||||
- **Bad target.** The `dest` must be a real site that supports **TLS 1.3** and
|
||||
**HTTP/2**, is reachable, and isn't blocked in your region. Pick a site you do
|
||||
not own and that sees lots of traffic.
|
||||
- **SNI mismatch.** The SNI / server names must match the target's real
|
||||
certificate, or the handshake gives the disguise away.
|
||||
- **Leaked private key.** Only ever distribute the **public** key to clients.
|
||||
- **Wrong flow.** REALITY + XTLS-Vision needs `flow = xtls-rprx-vision` on both
|
||||
the inbound client entry and the share link.
|
||||
|
||||
</Callout>
|
||||
|
||||
## Generate a config
|
||||
|
||||
Use the generator below to create a fresh X25519 keypair, UUID, and short ID,
|
||||
then copy the server inbound JSON and the client share link. Everything is
|
||||
computed **in your browser** — no keys or links are sent anywhere.
|
||||
|
||||
<RealityConfigGenerator />
|
||||
|
||||
<Callout type="info">
|
||||
The **private key** belongs only on your server. Share the generated
|
||||
`vless://` link (which contains the **public** key) with clients.
|
||||
</Callout>
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Share Links
|
||||
description: 3x-ui share-link formats (vless, vmess, trojan, ss, hysteria2, mtproto), the remark template variables, and an in-browser link inspector.
|
||||
icon: Link
|
||||
---
|
||||
|
||||
3x-ui generates a **share link** (and QR code) for each client. Client apps such
|
||||
as v2rayNG, Hiddify, and Mihomo import these links to configure themselves.
|
||||
|
||||
## Link formats
|
||||
|
||||
| Scheme | Shape |
|
||||
| -------------- | --------------------------------------------------------------- |
|
||||
| `vless://` | `vless://<uuid>@<host>:<port>?<params>#<remark>` |
|
||||
| `vmess://` | `vmess://<base64-json>` (a base64-encoded JSON object) |
|
||||
| `trojan://` | `trojan://<password>@<host>:<port>?<params>#<remark>` |
|
||||
| `ss://` | `ss://<userinfo>@<host>:<port>?<params>#<remark>` (SIP002; Shadowsocks-2022 uses percent-encoded userinfo) |
|
||||
| `hysteria2://` | `hysteria2://<auth>@<host>:<port>?<params>#<remark>` |
|
||||
| `tg://proxy` | `tg://proxy?server=…&port=…&secret=…` (MTProto) |
|
||||
|
||||
The query parameters carry the transport and security settings — `security`,
|
||||
`sni`, `fp`, `pbk`, `sid`, `spx`, `flow`, `type`, `path`, `host`, `alpn`, and
|
||||
more.
|
||||
|
||||
## Inspect a link
|
||||
|
||||
Paste any share link to decode every field. Parsing happens **entirely in your
|
||||
browser** — the link is never sent over the network.
|
||||
|
||||
<ShareLinkInspector />
|
||||
|
||||
<Callout type="warn">
|
||||
Share links contain everything needed to connect as a client, including the
|
||||
client's credential. Treat them like passwords.
|
||||
</Callout>
|
||||
|
||||
## Remark template variables
|
||||
|
||||
The text after `#` in each link (the **remark**) is generated from a template
|
||||
you control in Panel Settings (`remarkTemplate`). The default is:
|
||||
|
||||
```text
|
||||
{{INBOUND}}-{{EMAIL}}|📊{{TRAFFIC_LEFT}}|⏳{{DAYS_LEFT}}D
|
||||
```
|
||||
|
||||
Tokens use `{{UPPER_CASE}}` syntax. The template is split on `|` into segments;
|
||||
a segment whose only value is the unlimited marker `∞` (for `TRAFFIC_LEFT`,
|
||||
`TRAFFIC_TOTAL`, `DAYS_LEFT`, or `TIME_LEFT`) is dropped, so unlimited clients
|
||||
don't show empty decorations.
|
||||
|
||||
### Available tokens
|
||||
|
||||
| Token | Value |
|
||||
| ----- | ----- |
|
||||
| `{{EMAIL}}` / `{{USERNAME}}` | Client email (identifier) |
|
||||
| `{{INBOUND}}` | Inbound remark |
|
||||
| `{{HOST}}` | Host-row remark (managed hosts) |
|
||||
| `{{ID}}` / `{{SHORT_ID}}` | Client UUID / its first 8 chars |
|
||||
| `{{TELEGRAM_ID}}` · `{{SUB_ID}}` · `{{COMMENT}}` | Telegram ID, subscription ID, comment |
|
||||
| `{{STATUS}}` / `{{STATUS_EMOJI}}` | `active`/`expired`/`depleted`/`disabled` (or ✅⏳🚫) |
|
||||
| `{{DAYS_LEFT}}` / `{{TIME_LEFT}}` | Days, or `Xd Xh Xm`, remaining (`∞` if unlimited) |
|
||||
| `{{EXPIRE_DATE}}` / `{{JALALI_EXPIRE_DATE}}` / `{{EXPIRE_UNIX}}` | Expiry as Gregorian / Jalali date / Unix seconds |
|
||||
| `{{CREATED_UNIX}}` | Creation time (Unix seconds) |
|
||||
| `{{TRAFFIC_USED}}` / `{{TRAFFIC_LEFT}}` / `{{TRAFFIC_TOTAL}}` | Human-readable usage (`∞` if unlimited) |
|
||||
| `{{TRAFFIC_USED_BYTES}}` / `{{TRAFFIC_LEFT_BYTES}}` / `{{TRAFFIC_TOTAL_BYTES}}` | Same, in bytes |
|
||||
| `{{UP}}` / `{{DOWN}}` | Upload / download (human-readable) |
|
||||
| `{{RESET_DAYS}}` · `{{USAGE_PERCENTAGE}}` | Reset period (days) · used percent |
|
||||
| `{{PROTOCOL}}` / `{{TRANSPORT}}` / `{{SECURITY}}` | e.g. `VLESS` / `ws` / `REALITY` |
|
||||
|
||||
<Callout type="info">
|
||||
Usage tokens (traffic, days, status) appear in the subscription **body** but
|
||||
are stripped from the display/QR view, so a shared QR doesn't leak a client's
|
||||
remaining quota. Date tokens follow the `datepicker` setting (Gregorian or
|
||||
Jalali).
|
||||
</Callout>
|
||||
|
||||
## Related
|
||||
|
||||
<Cards>
|
||||
<Card title="REALITY" href="/docs/config/reality" description="Generate a VLESS + REALITY config and link." />
|
||||
<Card title="Subscription" href="/docs/config/subscription" description="Serve all of a client's links from one URL." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
title: SSL Certificates
|
||||
description: Get and renew TLS certificates for the 3x-ui panel and inbounds — with the x-ui ACME menu (domain or bare IP), a Cloudflare DNS-01 wildcard, or manual Certbot.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
A TLS certificate lets you serve the **panel** over HTTPS (so your login and API
|
||||
traffic are encrypted) and terminate TLS on **inbounds** (VLESS-TLS, Trojan,
|
||||
Shadowsocks-TLS, and friends). There are three ways to obtain one:
|
||||
|
||||
- **The `x-ui` menu** — built-in [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment)
|
||||
client. Easiest for a single domain or a bare IP.
|
||||
- **Cloudflare DNS-01** — also from the menu; needed for **wildcard** certs or
|
||||
when port 80 is blocked / the server sits behind Cloudflare's proxy.
|
||||
- **Manual Certbot** — if you'd rather manage `acme.sh`/Certbot yourself.
|
||||
|
||||
<Callout type="info">
|
||||
If you put the panel behind Nginx or Caddy, let the proxy handle the
|
||||
certificate instead — see [Reverse proxy](/docs/operations/reverse-proxy).
|
||||
[REALITY](/docs/config/reality) inbounds need **no** certificate at all; they
|
||||
borrow a real site's TLS. This page is for the panel and for classic TLS
|
||||
inbounds.
|
||||
</Callout>
|
||||
|
||||
## The `x-ui` SSL menu (Let's Encrypt)
|
||||
|
||||
Run `x-ui` and choose **`20` — SSL Certificate Management**. It drives
|
||||
[acme.sh](https://github.com/acmesh-official/acme.sh) and offers:
|
||||
|
||||
| Option | What it does |
|
||||
| ------------------------------ | ------------------------------------------------------------------- |
|
||||
| Get SSL (Domain) | Issue a certificate for a domain via HTTP validation. |
|
||||
| Get SSL for IP Address | Issue a short-lived (6-day, auto-renewing) cert for a **bare IP**. |
|
||||
| Revoke | Revoke an existing certificate. |
|
||||
| Force Renew | Renew now, before expiry. |
|
||||
| Show Existing Domains | List certificates already on the server. |
|
||||
| Set Cert paths for the panel | Point the panel's TLS at an issued cert (sets the fields for you). |
|
||||
|
||||
### Issue a certificate for a domain
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Point the domain at the server
|
||||
|
||||
Create an `A` (and/or `AAAA`) record for your domain that resolves to this
|
||||
server's public IP. Validation fails until DNS has propagated.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Free up port 80
|
||||
|
||||
HTTP validation needs **port 80** reachable from the internet and not already in
|
||||
use. Stop anything bound to it for the duration, and allow it through the
|
||||
[firewall](/docs/reference/ports-firewall).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Run the issuer
|
||||
|
||||
`x-ui` → `20` → **Get SSL (Domain)**, then enter the domain. acme.sh requests
|
||||
the certificate and saves it under `/root/cert/<domain>/` as `fullchain.pem`
|
||||
(the certificate chain) and `privkey.pem` (the private key).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Wire it into the panel
|
||||
|
||||
Choose **Set Cert paths for the panel** to fill in `webCertFile` and
|
||||
`webKeyFile` and restart the panel, or set them yourself in
|
||||
[Panel Settings](/docs/config/panel#tls). The panel serves HTTPS as soon as both
|
||||
are set.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
### Issue a certificate for a bare IP
|
||||
|
||||
No domain? Choose **Get SSL for IP Address** to obtain a short-lived
|
||||
certificate (valid ~6 days, renewed automatically) bound to the server's IP.
|
||||
Useful for reaching the panel over HTTPS before you've set up a domain.
|
||||
|
||||
## Cloudflare (DNS-01 wildcard)
|
||||
|
||||
DNS validation proves you control the domain by creating a TXT record instead of
|
||||
answering on port 80 — so it works **behind Cloudflare's proxy**, on servers
|
||||
where port 80 is blocked, and for **wildcard** certificates (`*.example.com`).
|
||||
|
||||
Your domain's DNS must be managed by Cloudflare, and you need one of:
|
||||
|
||||
- a **scoped API token** with the `Zone:DNS:Edit` permission (recommended), or
|
||||
- your account **email + Global API Key**.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Create a scoped API token
|
||||
|
||||
In the Cloudflare dashboard go to **My Profile → API Tokens →
|
||||
[Create Token](https://dash.cloudflare.com/profile/api-tokens)**, pick the
|
||||
**Edit zone DNS** template, scope it to the zone you're issuing for, and create
|
||||
it. Copy the token — it's shown only once.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Run the Cloudflare issuer
|
||||
|
||||
`x-ui` → **`21` — Cloudflare SSL Certificate**. When asked, choose **`t`** for an
|
||||
API token (the default) or **`g`** for the Global API Key, then enter your
|
||||
domain (and, for the Global API Key, your account email and key). acme.sh creates
|
||||
the TXT record, validates, and cleans it up.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Point the panel at it
|
||||
|
||||
As with the domain flow, use **Set Cert paths for the panel** (menu `20`) or set
|
||||
`webCertFile` / `webKeyFile` in [Panel Settings](/docs/config/panel#tls).
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Prefer a scoped token over the Global API Key — it only grants DNS edits on the
|
||||
zone you choose, so a leak can't touch the rest of your Cloudflare account.
|
||||
</Callout>
|
||||
|
||||
## Manual (Certbot)
|
||||
|
||||
If you'd rather not use the menu, issue a certificate with Certbot's standalone
|
||||
plugin (again, this needs port 80 free and the domain resolving to the server):
|
||||
|
||||
```bash
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
Certbot writes the certificate to `/etc/letsencrypt/live/yourdomain.com/`
|
||||
(`fullchain.pem` and `privkey.pem`). Point the panel at those two files in
|
||||
[Panel Settings](/docs/config/panel#tls), and set up renewal — `certbot renew`
|
||||
runs on a systemd timer by default.
|
||||
|
||||
## Using the certificate
|
||||
|
||||
- **Panel** — set `webCertFile` (the full chain) and `webKeyFile` (the private
|
||||
key) in [Panel Settings](/docs/config/panel#tls). Both must be set for the
|
||||
panel to switch to HTTPS. Menu option **`11` — View Current Settings** prints
|
||||
the paths currently in use.
|
||||
- **Inbounds** — when you enable TLS on an inbound, reference the same
|
||||
certificate and key files (or paste their contents) in the inbound's TLS
|
||||
settings. See [Inbounds](/docs/config/inbounds) and
|
||||
[Transports](/docs/config/transports).
|
||||
|
||||
<Callout type="warn">
|
||||
Certificates expire (Let's Encrypt: 90 days; IP certs: ~6 days). The menu and
|
||||
Certbot both renew automatically, but the panel keeps reading the **files** at
|
||||
their fixed paths — so renew **in place** rather than moving the files, and the
|
||||
panel picks up the new cert on its next restart. **Force Renew** (menu `20`)
|
||||
triggers a renewal on demand.
|
||||
</Callout>
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="Panel Settings"
|
||||
href="/docs/config/panel#tls"
|
||||
description="webCertFile / webKeyFile and the rest of the web-server settings."
|
||||
/>
|
||||
<Card
|
||||
title="Reverse proxy"
|
||||
href="/docs/operations/reverse-proxy"
|
||||
description="Let Nginx or Caddy terminate TLS for you instead."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="Stealth TLS for inbounds — no certificate required."
|
||||
/>
|
||||
</Cards>
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
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` | `/sub/` | 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/<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** | `/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. |
|
||||
|
||||
Only enabled inbounds using **VLESS, VMess, Trojan, Shadowsocks, or Hysteria2**
|
||||
appear in a subscription, ordered by their sub-sort index. Requesting `/sub/`
|
||||
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 mixed/HTTP inbounds, 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>
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
title: Transports & Security
|
||||
description: Every transport 3x-ui exposes — TCP, mKCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, Hysteria — with their settings, plus FinalMask obfuscation, sockopt, TLS/REALITY, XTLS-Vision, and VLESS encryption.
|
||||
icon: Network
|
||||
---
|
||||
|
||||
A **transport** decides how packets are carried between client and server, a
|
||||
**security** layer decides how they're encrypted and disguised, and **FinalMask**
|
||||
can obfuscate what's left. The panel only offers valid combinations; this page
|
||||
lists every transport's settings and the rules the panel enforces.
|
||||
|
||||
## Transports
|
||||
|
||||
Pick the transport (the inbound's `network`) in the inbound/outbound form. Each
|
||||
network writes its own settings key on the wire (`tcpSettings`, `kcpSettings`, …).
|
||||
|
||||
| Transport | Settings key | When to use it |
|
||||
| --------------- | --------------------- | ---------------------------------------------------------------------- |
|
||||
| **TCP (Raw)** | `tcpSettings` | Lowest overhead. The basis for REALITY + XTLS-Vision and fallbacks; optional HTTP/1.1 header camouflage. |
|
||||
| **mKCP** | `kcpSettings` | Reliable protocol over **UDP** — trades bandwidth for lower latency on lossy links. Carries no TLS/REALITY. |
|
||||
| **WebSocket** | `wsSettings` | Works through CDNs and HTTP reverse proxies; very compatible. |
|
||||
| **gRPC** | `grpcSettings` | HTTP/2-based; multiplexes well and proxies cleanly through Nginx. |
|
||||
| **HTTPUpgrade** | `httpupgradeSettings` | CDN-friendly HTTP/1.1 `Upgrade`; lighter than full WebSocket. |
|
||||
| **XHTTP** | `xhttpSettings` | Modern stream-multiplexed HTTP transport; CDN-friendly and REALITY-capable. |
|
||||
| **Hysteria** | `hysteriaSettings` | QUIC-based transport — only for the **Hysteria2** protocol. |
|
||||
|
||||
<Callout type="info">
|
||||
**WireGuard** and **Tunnel** (dokodemo-door) inbounds expose no transport
|
||||
selector — their stream carries only security/sockopt. Earlier panels also
|
||||
exposed a raw **HTTP/2 (`http`)** transport; it has been superseded by **XHTTP**
|
||||
and is no longer selectable.
|
||||
</Callout>
|
||||
|
||||
### TCP (Raw) — `tcpSettings`
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ------------------------------ | ------- | ----------------------------------------------------------------------- |
|
||||
| `acceptProxyProtocol` | `false` | Accept the PROXY protocol from an upstream proxy so the real client IP is preserved. |
|
||||
| `header.type` | `none` | `none`, or `http` for HTTP/1.1 camouflage. |
|
||||
| `header.request` / `response` | — | When `type: http`: method, path, version and a header map that mimic a normal HTTP exchange. |
|
||||
|
||||
### mKCP — `kcpSettings`
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ------------------ | ----------- | ---------------------------------------------------------------- |
|
||||
| `mtu` | `1350` | Maximum transmission unit, in bytes (576–1460). |
|
||||
| `tti` | `20` | Transmission time interval, in ms (10–100). Lower = more responsive, more overhead. |
|
||||
| `uplinkCapacity` | `5` | Upload bandwidth budget, in **MB/s**. |
|
||||
| `downlinkCapacity` | `20` | Download bandwidth budget, in **MB/s**. |
|
||||
| `cwndMultiplier` | `1` | Congestion-window multiplier; raise to push harder on good links. |
|
||||
| `maxSendingWindow` | `2097152` | Upper bound on in-flight packets. |
|
||||
|
||||
<Callout type="info">
|
||||
mKCP can't carry TLS or REALITY. To disguise it, add a **FinalMask** UDP mask —
|
||||
the `mkcp-legacy` mask reproduces the classic header obfuscation that older Xray
|
||||
stored in `kcpSettings.header`/`seed` (those fields no longer exist here).
|
||||
</Callout>
|
||||
|
||||
### WebSocket — `wsSettings`
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --------------------- | ------- | ---------------------------------------------------------------- |
|
||||
| `path` | `/` | Request path — route on it when several services share one host. |
|
||||
| `host` | _(none)_| `Host` header override (useful behind a CDN). |
|
||||
| `headers` | `{}` | Extra request headers. |
|
||||
| `heartbeatPeriod` | `0` | Seconds between keepalive pings; `0` disables them. |
|
||||
| `acceptProxyProtocol` | `false` | Accept the PROXY protocol from an upstream. |
|
||||
|
||||
### gRPC — `grpcSettings`
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ------------- | ------- | --------------------------------------------------------- |
|
||||
| `serviceName` | _(none)_| gRPC service path; acts like a secret route. |
|
||||
| `authority` | _(none)_| `:authority` pseudo-header override. |
|
||||
| `multiMode` | `false` | Multiplex several streams over one connection. |
|
||||
|
||||
### HTTPUpgrade — `httpupgradeSettings`
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --------------------- | ------- | --------------------------------------------- |
|
||||
| `path` | `/` | Request path. |
|
||||
| `host` | _(none)_| `Host` header override. |
|
||||
| `headers` | `{}` | Extra request headers. |
|
||||
| `acceptProxyProtocol` | `false` | Accept the PROXY protocol from an upstream. |
|
||||
|
||||
HTTPUpgrade is a one-shot HTTP/1.1 `Upgrade` with no WebSocket framing — there's
|
||||
no heartbeat field.
|
||||
|
||||
### XHTTP — `xhttpSettings`
|
||||
|
||||
XHTTP (SplitHTTP) has a large field set; the panel fills sensible defaults. The
|
||||
ones you'll usually touch:
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ---------------------- | ----------- | ---------------------------------------------------------------------- |
|
||||
| `path` | `/` | Request path. |
|
||||
| `host` | _(none)_ | `Host` header override. |
|
||||
| `mode` | `auto` | `auto`, `packet-up`, `stream-up`, or `stream-one`. `packet-up` is the most CDN-compatible; `stream-*` are lower latency. |
|
||||
| `xPaddingBytes` | `100-1000` | Random padding range that blurs packet sizes. |
|
||||
| `scMaxBufferedPosts` | `30` | Server-side buffer for uploaded POSTs. |
|
||||
| `scStreamUpServerSecs` | `20-80` | Stream-up server window (dash range). |
|
||||
| `xmux` (`enableXmux`) | _(off)_ | Connection multiplexing — `maxConcurrency` `16-32`, `maxConnections` `6`, … Turn on for high concurrency. |
|
||||
|
||||
Session-ID fields (`sessionIDPlacement`, `sessionIDKey`, `sessionIDTable`,
|
||||
`sessionIDLength`) and the `scMin/MaxEachPostBytes` knobs are advanced; leave them
|
||||
empty unless you're matching a specific upstream.
|
||||
|
||||
### Hysteria — `hysteriaSettings`
|
||||
|
||||
Only valid when the protocol is **Hysteria2**.
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ---------------- | ------- | ----------------------------------------------------------------------- |
|
||||
| `version` | `2` | Hysteria protocol version. |
|
||||
| `auth` | _(none)_| Shared authentication string. |
|
||||
| `udpIdleTimeout` | `60` | Seconds (2–600) before idle UDP sessions are dropped. |
|
||||
| `masquerade` | — | Disguise as an HTTP/3 server: `type` `proxy`/`file`/`string` with `url`/`dir`/`content`, plus `headers` and `statusCode`. |
|
||||
|
||||
## FinalMask — late-layer obfuscation
|
||||
|
||||
**FinalMask** wraps traffic **after** the transport and security layers, so it can
|
||||
disguise transports that don't carry TLS (like mKCP) or add a second skin on top of
|
||||
TLS. Masks are configured per direction:
|
||||
|
||||
- **TCP masks** — `fragment`, `sudoku`, `header-custom`.
|
||||
- **UDP masks** — `salamander`, `mkcp-legacy`, `header-custom`, `xdns`, `xicmp`,
|
||||
`noise`, `sudoku`, `realm`. (`mkcp-legacy` reproduces the old mKCP header
|
||||
obfuscation.)
|
||||
- **QUIC params** — congestion control (`reno`, `bbr`, `brutal`, `force-brutal`),
|
||||
Brutal up/down rates, `udpHop` (rotate the QUIC port across a range to dodge
|
||||
port blocking), and receive-window tuning.
|
||||
|
||||
FinalMask replaces the per-transport `header`/`seed` obfuscation that older Xray
|
||||
builds exposed.
|
||||
|
||||
## sockopt — low-level socket options
|
||||
|
||||
`sockopt` rides alongside any transport and tunes the underlying socket. The most
|
||||
useful fields:
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --------------------- | ------- | ---------------------------------------------------------------- |
|
||||
| `tcpFastOpen` | `false` | Enable TCP Fast Open. |
|
||||
| `tcpcongestion` | `bbr` | Congestion control: `bbr`, `cubic`, or `reno`. |
|
||||
| `tproxy` | `off` | Transparent proxy mode: `off`, `redirect`, or `tproxy`. |
|
||||
| `domainStrategy` | `AsIs` | How addresses resolve (`UseIP`, `ForceIPv4`, …). |
|
||||
| `dialerProxy` | _(none)_| Chain this outbound's dialing through another outbound tag. |
|
||||
| `interface` | _(none)_| Bind to a specific network interface. |
|
||||
| `mark` | `0` | SO_MARK for policy routing (`0` = unset). |
|
||||
|
||||
Numeric fields left at `0` are omitted on the wire so Xray keeps OS defaults.
|
||||
Advanced entries (`happyEyeballs`, `customSockopt[]`, keepalive timers) are
|
||||
available for special cases.
|
||||
|
||||
## Security
|
||||
|
||||
The security layer is one of **`none`**, **`tls`**, or **`reality`**, with these
|
||||
eligibility rules:
|
||||
|
||||
| Security | Eligible transports | Eligible protocols |
|
||||
| ----------- | -------------------------------------------- | --------------------------------------------------- |
|
||||
| **TLS** | `tcp`, `ws`, `grpc`, `httpupgrade`, `xhttp` | VLESS, VMess, Trojan, Shadowsocks (Hysteria2 is always TLS) |
|
||||
| **REALITY** | `tcp`, `grpc`, `xhttp` | VLESS, Trojan |
|
||||
|
||||
mKCP and Hysteria don't take a separate TLS/REALITY layer — mKCP runs plaintext
|
||||
(obfuscate with FinalMask), and Hysteria is QUIC/TLS by design. REALITY disguises
|
||||
your server as a real TLS site and needs no certificate — see
|
||||
[REALITY](/docs/config/reality).
|
||||
|
||||
## XTLS-Vision flow
|
||||
|
||||
The `xtls-rprx-vision` flow is fast and DPI-resistant. It's available for
|
||||
**VLESS** when either:
|
||||
|
||||
- the transport is raw **TCP** with **TLS** or **REALITY** security (classic
|
||||
XTLS-Vision), or
|
||||
- the transport is **XHTTP** with VLESS encryption enabled (see below).
|
||||
|
||||
Set the flow on the VLESS **client**, not the inbound. With classic Vision on
|
||||
TCP, the panel can also offer a **Vision seed** once a client uses the flow.
|
||||
|
||||
## VLESS encryption (ML-KEM)
|
||||
|
||||
VLESS supports post-quantum **encryption** (ML-KEM / `mlkem768x25519`), stored in
|
||||
the inbound's `decryption` (server) and clients' `encryption` (for link
|
||||
generation). When enabled, it unlocks the Vision flow over XHTTP. Generate the
|
||||
keys from the panel's VLESS settings.
|
||||
|
||||
## Shadowsocks ciphers
|
||||
|
||||
Shadowsocks inbounds support both classic ciphers and **Shadowsocks-2022**
|
||||
(method names starting with `2022-blake3-`). Most ciphers are multi-user;
|
||||
`2022-blake3-chacha20-poly1305` is single-user.
|
||||
|
||||
<Callout type="info">
|
||||
Transports and security must match on both ends. The client's share link
|
||||
encodes them (`type=ws`, `security=reality`, `flow=xtls-rprx-vision`, …) —
|
||||
decode any link with the [share-link inspector](/docs/config/share-links).
|
||||
</Callout>
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: First Login
|
||||
description: Find your generated 3x-ui credentials, reach the panel, enable two-factor auth, and harden it before exposing anything.
|
||||
icon: KeyRound
|
||||
---
|
||||
|
||||
After installation, your first job is to log in and **secure the panel** before
|
||||
exposing anything else.
|
||||
|
||||
## Reach the panel
|
||||
|
||||
The panel is served at:
|
||||
|
||||
```text
|
||||
http://<your-server-ip>:<port>/<web-base-path>
|
||||
```
|
||||
|
||||
The default port is **2053** and the default base path is `/` — but a script
|
||||
install **randomly generates** the username, password, **port**, and web base
|
||||
path, so check your actual values.
|
||||
|
||||
### Find your credentials
|
||||
|
||||
A script install prints a credential summary when it finishes and also writes it
|
||||
to a root-only file:
|
||||
|
||||
```bash title="/etc/x-ui/install-result.env (mode 600)"
|
||||
XUI_USERNAME=...
|
||||
XUI_PASSWORD=...
|
||||
XUI_PANEL_PORT=...
|
||||
XUI_WEB_BASE_PATH=...
|
||||
XUI_ACCESS_URL=...
|
||||
XUI_API_TOKEN=...
|
||||
XUI_DB_TYPE=sqlite
|
||||
```
|
||||
|
||||
If you missed them, use the management tools:
|
||||
|
||||
```bash
|
||||
x-ui # menu → 11 (View Current Settings)
|
||||
x-ui settings # or the one-shot form
|
||||
```
|
||||
|
||||
For **Docker**, read the generated credentials from the container logs, or run
|
||||
`docker exec -it <container> x-ui setting -show`.
|
||||
|
||||
<Callout type="warn">
|
||||
If your panel still uses the default `admin` / `admin` (the panel warns when it
|
||||
does), change it immediately — before creating any inbounds.
|
||||
</Callout>
|
||||
|
||||
## Change credentials, port, and path
|
||||
|
||||
A non-default port and a long, random **web base path** make the panel much
|
||||
harder to find. Change them from **Panel Settings** in the UI, or from the
|
||||
`x-ui` menu:
|
||||
|
||||
- **7 — Reset Username & Password** (optionally disabling 2FA at the same time)
|
||||
- **8 — Reset Web Base Path** (randomizes it)
|
||||
- **10 — Change Port**
|
||||
|
||||
Changing your username or password **logs out all existing sessions** and, if
|
||||
two-factor auth was on, disables it.
|
||||
|
||||
## Two-factor authentication (2FA)
|
||||
|
||||
3x-ui supports TOTP two-factor auth (compatible with Google Authenticator, Aegis,
|
||||
etc.). Enable it in **Panel Settings** — once enabled, the login page asks for a
|
||||
6-digit code in addition to your password, and turning it on forces everyone to
|
||||
log in again. You can disable it from the menu's **Reset Username & Password**
|
||||
step or with `x-ui setting -resetTwoFactor`.
|
||||
|
||||
## Built-in login protection
|
||||
|
||||
- **Brute-force limiter:** after **5** failed logins from the same IP/username
|
||||
within 5 minutes, that combination is blocked for **15 minutes**.
|
||||
- **Generic errors:** the login page reports "wrong username or password" for
|
||||
both bad credentials and bad 2FA codes, so it leaks nothing.
|
||||
- **Sessions** last `sessionMaxAge` minutes (default **360** = 6 hours) and are
|
||||
invalidated when you change credentials.
|
||||
- **LDAP** can be enabled as an auth fallback in Panel Settings.
|
||||
|
||||
## Essential hardening checklist
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Set strong, unique credentials
|
||||
|
||||
Replace the generated (or `admin/admin`) username and password with strong values.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Use a non-default port and random base path
|
||||
|
||||
Move the panel off `2053` and serve it under a long random path.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Enable two-factor authentication
|
||||
|
||||
Turn on 2FA so a leaked password alone can't grant access.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Put the panel behind TLS
|
||||
|
||||
Use a valid certificate (via the `x-ui` menu's SSL management, or a reverse
|
||||
proxy) so the panel is only reachable over HTTPS.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Restrict access with a firewall
|
||||
|
||||
Open only the ports you actually need, and consider limiting panel access by IP.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Want the panel on a clean domain with automatic HTTPS? See
|
||||
[Reverse proxy](/docs/operations/reverse-proxy). For deeper hardening, see
|
||||
[Security](/docs/operations/security).
|
||||
</Callout>
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Meet 3x-ui
|
||||
description: A web panel for Xray-core — manage inbounds, protocols, clients, and subscriptions from your browser instead of editing JSON by hand.
|
||||
icon: Info
|
||||
---
|
||||
|
||||
**3x-ui** is a web control panel that sits on top of
|
||||
[Xray-core](https://github.com/XTLS/Xray-core), the proxy engine that actually
|
||||
moves your traffic. Instead of writing and reloading Xray's JSON configuration
|
||||
by hand, you manage everything — inbounds, protocols, clients, certificates,
|
||||
subscriptions — from a browser dashboard.
|
||||
|
||||
## How the pieces fit together
|
||||
|
||||
<Mermaid
|
||||
chart={`
|
||||
flowchart LR
|
||||
Admin["Admin browser"] -->|HTTPS panel| Panel["3x-ui panel"]
|
||||
Panel -->|writes config, reloads| Xray["Xray-core"]
|
||||
Panel --- DB[("SQLite or PostgreSQL")]
|
||||
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
||||
Xray -->|proxied traffic| Internet["Internet"]
|
||||
`}
|
||||
/>
|
||||
|
||||
- **The panel** is the management layer: it stores your configuration in a
|
||||
database, renders the dashboard, exposes a REST API, and writes the live Xray
|
||||
configuration.
|
||||
- **Xray-core** is the data plane: it terminates client connections on your
|
||||
**inbounds** and forwards traffic to its destination.
|
||||
- **Client apps** (such as v2rayNG, Clash/Mihomo, Hiddify, and others) connect
|
||||
using a share link or a subscription that the panel generates for each client.
|
||||
|
||||
## What it gives you
|
||||
|
||||
- A dashboard for **inbounds** across every major protocol — VLESS, VMess,
|
||||
Trojan, Shadowsocks, WireGuard, Hysteria2, SOCKS, HTTP, and Dokodemo-door.
|
||||
- First-class **REALITY** and **XTLS-Vision** support for stealthy, fast
|
||||
transports.
|
||||
- **Per-client** traffic quotas, expiry dates, IP limits, online status, and
|
||||
one-click share links / QR codes.
|
||||
- **Subscriptions** in VLESS, Clash/Mihomo, and JSON formats.
|
||||
- Operational tooling: **multi-node** management, a **Telegram bot**, backups,
|
||||
Fail2ban-based IP limiting, and a documented REST API.
|
||||
|
||||
## Under the hood
|
||||
|
||||
| Layer | Technology |
|
||||
| ------------ | -------------------------------------------- |
|
||||
| Backend | Go with the Gin web framework |
|
||||
| Frontend | TypeScript / React |
|
||||
| Database | SQLite (default) or PostgreSQL |
|
||||
| Proxy engine | Xray-core (bundled and managed by the panel) |
|
||||
|
||||
The default SQLite database lives at `/etc/x-ui/x-ui.db`, and the panel listens
|
||||
on port **2053** by default. Both are configurable — see
|
||||
[First login](/docs/guide/first-login) and the environment variable reference.
|
||||
|
||||
## Who it's for
|
||||
|
||||
3x-ui is aimed at anyone running their own Xray server: from a single personal
|
||||
VPS to operators managing many nodes and clients. If you want the power of
|
||||
Xray-core without living in JSON config files, this is for you.
|
||||
|
||||
<Callout type="info">
|
||||
3x-ui is an enhanced fork of the original X-UI project, adding broader protocol
|
||||
support, improved stability, per-client traffic accounting, multi-node
|
||||
management, and many quality-of-life features.
|
||||
</Callout>
|
||||
|
||||
Ready to install? Continue to [Installation](/docs/guide/installation).
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: Installation
|
||||
description: Install 3x-ui via the official script (stable, pinned, or dev-latest), unattended/cloud-init, or Docker — and choose SQLite or PostgreSQL.
|
||||
icon: Download
|
||||
---
|
||||
|
||||
3x-ui runs on a wide range of Linux distributions — Ubuntu, Debian, Armbian,
|
||||
Fedora, CentOS, RHEL, AlmaLinux, Rocky Linux, Oracle Linux, Amazon Linux,
|
||||
Virtuozzo, Arch, Manjaro, openSUSE (Tumbleweed/Leap), Alpine — and Windows,
|
||||
across `amd64`, `386`, `arm64`, `armv7`, `armv6`, `armv5`, and `s390x`.
|
||||
|
||||
<Callout type="warn">
|
||||
Run the script installer as **root** (or with `sudo`). It installs a service,
|
||||
sets up the `x-ui` management command, and enables the panel on boot.
|
||||
</Callout>
|
||||
|
||||
<Tabs items={['Script', 'Docker', 'Manual']}>
|
||||
|
||||
<Tab value="Script">
|
||||
|
||||
The official script is the recommended path. During installation it generates a
|
||||
**random** username, password, and access (web base) path, sets up the service,
|
||||
and installs the `x-ui` management command.
|
||||
|
||||
```bash title="latest stable"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
Install a **specific version** by appending its tag:
|
||||
|
||||
```bash title="pinned version"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
||||
```
|
||||
|
||||
Install the rolling **dev** build (the latest per-commit pre-release from `main`
|
||||
— not a stable release) by passing `dev-latest`:
|
||||
|
||||
```bash title="rolling dev build"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
||||
```
|
||||
|
||||
When it finishes, note the printed login details and run `x-ui` to open the
|
||||
[management menu](/docs/guide/update-uninstall#the-x-ui-management-menu), then
|
||||
continue to [First login](/docs/guide/first-login).
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab value="Docker">
|
||||
|
||||
The default Compose setup uses SQLite. Clone the repo (or copy its
|
||||
`docker-compose.yml` and `Dockerfile`) and start it:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
To run with the bundled **PostgreSQL** service, uncomment the two `XUI_DB_*`
|
||||
lines in `docker-compose.yml` and start with the profile:
|
||||
|
||||
```bash
|
||||
docker compose --profile postgres up -d
|
||||
```
|
||||
|
||||
Prefer the prebuilt image? It's published to the GitHub Container Registry. The
|
||||
image bundles Fail2ban (for [IP limits](/docs/operations/security)), which bans
|
||||
with `iptables` and therefore needs `NET_ADMIN` (and `NET_RAW` for IPv6) —
|
||||
otherwise bans are logged but never applied:
|
||||
|
||||
```bash title="docker run"
|
||||
docker run -d \
|
||||
--cap-add=NET_ADMIN \
|
||||
--cap-add=NET_RAW \
|
||||
-e XUI_ENABLE_FAIL2BAN=true \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/mhsanaei/3x-ui:latest
|
||||
```
|
||||
|
||||
The `db/` volume holds the SQLite database (`/etc/x-ui/x-ui.db`) and `cert/`
|
||||
holds TLS certificates, so your data survives upgrades.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab value="Manual">
|
||||
|
||||
For advanced users, download a release archive for your architecture from the
|
||||
[releases page](https://github.com/MHSanaei/3x-ui/releases), extract it, and run
|
||||
the binary as a systemd service. The install script automates exactly these
|
||||
steps, so it's preferred unless you have a specific reason to install by hand.
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## Build your install command
|
||||
|
||||
Tailor the command to your setup:
|
||||
|
||||
<InstallCommandBuilder />
|
||||
|
||||
## Choose a database
|
||||
|
||||
You pick the storage backend at install time:
|
||||
|
||||
- **SQLite** (default) — a single file at `/etc/x-ui/x-ui.db`. Zero setup.
|
||||
- **PostgreSQL** — for high client counts or multi-node setups. The installer
|
||||
can install it locally or use a DSN you provide.
|
||||
|
||||
See [Database](/docs/reference/database) for details and SQLite→PostgreSQL
|
||||
migration.
|
||||
|
||||
## Unattended / cloud-init
|
||||
|
||||
The installer also runs **non-interactively** for automation. Set
|
||||
`XUI_NONINTERACTIVE=1` (or run with no TTY) and it installs end-to-end with zero
|
||||
prompts, generating random credentials and writing them to
|
||||
`/etc/x-ui/install-result.env`:
|
||||
|
||||
```bash
|
||||
XUI_NONINTERACTIVE=1 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
The repo's [`deploy/`](https://github.com/MHSanaei/3x-ui/tree/main/deploy)
|
||||
directory has ready-made **cloud-init** user-data for unattended installs on any
|
||||
cloud (Hetzner, AWS, DigitalOcean, Vultr, GCP, Azure, Oracle).
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="First login"
|
||||
href="/docs/guide/first-login"
|
||||
description="Reach the panel and secure it."
|
||||
/>
|
||||
<Card
|
||||
title="Update & uninstall"
|
||||
href="/docs/guide/update-uninstall"
|
||||
description="The x-ui menu, updates, and removal."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="Configure your first stealthy inbound."
|
||||
/>
|
||||
</Cards>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Getting Started",
|
||||
"icon": "Rocket",
|
||||
"pages": ["index", "installation", "first-login", "update-uninstall"]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Update & Uninstall
|
||||
description: Manage 3x-ui with the x-ui menu and CLI — update (stable, dev, or legacy), change settings, and uninstall cleanly.
|
||||
icon: RefreshCw
|
||||
---
|
||||
|
||||
After a script install, the `x-ui` command is your control center. Run it with
|
||||
no arguments for the interactive menu, or pass a subcommand for a one-shot action.
|
||||
|
||||
```bash
|
||||
x-ui
|
||||
```
|
||||
|
||||
## The `x-ui` management menu
|
||||
|
||||
The menu (items `0`–`28`) shows the panel/Xray status at the top, then:
|
||||
|
||||
| # | Item | What it does |
|
||||
| ----- | -------------------------------------- | --------------------------------------------------------- |
|
||||
| 1 | Install | (Re)install from the remote script |
|
||||
| 2 | Update | Update to the latest **stable** release |
|
||||
| 3 | Update to Dev Channel (latest commit) | Update to the rolling `dev-latest` build |
|
||||
| 4 | Update Menu | Update just the `x-ui` menu script |
|
||||
| 5 | Legacy Version | Install a specific older version (prompts for a tag) |
|
||||
| 6 | Uninstall | Remove 3x-ui (see below) |
|
||||
| 7 | Reset Username & Password | Set new credentials; optionally disable 2FA |
|
||||
| 8 | Reset Web Base Path | Randomize the web base path |
|
||||
| 9 | Reset Settings | Reset panel settings (your account is preserved) |
|
||||
| 10 | Change Port | Change the panel port |
|
||||
| 11 | View Current Settings | Show username, port, web base path, cert paths |
|
||||
| 12–14 | Start / Stop / Restart | Control the panel service |
|
||||
| 15 | Restart Xray | Reload only Xray-core |
|
||||
| 16 | Check Status | Service status |
|
||||
| 17 | Logs Management | View debug logs / clear logs |
|
||||
| 18–19 | Enable / Disable Autostart | Toggle start-on-boot |
|
||||
| 20 | SSL Certificate Management | Let's Encrypt (domain or IP), custom paths, renew/revoke |
|
||||
| 21 | Cloudflare SSL Certificate | DNS-01 wildcard cert via Cloudflare |
|
||||
| 22 | IP Limit Management | Fail2ban-based per-client IP limits |
|
||||
| 23 | Firewall Management | `ufw` install and port rules |
|
||||
| 24 | SSH Port Forwarding Management | Bind the panel to localhost and tunnel over SSH |
|
||||
| 25 | PostgreSQL Management | Install/migrate/manage PostgreSQL |
|
||||
| 26 | Enable BBR | Toggle the BBR congestion-control sysctl |
|
||||
| 27 | Update Geo Files | Update geoip/geosite data (Loyalsoldier, IR, RU) |
|
||||
| 28 | Speedtest by Ookla | Run an Ookla speed test |
|
||||
| 0 | Exit | — |
|
||||
|
||||
Some of these have their own pages: [SSL certificates](/docs/config/ssl-certificates)
|
||||
(items 20–21), [Security](/docs/operations/security) (IP limits, firewall),
|
||||
[Reverse proxy](/docs/operations/reverse-proxy) and [Panel settings](/docs/config/panel)
|
||||
(TLS), and [Database](/docs/reference/database) (PostgreSQL).
|
||||
|
||||
## CLI subcommands
|
||||
|
||||
For scripts and quick actions, `x-ui` also takes a subcommand directly:
|
||||
|
||||
| Command | Action |
|
||||
| -------------------------- | --------------------------------------------------- |
|
||||
| `x-ui start` / `stop` / `restart` | Control the service |
|
||||
| `x-ui restart-xray` | Reload only Xray-core |
|
||||
| `x-ui status` | Show status |
|
||||
| `x-ui settings` | Show current settings |
|
||||
| `x-ui enable` / `disable` | Toggle autostart on boot |
|
||||
| `x-ui log` | Tail the debug log |
|
||||
| `x-ui banlog` | Show Fail2ban ban log |
|
||||
| `x-ui update` | Update to the latest stable release |
|
||||
| `x-ui update-dev` | Update to the rolling `dev-latest` build |
|
||||
| `x-ui legacy` | Install a specific older version (prompts) |
|
||||
| `x-ui update-all-geofiles` | Update all geo files, restart if changed |
|
||||
| `x-ui migrate-db --dsn …` | Migrate SQLite → PostgreSQL (see [Database](/docs/reference/database)) |
|
||||
| `x-ui install` / `uninstall` | Install / uninstall |
|
||||
|
||||
## Updating
|
||||
|
||||
- **Stable:** menu option **2** or `x-ui update`. Re-running the install script
|
||||
also updates in place.
|
||||
- **Dev channel:** menu option **3** or `x-ui update-dev` — the rolling
|
||||
`dev-latest` per-commit build (not a stable release).
|
||||
- **A specific older version:** menu option **5** (Legacy Version).
|
||||
|
||||
Updating preserves your database and settings. Take a
|
||||
[backup](/docs/operations/backup-restore) before a major-version jump.
|
||||
|
||||
<Callout type="info">
|
||||
Docker users update differently — pull the new image and recreate the
|
||||
container (`docker compose pull && docker compose up -d`) rather than using the
|
||||
`x-ui` update commands.
|
||||
</Callout>
|
||||
|
||||
## Uninstalling
|
||||
|
||||
Menu option **6** or `x-ui uninstall`. It stops and disables the service, removes
|
||||
the service unit, and deletes `/etc/x-ui/` and the install folder. If the panel
|
||||
used a locally-installed PostgreSQL, it offers to purge that too (a separate,
|
||||
irreversible confirmation).
|
||||
|
||||
<Callout type="warn">
|
||||
Uninstalling removes the database (`/etc/x-ui/x-ui.db`) and your configuration.
|
||||
[Back up](/docs/operations/backup-restore) first if you might need it.
|
||||
</Callout>
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: Contributing
|
||||
description: How to contribute to 3x-ui and to translate this documentation.
|
||||
icon: GitPullRequestArrow
|
||||
---
|
||||
|
||||
3x-ui is community-driven. Contributions to the panel and to these docs are
|
||||
welcome.
|
||||
|
||||
## Support the developer
|
||||
|
||||
3x-ui is free and open source, built and maintained in the open. If it's useful
|
||||
to you, consider supporting continued development:
|
||||
|
||||
- **Donate** at [donate.sanaei.dev](https://donate.sanaei.dev/) — the page shows
|
||||
current funding **goals and targets** you can help reach.
|
||||
- **Star** the [repository](https://github.com/MHSanaei/3x-ui) and share the
|
||||
project.
|
||||
- **Join** the Telegram channel [@XrayUI](https://t.me/XrayUI) to follow news and
|
||||
help others.
|
||||
|
||||
## Contribute to 3x-ui
|
||||
|
||||
- Read the project's `CONTRIBUTING.md` in the
|
||||
[repository](https://github.com/MHSanaei/3x-ui).
|
||||
- Open issues for bugs and feature requests with clear reproduction steps.
|
||||
- Use Conventional Commits and keep pull requests focused.
|
||||
|
||||
## Translate the documentation
|
||||
|
||||
This site is built for translation. Content lives under `content/docs/<locale>/`
|
||||
(`en`, `fa`, `ru`, `zh`), and untranslated pages **fall back to English**, so you
|
||||
can translate incrementally.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Copy a page
|
||||
|
||||
Copy a page from `content/docs/en/...` to the same path under your locale, e.g.
|
||||
`content/docs/fa/guide/installation.mdx`.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Translate the prose only
|
||||
|
||||
Translate the body and the frontmatter `title`/`description`. **Do not** translate
|
||||
code, commands, environment variable names, protocol names, or share links.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Mind direction
|
||||
|
||||
Persian (`fa`) renders right-to-left. Keep code blocks and links left-to-right
|
||||
(the layout already handles this), and check the page in both directions.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Missing a page in your locale is fine — it falls back to English rather than
|
||||
404ing. Translate the highest-traffic pages first (installation, first login,
|
||||
REALITY).
|
||||
</Callout>
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: FAQ
|
||||
description: Frequently asked questions about 3x-ui — licensing, supported systems, databases, and clients.
|
||||
icon: CircleQuestionMark
|
||||
---
|
||||
|
||||
## Is 3x-ui free and open source?
|
||||
|
||||
Yes. 3x-ui is open source under the GPL-3.0 license. The source is on
|
||||
[GitHub](https://github.com/MHSanaei/3x-ui).
|
||||
|
||||
## What systems does it run on?
|
||||
|
||||
Most major Linux distributions (Ubuntu, Debian, CentOS/RHEL and derivatives,
|
||||
Fedora, Arch, Alpine, and more) across `amd64`, `arm64`, and other architectures.
|
||||
It also runs as a Docker container. See [Installation](/docs/guide/installation).
|
||||
|
||||
## SQLite or PostgreSQL?
|
||||
|
||||
SQLite is the default and is fine for most deployments. PostgreSQL is available
|
||||
for larger setups via `XUI_DB_TYPE=postgres` and `XUI_DB_DSN` — see the
|
||||
[environment variables](/docs/reference/env-vars).
|
||||
|
||||
## Which client apps work with it?
|
||||
|
||||
Any Xray-compatible client — for example v2rayNG, Hiddify, and Clash/Mihomo.
|
||||
Import a client's share link or QR code, or use a
|
||||
[subscription](/docs/config/subscription).
|
||||
|
||||
## How is 3x-ui different from x-ui?
|
||||
|
||||
3x-ui is an enhanced fork of the original X-UI project. It adds broader protocol
|
||||
support, improved stability, per-client traffic accounting, multi-node
|
||||
management, a 13-language UI, and many quality-of-life features.
|
||||
|
||||
## How do I update?
|
||||
|
||||
Re-run the install script (it updates in place), or pull the new Docker image.
|
||||
See [Installation](/docs/guide/installation) and the
|
||||
[releases page](https://github.com/MHSanaei/3x-ui/releases).
|
||||
|
||||
## Where can I get help?
|
||||
|
||||
Join the official Telegram channel [@XrayUI](https://t.me/XrayUI) for
|
||||
announcements and community support, or open an issue on
|
||||
[GitHub](https://github.com/MHSanaei/3x-ui/issues). For common problems, start
|
||||
with [Troubleshooting](/docs/help/troubleshooting).
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Help",
|
||||
"icon": "LifeBuoy",
|
||||
"pages": ["troubleshooting", "faq", "migration", "contributing"]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Migration
|
||||
description: Migrate to 3x-ui from x-ui, between servers, or between 3x-ui versions.
|
||||
icon: ArrowRightLeft
|
||||
---
|
||||
|
||||
## Between servers
|
||||
|
||||
Moving to a new server is a database move:
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Back up the old server
|
||||
|
||||
Copy the database (default `/etc/x-ui/x-ui.db`) and your certificates. See
|
||||
[Backup & restore](/docs/operations/backup-restore).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Install 3x-ui on the new server
|
||||
|
||||
Use the same install method and a compatible version. See
|
||||
[Installation](/docs/guide/installation).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Restore the database
|
||||
|
||||
Stop the panel, put the database in place, restore certificates, and start the
|
||||
panel. Update any IP/domain-specific settings.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Between 3x-ui versions
|
||||
|
||||
Within the same backend, upgrading is usually just re-running the installer or
|
||||
pulling a new image — the panel migrates its own database. Across **major**
|
||||
versions, read the [release notes](https://github.com/MHSanaei/3x-ui/releases)
|
||||
first and take a backup.
|
||||
|
||||
## From x-ui
|
||||
|
||||
Importing an older x-ui panel's database directly into 3x-ui is **not
|
||||
supported** — the schemas differ. Install 3x-ui fresh and recreate
|
||||
inbounds/clients, exporting share links from the old panel as you go.
|
||||
|
||||
<Callout type="warn">
|
||||
Always take a backup before any migration, and keep the old server running
|
||||
until you've verified the new one.
|
||||
</Callout>
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Troubleshooting
|
||||
description: Fix common 3x-ui problems — the panel won't start, 502 errors, certificate issues, and clients that can't connect.
|
||||
icon: Wrench
|
||||
---
|
||||
|
||||
A checklist for the most common issues. When in doubt, raise the log level
|
||||
(`XUI_LOG_LEVEL=debug`) and check the panel and Xray logs.
|
||||
|
||||
## The panel won't start
|
||||
|
||||
- Check the service status and logs (`x-ui` menu → status/logs).
|
||||
- Make sure the **panel port isn't already in use** by another service.
|
||||
- Verify the database path is writable (default `/etc/x-ui/x-ui.db`).
|
||||
|
||||
## 502 / panel unreachable behind a proxy
|
||||
|
||||
- Confirm the panel is actually listening on the upstream port (e.g. `2053`).
|
||||
- Ensure your [reverse proxy](/docs/operations/reverse-proxy) passes WebSocket
|
||||
upgrade headers and points at the correct port and **web base path**.
|
||||
- Check the firewall isn't blocking the proxy → panel connection.
|
||||
|
||||
## Certificate problems
|
||||
|
||||
- The domain's DNS must point at the server before issuing a certificate.
|
||||
- Ports 80/443 must be reachable for HTTP/TLS validation (or use DNS validation).
|
||||
- For REALITY, remember it needs **no certificate** — the issue is usually a bad
|
||||
`dest`/SNI instead (see [REALITY pitfalls](/docs/config/reality)).
|
||||
|
||||
## A client can't connect
|
||||
|
||||
- Decode the client's link with the
|
||||
[share-link inspector](/docs/config/share-links) and confirm every parameter.
|
||||
- Check the **transport and security match** on both ends.
|
||||
- Make sure the client hasn't hit its **traffic, expiry, or IP limit**.
|
||||
- Confirm the inbound port is open in the firewall.
|
||||
|
||||
<Callout type="info">
|
||||
Still stuck? Search the
|
||||
[GitHub issues](https://github.com/MHSanaei/3x-ui/issues) — your symptom has
|
||||
probably been seen before.
|
||||
</Callout>
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: 3x-ui Documentation
|
||||
description: Official documentation for 3x-ui — an advanced web panel for managing Xray-core servers, proxies, clients, and subscriptions.
|
||||
icon: House
|
||||
---
|
||||
|
||||
**3x-ui** is an open-source web panel for deploying and managing
|
||||
[Xray-core](https://github.com/XTLS/Xray-core) servers. It gives you a modern
|
||||
dashboard for inbounds, protocols, clients, traffic accounting, subscriptions,
|
||||
and more — without hand-editing Xray JSON on the command line.
|
||||
|
||||
This site is the official documentation and a set of **interactive, in-browser
|
||||
tools** (config generators) that run entirely on your device — no data ever
|
||||
leaves the page.
|
||||
|
||||
## Start here
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="What is 3x-ui?"
|
||||
href="/docs/guide"
|
||||
description="The big picture: Xray-core, the panel, and who it's for."
|
||||
/>
|
||||
<Card
|
||||
title="Installation"
|
||||
href="/docs/guide/installation"
|
||||
description="Install via script, Docker, or manually."
|
||||
/>
|
||||
<Card
|
||||
title="First login"
|
||||
href="/docs/guide/first-login"
|
||||
description="Reach the panel and harden it before anything else."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="Set up VLESS + REALITY with XTLS-Vision."
|
||||
/>
|
||||
</Cards>
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Every major protocol** — VLESS, VMess, Trojan, Shadowsocks, WireGuard,
|
||||
Hysteria2, SOCKS, HTTP, and Dokodemo-door.
|
||||
- **REALITY & XTLS-Vision** — modern, censorship-resistant transports.
|
||||
- **Per-client controls** — traffic quotas, expiry dates, IP limits, share
|
||||
links, and QR codes.
|
||||
- **Subscriptions** — VLESS, Clash/Mihomo, and JSON formats.
|
||||
- **Operations** — multi-node management, Telegram bot, backups, and a REST API.
|
||||
|
||||
<Callout type="info">
|
||||
New to Xray? Read [What is 3x-ui?](/docs/guide) first — it explains how the panel, Xray-core, and
|
||||
your client apps fit together.
|
||||
</Callout>
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pages": ["index", "guide", "config", "operations", "reference", "help"]
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Backup & Restore
|
||||
description: Back up and restore your 3x-ui database and certificates, manually or via the Telegram bot.
|
||||
icon: DatabaseBackup
|
||||
---
|
||||
|
||||
Your entire configuration — inbounds, clients, settings — lives in the panel's
|
||||
database. Back it up regularly so you can recover or migrate.
|
||||
|
||||
## What to back up
|
||||
|
||||
- **The database** — SQLite at `/etc/x-ui/x-ui.db` by default (or your
|
||||
PostgreSQL database if you use that backend).
|
||||
- **Certificates** — anything under `/root/cert/` (or wherever you store TLS
|
||||
certs).
|
||||
|
||||
## Manual backup
|
||||
|
||||
You can download a backup from the panel's overview, or copy the database file
|
||||
directly from the server:
|
||||
|
||||
```bash title="copy the SQLite database"
|
||||
cp /etc/x-ui/x-ui.db /root/x-ui-backup-$(date +%F).db
|
||||
```
|
||||
|
||||
To restore, stop the panel, put the database back in place, and start it again.
|
||||
|
||||
<Callout type="warn">
|
||||
Restore a backup onto the **same major version** it came from when possible.
|
||||
Across major upgrades, let the panel run its migrations rather than forcing an
|
||||
old schema.
|
||||
</Callout>
|
||||
|
||||
## Telegram backup
|
||||
|
||||
If you've configured the [Telegram bot](/docs/operations/telegram-bot), enable
|
||||
**`tgBotBackup`** to attach a backup to the periodic report (on the `tgRunTime`
|
||||
schedule, default daily). The bot sends both the **database** and the **Xray
|
||||
`config.json`** to your admin chat, so you always have an off-server copy. Admins
|
||||
can also request a backup on demand from the bot's menu.
|
||||
|
||||
## SQLite dump / restore
|
||||
|
||||
The `x-ui migrate-db` command converts the SQLite database to and from a plain
|
||||
SQL text dump (handy for inspection or transferring between machines):
|
||||
|
||||
```bash
|
||||
x-ui migrate-db --dump /root/x-ui.sql # SQLite -> SQL text
|
||||
x-ui migrate-db --restore /root/x-ui.sql # SQL text -> SQLite
|
||||
```
|
||||
|
||||
To move to PostgreSQL instead, see [Database](/docs/reference/database).
|
||||
|
||||
<Callout type="info">
|
||||
Whatever method you use, store backups **off the server** and test a restore
|
||||
occasionally — an untested backup isn't a backup.
|
||||
</Callout>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "Operations",
|
||||
"icon": "ServerCog",
|
||||
"pages": [
|
||||
"reverse-proxy",
|
||||
"multi-node",
|
||||
"outbounds-routing",
|
||||
"backup-restore",
|
||||
"telegram-bot",
|
||||
"security"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Multi-node & Managed Hosts
|
||||
description: Manage multiple 3x-ui panels from one master, with API-token or mTLS trust, heartbeats, and per-inbound host overrides for subscriptions.
|
||||
icon: Boxes
|
||||
---
|
||||
|
||||
3x-ui can manage **multiple servers** from a single master panel, and override
|
||||
how each inbound is advertised in subscriptions with **managed hosts**.
|
||||
|
||||
## Nodes
|
||||
|
||||
A **node** is another 3x-ui panel that your master panel manages over the node's
|
||||
API. The master polls each node and shows its status, versions, CPU/memory,
|
||||
uptime, and traffic in one place.
|
||||
|
||||
### Add a node
|
||||
|
||||
Provide the node's connection details:
|
||||
|
||||
| Field | Notes |
|
||||
| ----------------- | --------------------------------------------------------------------- |
|
||||
| **Name** | Unique label (e.g. `de-fra-1`). |
|
||||
| **Scheme** | `https` (default) or `http`. |
|
||||
| **Address / Port**| The node panel's host and port. |
|
||||
| **Base path** | The node's web base path. |
|
||||
| **API token** | A Bearer token created on the node (not needed in mTLS mode). |
|
||||
| **TLS verify** | `verify` (default), `skip`, `pin` (pin a cert SHA-256), or `mtls`. |
|
||||
| **Inbound sync** | `all` inbounds, or `selected` by tag. |
|
||||
| **Outbound tag** | Optionally reach the node **through** a named outbound (egress bridge).|
|
||||
|
||||
The master verifies reachability when you add or test a node. It then sends a
|
||||
**heartbeat** every few seconds, updating the node's status (`online` / `offline`)
|
||||
and emitting `node.up` / `node.down` events (see the
|
||||
[Telegram bot](/docs/operations/telegram-bot)).
|
||||
|
||||
<Callout type="info">
|
||||
Nodes are identified by a stable per-panel GUID, so a node keeps its identity
|
||||
across restarts. A node can itself manage further nodes — the master surfaces
|
||||
those as read-only **transitive** sub-nodes (Node 1 → Node 2 → Node 3).
|
||||
</Callout>
|
||||
|
||||
### Mutual TLS (mTLS) between master and node
|
||||
|
||||
For the strongest trust, use `tlsVerifyMode = mtls` (requires `https`):
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Get the master's CA
|
||||
|
||||
On the master, fetch its node-auth CA certificate (the CA private key never
|
||||
leaves the panel).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Trust it on the node
|
||||
|
||||
Paste that CA into the node's "trusted CA" setting. It takes effect on the node's
|
||||
next restart.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Switch the node to mTLS
|
||||
|
||||
Set the node's TLS verify mode to `mtls`. The master now presents a client
|
||||
certificate instead of an API token.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Managed hosts
|
||||
|
||||
A **managed host** is an override endpoint attached to an inbound. At
|
||||
subscription time, each enabled host renders an additional share link / proxy
|
||||
with its own address, port, TLS, SNI, host header, path, and more — superseding
|
||||
the older "external proxy" list. Use them to:
|
||||
|
||||
- front an inbound through a **CDN** (Cloudflare) with a different address/SNI,
|
||||
- advertise **multiple domains** or per-region endpoints for one inbound,
|
||||
- tweak ALPN, fingerprint, ECH, or mux per endpoint.
|
||||
|
||||
Each host has a remark (which supports the same
|
||||
[template variables](/docs/config/share-links#remark-template-variables)), an
|
||||
enable toggle, a sort order, and can be **excluded from specific subscription
|
||||
formats** or **scoped to specific nodes**.
|
||||
|
||||
<Callout type="info">
|
||||
Hosts whose address/port point at a CDN let you keep the real server address
|
||||
private while clients connect through the CDN edge.
|
||||
</Callout>
|
||||
|
||||
## Related
|
||||
|
||||
<Cards>
|
||||
<Card title="Outbounds & routing" href="/docs/operations/outbounds-routing" description="WARP, NordVPN, outbound subscriptions, and routing." />
|
||||
<Card title="Subscription" href="/docs/config/subscription" description="How hosts shape subscription output." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: Outbounds & Routing
|
||||
description: Shape egress in 3x-ui — WARP and NordVPN outbounds, outbound subscriptions (server pools), routing rules, and load balancers.
|
||||
icon: Route
|
||||
---
|
||||
|
||||
Inbounds accept clients; **outbounds** decide where their traffic goes next.
|
||||
3x-ui can route traffic through Cloudflare WARP, NordVPN, or arbitrary outbound
|
||||
pools imported from a subscription, and select between them with routing rules
|
||||
and balancers.
|
||||
|
||||
## Editing outbounds & routing
|
||||
|
||||
Outbounds, routing rules, balancers, DNS, and logging all live in the **Xray
|
||||
configuration** (the config template you edit under Xray Settings). There's no
|
||||
separate per-rule UI — you edit the JSON, and the panel reloads Xray. The panel
|
||||
also offers an **outbound connectivity test** and a **route test** (ask the
|
||||
running core which outbound a given destination would use).
|
||||
|
||||
## Build an outbound
|
||||
|
||||
Every outbound is a JSON object with up to four parts: a **`tag`** (referenced by
|
||||
routing rules and balancers), a **`protocol`**, protocol-specific **`settings`**,
|
||||
and — for proxy protocols — **`streamSettings`** that must match the remote
|
||||
inbound's transport and security. Two outbounds are almost always present:
|
||||
|
||||
- **`freedom`** sends traffic straight to its destination — the default egress.
|
||||
Optionally set a `domainStrategy` (e.g. `UseIP`) to control how hostnames resolve.
|
||||
- **`blackhole`** drops traffic. Route unwanted destinations (ads, torrents) here.
|
||||
|
||||
```json title="freedom + blackhole"
|
||||
{
|
||||
"outbounds": [
|
||||
{ "tag": "direct", "protocol": "freedom", "settings": {} },
|
||||
{ "tag": "block", "protocol": "blackhole", "settings": {} }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
A **proxy** outbound (VLESS, VMess, Trojan, Shadowsocks) forwards to another
|
||||
server — handy for chaining or sending select traffic abroad. Mind the wire
|
||||
shapes 3x-ui uses: **VLESS is the flat form** (`address`/`port`/`id`/`flow`/
|
||||
`encryption`), **VMess uses `settings.vnext[]`**, and **Trojan/Shadowsocks use
|
||||
`settings.servers[]`**. The `streamSettings` must mirror the destination's
|
||||
[transport and security](/docs/config/transports).
|
||||
|
||||
Assemble any outbound below and paste the JSON into **Xray Settings → Outbounds**:
|
||||
|
||||
<OutboundGenerator />
|
||||
|
||||
## Cloudflare WARP
|
||||
|
||||
WARP lets your server egress through Cloudflare's network. 3x-ui can register a
|
||||
WARP account for you and wire it into a WireGuard outbound tagged **`warp`**:
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Add a `warp`-tagged outbound
|
||||
|
||||
Create a WireGuard outbound with the tag `warp` in your Xray config.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Register WARP
|
||||
|
||||
From the panel's WARP controls, register an account. 3x-ui fills the outbound's
|
||||
keys, addresses, reserved bytes, and peer endpoint automatically.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### (Optional) auto-rotate the IP
|
||||
|
||||
Set a WARP update interval (in **days**) to periodically rotate the WARP IP. A
|
||||
free license can also be applied.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
Route the traffic you want (for example specific domains) to the `warp` outbound
|
||||
with a routing rule.
|
||||
|
||||
## NordVPN
|
||||
|
||||
3x-ui can fetch NordVPN (NordLynx/WireGuard) credentials from an access token (or
|
||||
accept a private key directly) and list countries/servers, so you can build a
|
||||
NordVPN outbound.
|
||||
|
||||
## Outbound subscriptions (server pools)
|
||||
|
||||
An **outbound subscription** imports a remote share-link subscription and injects
|
||||
its servers as **outbounds** into the running Xray config — without touching your
|
||||
saved template. This is the recommended way to subscribe to a *pool* of servers.
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| ---------------- | ------- | -------------------------------------------------------------- |
|
||||
| `url` | — | The remote subscription URL (SSRF-guarded). |
|
||||
| `tagPrefix` | auto | Prefix for generated outbound tags (e.g. `hk-`); blank = `subN-`. |
|
||||
| `updateInterval` | `600` | Refresh interval in **seconds**. |
|
||||
| `prepend` | `false` | Place these outbounds before your manual ones. |
|
||||
| `priority` | `0` | Merge order (lower first). |
|
||||
|
||||
Imported outbounds get **stable tags**: the same server keeps the same tag across
|
||||
refreshes, so exact-tag routing/balancer selectors stay pinned — while
|
||||
prefix/wildcard selectors (e.g. `hk-*`) automatically pick up new servers as the
|
||||
pool changes. Supported link schemes: `vmess`, `vless`, `trojan`, `ss`,
|
||||
`hysteria2` (`hy2`), and `wireguard` (`wg`). The panel refreshes enabled
|
||||
subscriptions on a timer and reloads Xray when something changes.
|
||||
|
||||
## Routing rules
|
||||
|
||||
**Routing rules** decide which outbound (or balancer) each connection uses. Each
|
||||
rule is a `field`-type matcher: set any of `domain`, `ip`, `port`, `network`,
|
||||
`protocol`, `inboundTag`, `sourceIP`, … and point it at an **`outboundTag`** or a
|
||||
**`balancerTag`**. Rules are evaluated **top-to-bottom — the first match wins**, so
|
||||
put specific rules above general ones.
|
||||
|
||||
```json title="route ads to blackhole, private IPs direct"
|
||||
{
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{ "type": "field", "domain": ["geosite:category-ads-all"], "outboundTag": "block" },
|
||||
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Balancers
|
||||
|
||||
A **balancer** groups outbounds by a **selector** (tag prefixes, including the
|
||||
wildcard pools from outbound subscriptions) and spreads or fails traffic over them
|
||||
with a **strategy**:
|
||||
|
||||
| Strategy | Picks… | Needs a monitor |
|
||||
| ------------- | ----------------------------------------------- | ------------------------ |
|
||||
| `random` | a random member per connection | no |
|
||||
| `roundRobin` | members in rotation | no |
|
||||
| `leastPing` | the lowest-latency member | **`observatory`** |
|
||||
| `leastLoad` | the most stable member by sampled load | **`burstObservatory`** |
|
||||
|
||||
Reference a balancer from a rule via `balancerTag`. `leastPing` and `leastLoad`
|
||||
need a health monitor, which Xray places at the **top level** of the config
|
||||
(`observatory` / `burstObservatory`, **not** inside `routing`). The panel can
|
||||
report balancer status and **override** a balancer to a specific outbound for
|
||||
testing.
|
||||
|
||||
Build the routing block — rules, balancers, and the matching observatory — here:
|
||||
|
||||
<RoutingBuilder />
|
||||
|
||||
<Callout type="warn">
|
||||
Outbounds that reach external services are fetched with SSRF protection — by
|
||||
default private/internal addresses are blocked unless you explicitly allow them
|
||||
per source.
|
||||
</Callout>
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Reverse Proxy
|
||||
description: Put the 3x-ui panel and subscription behind Nginx or Caddy with Let's Encrypt TLS.
|
||||
icon: Waypoints
|
||||
---
|
||||
|
||||
A reverse proxy lets you serve the panel and subscription on a clean domain with
|
||||
automatic HTTPS, and hide the real ports behind ports 80/443. Prefer to let the
|
||||
panel terminate TLS directly? Get a certificate with the
|
||||
[`x-ui` SSL menu](/docs/config/ssl-certificates) instead.
|
||||
|
||||
## Generate a config
|
||||
|
||||
<ReverseProxyGenerator />
|
||||
|
||||
<Callout type="info">
|
||||
The panel uses WebSockets for live updates, so the proxy must pass the
|
||||
`Upgrade`/`Connection` headers (the Nginx output above already does). Caddy
|
||||
handles WebSocket upgrades automatically.
|
||||
</Callout>
|
||||
|
||||
## Nginx + certificate
|
||||
|
||||
With Nginx, obtain a certificate with `certbot` (or `acme.sh`) and reference it
|
||||
in the server block:
|
||||
|
||||
```bash title="certbot"
|
||||
certbot certonly --nginx -d panel.example.com
|
||||
```
|
||||
|
||||
Reload Nginx after installing the certificate, and set up automatic renewal
|
||||
(`certbot renew` runs on a timer by default).
|
||||
|
||||
## Caddy
|
||||
|
||||
Caddy obtains and renews certificates for you — point a Caddyfile at the panel
|
||||
and it just works:
|
||||
|
||||
```text title="Caddyfile"
|
||||
panel.example.com {
|
||||
reverse_proxy 127.0.0.1:2053
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Keep the panel's **web base path** even behind a proxy; defense in depth.
|
||||
- If you terminate TLS at the proxy, you may want `XUI_SKIP_HSTS=true` on the
|
||||
panel — see the [environment variables reference](/docs/reference/env-vars).
|
||||
- Proxy the [subscription](/docs/config/subscription) server too, so its contents
|
||||
are served over HTTPS.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: Security
|
||||
description: Harden 3x-ui — panel auth and 2FA, Fail2ban IP limits, firewall rules, BBR, and staying current.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
A proxy panel is a high-value target. A few layers of hardening go a long way.
|
||||
|
||||
## Panel hardening
|
||||
|
||||
- Strong, unique credentials and **two-factor auth** (TOTP).
|
||||
- A non-default panel port and a long, random web base path.
|
||||
- TLS on the panel (directly or via a [reverse proxy](/docs/operations/reverse-proxy)).
|
||||
- The built-in **login limiter** blocks an IP/username after 5 failed attempts
|
||||
in 5 minutes (for 15 minutes), and the panel can route its own egress through
|
||||
an outbound.
|
||||
|
||||
See [First login](/docs/guide/first-login) for the full checklist.
|
||||
|
||||
## Fail2ban & IP limits
|
||||
|
||||
Set an **IP limit** per client (see [Clients](/docs/config/clients)) to cap the
|
||||
number of simultaneous source IPs. Enforcement is handled by **Fail2ban**, which
|
||||
3x-ui installs and configures for you (enabled by default on script installs, and
|
||||
on Docker via `XUI_ENABLE_FAIL2BAN=true`).
|
||||
|
||||
Manage it from the `x-ui` menu (**22 — IP Limit Management**): install/configure,
|
||||
change the ban duration (default **30 minutes**), ban/unban an IP, view ban logs,
|
||||
and check status. Under the hood:
|
||||
|
||||
- The jail is named **`3x-ipl`**; ban logs live at `/var/log/x-ui/3xipl.log` and
|
||||
`/var/log/x-ui/3xipl-banned.log` (also via `x-ui banlog`).
|
||||
- Bans cover all TCP/UDP **except** your SSH and panel ports, so a ban can't lock
|
||||
you out of the server or panel.
|
||||
|
||||
<Callout type="warn">
|
||||
On Docker, Fail2ban bans with `iptables`, which needs the `NET_ADMIN` (and
|
||||
`NET_RAW`) capability — `docker-compose.yml` grants them. With a bare
|
||||
`docker run`, add `--cap-add=NET_ADMIN --cap-add=NET_RAW` or bans are logged
|
||||
but never applied.
|
||||
</Callout>
|
||||
|
||||
## Firewall
|
||||
|
||||
Open only the ports you actually use: SSH, the panel port, the subscription
|
||||
port, and your inbound ports. The `x-ui` menu (**23 — Firewall Management**) wraps
|
||||
`ufw`, or generate rules here:
|
||||
|
||||
<FirewallRulesGenerator />
|
||||
|
||||
<Callout type="warn">
|
||||
Make sure SSH stays allowed before enabling a default-deny firewall, or you can
|
||||
lock yourself out. Test with a second session open.
|
||||
</Callout>
|
||||
|
||||
## Network tuning (BBR)
|
||||
|
||||
The `x-ui` menu (**26 — Enable BBR**) toggles Google's BBR congestion control
|
||||
(`net.ipv4.tcp_congestion_control = bbr`, `net.core.default_qdisc = fq`), which
|
||||
often improves throughput on congested links.
|
||||
|
||||
## Keep current
|
||||
|
||||
Update 3x-ui and Xray-core regularly — security fixes land in new releases. Watch
|
||||
the [releases page](https://github.com/MHSanaei/3x-ui/releases) and see
|
||||
[Update & uninstall](/docs/guide/update-uninstall).
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: Telegram Bot
|
||||
description: Connect a Telegram bot to 3x-ui for commands, periodic reports, event alerts (login, CPU, node up/down), backups, and client self-service.
|
||||
icon: Send
|
||||
---
|
||||
|
||||
3x-ui can drive a Telegram bot for monitoring, alerts, backups, and remote
|
||||
management. Admins get full control; regular users (linked by Telegram ID) can
|
||||
check their own usage and links.
|
||||
|
||||
<Callout type="info">
|
||||
Looking for news and community support? Join the official Telegram channel
|
||||
[@XrayUI](https://t.me/XrayUI). That's separate from the bot below, which you
|
||||
run yourself to manage your own panel.
|
||||
</Callout>
|
||||
|
||||
## Set it up
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Create a bot
|
||||
|
||||
Message [@BotFather](https://t.me/BotFather), send `/newbot`, and copy the **bot
|
||||
token**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Find your Telegram ID
|
||||
|
||||
Get your numeric Telegram user ID (the bot's own `/id` command reports it once
|
||||
connected). This is your **admin** ID.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Configure the panel
|
||||
|
||||
In Panel Settings, enable the Telegram bot and set the **token** and **admin chat
|
||||
ID(s)** (comma-separated). Save, then message your bot.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
Validate your token, admin IDs, and report schedule before pasting them into the
|
||||
panel:
|
||||
|
||||
<TelegramSetupHelper />
|
||||
|
||||
## Commands
|
||||
|
||||
These appear in the Telegram command menu: `/start`, `/help`, `/status`, `/id`.
|
||||
Additional commands:
|
||||
|
||||
| Command | Who | Action |
|
||||
| ------------------ | ------ | ------------------------------------------------------------ |
|
||||
| `/start`, `/help` | anyone | Greeting and the menu of inline buttons |
|
||||
| `/status` | anyone | Confirm the bot is alive |
|
||||
| `/id` | anyone | Show your Telegram numeric ID |
|
||||
| `/usage <arg>` | both | Admins search clients; users look up their own usage |
|
||||
| `/inbound <remark>`| admin | Show an inbound's details |
|
||||
| `/restart` | admin | Restart Xray |
|
||||
|
||||
Admins also get inline-button flows for server usage, sorted traffic reports,
|
||||
resetting traffic, DB backups, ban logs, listing inbounds/clients, online
|
||||
clients, "depleting soon", and a full **add-client** wizard. Regular users get
|
||||
buttons for their own usage, subscription links, individual links, and QR codes.
|
||||
|
||||
## Reports & alerts
|
||||
|
||||
- **Periodic report** — on the `tgRunTime` schedule (default `@daily`), the bot
|
||||
sends admins server usage (host, versions, uptime, load, memory, online
|
||||
clients, traffic), a list of exhausted/expiring clients, and — if
|
||||
`tgBotBackup` is on — a database + Xray config backup. Clients linked by
|
||||
Telegram ID get their own expiry/quota warnings.
|
||||
- **Event alerts** — selected by `tgEnabledEvents` (default `login.attempt,cpu.high`):
|
||||
|
||||
| Event | When |
|
||||
| --------------- | ------------------------------------------------------- |
|
||||
| `login.attempt` | A panel login succeeds or fails (with IP and username) |
|
||||
| `cpu.high` | CPU exceeds `tgCpu` percent (default 80) |
|
||||
| `memory.high` | Memory exceeds `tgMemory` percent (default 80) |
|
||||
| `xray.crash` | Xray-core crashes |
|
||||
| `outbound.down` / `outbound.up` | An outbound goes down / recovers |
|
||||
| `node.down` / `node.up` | A node goes offline / comes back |
|
||||
|
||||
The warning lead times come from `expireDiff` (days before expiry) and
|
||||
`trafficDiff` (GB of quota remaining); both default to `0` (off).
|
||||
|
||||
## Settings
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| -------------- | -------------------------- | ---------------------------------------------- |
|
||||
| `tgBotEnable` | `false` | Master on/off. |
|
||||
| `tgBotToken` | _(secret)_ | Bot API token. |
|
||||
| `tgBotChatId` | _(none)_ | Comma-separated **admin** Telegram IDs. |
|
||||
| `tgBotProxy` | _(none)_ | `socks5://`, `http://`, or `https://` proxy. |
|
||||
| `tgBotAPIServer` | _(default)_ | Custom Telegram Bot API server. |
|
||||
| `tgRunTime` | `@daily` | Report schedule (cron / `@daily` / `@every …`).|
|
||||
| `tgBotBackup` | `false` | Attach a DB backup to the periodic report. |
|
||||
| `tgCpu` / `tgMemory` | `80` / `80` | CPU / memory alert thresholds (percent). |
|
||||
| `tgLang` | `en-US` | Bot language. |
|
||||
| `tgEnabledEvents` | `login.attempt,cpu.high`| Which events to deliver. |
|
||||
|
||||
<Callout type="warn">
|
||||
The bot token controls your bot — keep it secret and only add **trusted** admin
|
||||
chat IDs. Login alerts never include passwords.
|
||||
</Callout>
|
||||
|
||||
<Callout type="info">
|
||||
Email (SMTP) notifications mirror the same events (`smtpEnabledEvents`) if you'd
|
||||
rather receive alerts by email — configure SMTP in Panel Settings.
|
||||
</Callout>
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: API Tokens
|
||||
description: >-
|
||||
Manage Bearer tokens used for programmatic auth (bots, central panels acting
|
||||
on this node, CI). Each token has a unique name and an enabled flag — disable
|
||||
to revoke without deleting, delete to revoke permanently. Tokens are stored as
|
||||
SHA-256 hashes and the plaintext is returned only once, in the create response
|
||||
— it cannot be retrieved afterwards, so copy it then. Send one as
|
||||
<code>Authorization: Bearer <token></code> on any /panel/api/* request —
|
||||
the token is a full-admin credential.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every API token, enabled or not. The token value is never returned
|
||||
— only metadata.
|
||||
url: >-
|
||||
#list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
|
||||
- depth: 2
|
||||
title: >-
|
||||
Mint a new API token. Name must be unique and 1-64 characters; the token
|
||||
string is server-generated and returned only in this response — it is
|
||||
stored hashed and cannot be retrieved later.
|
||||
url: >-
|
||||
#mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
|
||||
- depth: 2
|
||||
title: >-
|
||||
Permanently delete a token. Any caller using it stops authenticating
|
||||
immediately.
|
||||
url: >-
|
||||
#permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle a token enabled/disabled without deleting it. Disabled tokens are
|
||||
rejected by checkAPIAuth on the next request.
|
||||
url: >-
|
||||
#toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every API token, enabled or not. The token value is never
|
||||
returned — only metadata.
|
||||
id: >-
|
||||
list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
|
||||
- content: >-
|
||||
Mint a new API token. Name must be unique and 1-64 characters; the
|
||||
token string is server-generated and returned only in this response —
|
||||
it is stored hashed and cannot be retrieved later.
|
||||
id: >-
|
||||
mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
|
||||
- content: >-
|
||||
Permanently delete a token. Any caller using it stops authenticating
|
||||
immediately.
|
||||
id: >-
|
||||
permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
|
||||
- content: >-
|
||||
Toggle a token enabled/disabled without deleting it. Disabled tokens
|
||||
are rejected by checkAPIAuth on the next request.
|
||||
id: >-
|
||||
toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/apiTokens","method":"get"},{"path":"/panel/api/setting/apiTokens/create","method":"post"},{"path":"/panel/api/setting/apiTokens/delete/{id}","method":"post"},{"path":"/panel/api/setting/apiTokens/setEnabled/{id}","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Authentication
|
||||
description: >-
|
||||
Two authentication modes are supported. UI sessions use a cookie set by the
|
||||
login endpoint. Programmatic clients (bots, scripts, remote panels)
|
||||
authenticate with a Bearer token taken from Settings → Security → API Token.
|
||||
Both work for every endpoint under /panel/api/*.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Authenticate with username + password and receive a session cookie.
|
||||
Required before any cookie-based API call.
|
||||
url: >-
|
||||
#authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
|
||||
- depth: 2
|
||||
title: Clear the session cookie. Requires the CSRF header for browser sessions.
|
||||
url: '#clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Mint a CSRF token for the current session. The SPA replays it in the
|
||||
X-CSRF-Token header on unsafe requests. Bearer-token callers can skip
|
||||
this — the middleware short-circuits CSRF for authenticated API
|
||||
requests.
|
||||
url: >-
|
||||
#mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
|
||||
- depth: 2
|
||||
title: >-
|
||||
Returns whether 2FA is enabled on the panel — used by the login page to
|
||||
decide whether to show the OTP field.
|
||||
url: >-
|
||||
#returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Authenticate with username + password and receive a session cookie.
|
||||
Required before any cookie-based API call.
|
||||
id: >-
|
||||
authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
|
||||
- content: >-
|
||||
Clear the session cookie. Requires the CSRF header for browser
|
||||
sessions.
|
||||
id: clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions
|
||||
- content: >-
|
||||
Mint a CSRF token for the current session. The SPA replays it in the
|
||||
X-CSRF-Token header on unsafe requests. Bearer-token callers can skip
|
||||
this — the middleware short-circuits CSRF for authenticated API
|
||||
requests.
|
||||
id: >-
|
||||
mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
|
||||
- content: >-
|
||||
Returns whether 2FA is enabled on the panel — used by the login page
|
||||
to decide whether to show the OTP field.
|
||||
id: >-
|
||||
returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/login","method":"post"},{"path":"/logout","method":"post"},{"path":"/csrf-token","method":"get"},{"path":"/getTwoFactorEnable","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Backup
|
||||
description: Operations that interact with the configured Telegram bot.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Send a fresh DB backup to every Telegram chat configured as an admin
|
||||
recipient. No body, no params.
|
||||
url: >-
|
||||
#send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Send a fresh DB backup to every Telegram chat configured as an admin
|
||||
recipient. No body, no params.
|
||||
id: >-
|
||||
send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/backuptotgbot","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,627 @@
|
||||
---
|
||||
title: Clients
|
||||
description: >-
|
||||
Manage clients as first-class entities that can be attached to one or more
|
||||
inbounds. A single client row drives the settings.clients entry in every
|
||||
inbound it belongs to. Endpoints live under /panel/api/clients.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every client with its attached inbound IDs and traffic record. The
|
||||
reverse field, if set, is returned as a nested JSON object (legacy
|
||||
JSON-encoded-string form is still accepted on write).
|
||||
url: >-
|
||||
#list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Filter, sort, and paginate clients on the server. Each item is a slim
|
||||
row (no uuid/password/auth/flow/security/reverse/tgId) so the clients
|
||||
page can ship 25-ish rows in a few KB instead of the full table. The
|
||||
response also includes a summary computed across the full DB row set so
|
||||
dashboard counters stay stable as the user paginates or filters. Page
|
||||
size capped at 200; fetch /get/:email to obtain the full per-client
|
||||
payload for an edit/info modal.
|
||||
url: >-
|
||||
#filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch one client by email, including the inbound IDs and external config
|
||||
IDs it is attached to.
|
||||
url: >-
|
||||
#fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new client and attach it to one or more inbounds in a single
|
||||
call. Body is JSON. Per-protocol secrets (UUID for VLESS/VMess, password
|
||||
for Trojan/Shadowsocks, auth for Hysteria) are generated server-side
|
||||
when omitted, so callers can send only the universal fields.
|
||||
url: >-
|
||||
#create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
|
||||
- depth: 2
|
||||
title: >-
|
||||
Update an existing client by email. Changes propagate to every attached
|
||||
inbound. Body is the JSON client payload — supply the full set of fields
|
||||
you want to keep (the server replaces the row, it does not patch).
|
||||
url: >-
|
||||
#update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete a client by email. Removes it from every attached inbound and
|
||||
drops its traffic record unless keepTraffic=1 is passed.
|
||||
url: >-
|
||||
#delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Attach an existing client to one or more additional inbounds. Body is
|
||||
JSON.
|
||||
url: >-
|
||||
#attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
|
||||
- depth: 2
|
||||
title: Detach a client from one or more inbounds without deleting the client.
|
||||
url: '#detach-a-client-from-one-or-more-inbounds-without-deleting-the-client'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace a client's external links (per-client share links and remote
|
||||
subscription URLs surfaced in their subscription). Sends the full set;
|
||||
the server replaces all rows.
|
||||
url: >-
|
||||
#replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reset the up/down counters for every client globally. Quotas and expiry
|
||||
are not affected. Triggers an Xray restart if any counter actually
|
||||
moved.
|
||||
url: >-
|
||||
#reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete every client whose traffic quota is exhausted (used >= total,
|
||||
when reset is disabled) or whose expiry has passed. Returns the deleted
|
||||
count and triggers an Xray restart when any client was on a running
|
||||
inbound.
|
||||
url: >-
|
||||
#delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete every client that is not attached to any inbound, along with its
|
||||
traffic record, IP log, and external links. Useful for clearing clients
|
||||
left unattached after their inbounds were removed. Returns the deleted
|
||||
count. Cannot be undone.
|
||||
url: >-
|
||||
#delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return every client as a {client, inboundIds} array — the same shape
|
||||
/bulkCreate and /import accept — so the payload round-trips straight
|
||||
back through /import. Clients with no inbound attachment are included
|
||||
with an empty inboundIds list. The UI shows this in a CodeMirror viewer
|
||||
(copy / download); programmatic callers get the array in obj.
|
||||
url: >-
|
||||
#return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
|
||||
- depth: 2
|
||||
title: >-
|
||||
Import clients from a JSON body { "data": "<json>" }, where data is a
|
||||
string-encoded array produced by /export ([{client, inboundIds}]). Items
|
||||
with inboundIds are created and attached to those inbounds; items with
|
||||
an empty inboundIds list are restored as unattached client records.
|
||||
Existing emails are never overwritten — they are returned in skipped.
|
||||
Triggers a single Xray restart at the end if any target inbound was
|
||||
running.
|
||||
url: >-
|
||||
#import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Shift expiry and/or traffic quota for many clients in one call.
|
||||
addDays/addBytes may be negative. Clients with unlimited expiry
|
||||
(expiryTime=0) or unlimited traffic (totalGB=0) are skipped for the
|
||||
corresponding field — bulk extend never converts unlimited to limited.
|
||||
The optional flow directive sets the XTLS flow on every client: "none"
|
||||
clears it, "xtls-rprx-vision"/"xtls-rprx-vision-udp443" set it where the
|
||||
inbound supports it (omit or "" to leave it unchanged). Returns the
|
||||
adjusted count and per-email skip reasons.
|
||||
url: >-
|
||||
#shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Enable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to add each user. Note that enabling a
|
||||
client whose quota is exhausted or whose expiry has passed only flips
|
||||
the flag — the traffic loop will disable it again on the next tick.
|
||||
Returns the changed count and per-email skip reasons.
|
||||
url: >-
|
||||
#enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Disable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to remove each user. Returns the
|
||||
changed count and per-email skip reasons.
|
||||
url: >-
|
||||
#disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete many clients in one call. The server processes the list
|
||||
sequentially so each delete sees the committed state of the previous one
|
||||
— avoids the race the per-email fan-out had on the panel side. Pass
|
||||
keepTraffic=true to retain the xray_client_traffic rows after deletion.
|
||||
url: >-
|
||||
#delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create many clients in one call. Body is a JSON array of {client,
|
||||
inboundIds} payloads — the same shape /add accepts. Items are processed
|
||||
sequentially; per-email skip reasons are returned for items that fail
|
||||
(e.g., duplicate email). Triggers a single Xray restart at the end if
|
||||
any inbound was running.
|
||||
url: >-
|
||||
#create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Add many clients to a group in one call. Updates clients.group_name and
|
||||
patches the matching client entry inside every owning inbound's settings
|
||||
JSON in a single transaction. If the group name does not yet exist (in
|
||||
client_groups or as a derived label), it is auto-created as a persistent
|
||||
group. To clear the group label, use /groups/bulkRemove instead.
|
||||
url: >-
|
||||
#add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
|
||||
- depth: 2
|
||||
title: >-
|
||||
Clear the group label on many clients in one call. Inverse of
|
||||
/groups/bulkAdd. Clients themselves are kept — only the group label is
|
||||
cleared from clients.group_name and from each owning inbound's settings
|
||||
JSON. Groups become empty if all their members are removed.
|
||||
url: >-
|
||||
#clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Attach many existing clients to many inbounds in one call. Each client
|
||||
keeps its identity (email/UUID/password/subId) and a shared traffic row;
|
||||
all clients are added to a target inbound in a single AddInboundClient
|
||||
call. Clients already present on a target are reported under skipped.
|
||||
Returns per-email attached/skipped/errors lists and triggers a single
|
||||
Xray restart if any target inbound was running.
|
||||
url: >-
|
||||
#attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Mirror of bulkAttach: detach many existing clients from many inbounds in
|
||||
one call. For each email, intersects the client's current inbounds with
|
||||
the requested set and detaches from those only; (email, inbound) pairs
|
||||
where the client is not currently attached are silently no-ops. Emails
|
||||
not attached to any of the requested inbounds are reported under
|
||||
skipped. Client records are kept even if they become orphaned — use
|
||||
bulkDel for full removal. Returns per-email detached/skipped/errors
|
||||
lists and triggers a single Xray restart if any target inbound was
|
||||
running.
|
||||
url: >-
|
||||
#mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero up/down counters for many clients in one call. Loops the
|
||||
single-reset path so each client is re-enabled across its attached
|
||||
inbounds and pushed to Xray/remote nodes. Returns the count of
|
||||
successfully reset clients.
|
||||
url: >-
|
||||
#zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
|
||||
- depth: 2
|
||||
title: >-
|
||||
List all client groups with their member counts. Merges persisted groups
|
||||
(rows in client_groups, including empty placeholders) with the distinct
|
||||
group_name values currently set on clients. Sorted alphabetically
|
||||
(case-insensitive).
|
||||
url: >-
|
||||
#list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return just the email list of clients that currently belong to the given
|
||||
group. Useful for fanning a single bulk action over an entire group
|
||||
without round-tripping the full client list.
|
||||
url: >-
|
||||
#return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new empty (placeholder) group. The group becomes selectable in
|
||||
client forms and the filter drawer even before any client is added to
|
||||
it. Errors if a group with the same name already exists.
|
||||
url: >-
|
||||
#create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
|
||||
- depth: 2
|
||||
title: >-
|
||||
Rename a group. The new name is applied to the client_groups row AND
|
||||
propagated to every matching client (both clients.group_name and the
|
||||
client entry inside every owning inbound's settings JSON) in a single
|
||||
transaction. Returns the number of clients whose label was updated.
|
||||
url: >-
|
||||
#rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
|
||||
- depth: 2
|
||||
title: >-
|
||||
Remove a group. Deletes the client_groups row and clears the group label
|
||||
from every matching client (both clients.group_name and the inbound
|
||||
settings JSON). The clients themselves are NOT deleted — use /bulkDel
|
||||
after filtering by group for that. Returns the count of clients whose
|
||||
label was cleared.
|
||||
url: >-
|
||||
#remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero out a single client’s up/down counters. Re-enables the client
|
||||
across every attached inbound and pushes the change to Xray (or the
|
||||
remote node) so depleted users can connect again immediately.
|
||||
url: >-
|
||||
#zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
|
||||
- depth: 2
|
||||
title: >-
|
||||
Manually adjust a client’s upload + download counters. Useful for
|
||||
migrations from external accounting systems.
|
||||
url: >-
|
||||
#manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
|
||||
- depth: 2
|
||||
title: >-
|
||||
List source IPs that have connected with the given client’s credentials.
|
||||
Returns an array of "ip (timestamp)" strings.
|
||||
url: >-
|
||||
#list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
|
||||
- depth: 2
|
||||
title: Reset the recorded IP list for a client.
|
||||
url: '#reset-the-recorded-ip-list-for-a-client'
|
||||
- depth: 2
|
||||
title: >-
|
||||
List the emails of currently connected clients (last seen within the
|
||||
heartbeat window), deduped across every node.
|
||||
url: >-
|
||||
#list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Online client emails grouped by the panelGuid of the node that
|
||||
physically hosts each client. The local panel uses its own GUID; each
|
||||
node (at any depth in a chain) uses its GUID. Lets the inbounds page
|
||||
attribute online status to the real node instead of the intermediate one
|
||||
it syncs through.
|
||||
url: >-
|
||||
#online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
|
||||
- depth: 2
|
||||
title: >-
|
||||
Per-client source IPs grouped by the panelGuid of the node that observed
|
||||
them. Lets the central panel attribute and enforce per-client IP limits
|
||||
using the real visitor IPs each node sees, instead of the address of the
|
||||
intermediate panel it syncs through.
|
||||
url: >-
|
||||
#per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
|
||||
- depth: 2
|
||||
title: >-
|
||||
Inbound tags that carried traffic within the heartbeat window, grouped
|
||||
by the hosting node's panelGuid. Pairs with onlinesByGuid so the
|
||||
inbounds page only marks a multi-inbound client online on the inbounds
|
||||
it actually used. Nodes that do not report per-inbound activity are
|
||||
absent.
|
||||
url: >-
|
||||
#inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
|
||||
- depth: 2
|
||||
title: Map of client email → last-seen unix timestamp.
|
||||
url: '#map-of-client-email--last-seen-unix-timestamp'
|
||||
- depth: 2
|
||||
title: Traffic counters for a client identified by email.
|
||||
url: '#traffic-counters-for-a-client-identified-by-email'
|
||||
- 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
|
||||
- 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:
|
||||
vmess, vless, trojan, shadowsocks, hysteria. If
|
||||
streamSettings.externalProxy is set, returns one URL per external proxy.
|
||||
Protocols without a URL form (socks, http, mixed, wireguard, dokodemo,
|
||||
tunnel) contribute nothing.
|
||||
url: >-
|
||||
#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-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every client with its attached inbound IDs and traffic record.
|
||||
The reverse field, if set, is returned as a nested JSON object (legacy
|
||||
JSON-encoded-string form is still accepted on write).
|
||||
id: >-
|
||||
list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
|
||||
- content: >-
|
||||
Filter, sort, and paginate clients on the server. Each item is a slim
|
||||
row (no uuid/password/auth/flow/security/reverse/tgId) so the clients
|
||||
page can ship 25-ish rows in a few KB instead of the full table. The
|
||||
response also includes a summary computed across the full DB row set
|
||||
so dashboard counters stay stable as the user paginates or filters.
|
||||
Page size capped at 200; fetch /get/:email to obtain the full
|
||||
per-client payload for an edit/info modal.
|
||||
id: >-
|
||||
filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
|
||||
- content: >-
|
||||
Fetch one client by email, including the inbound IDs and external
|
||||
config IDs it is attached to.
|
||||
id: >-
|
||||
fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
|
||||
- content: >-
|
||||
Create a new client and attach it to one or more inbounds in a single
|
||||
call. Body is JSON. Per-protocol secrets (UUID for VLESS/VMess,
|
||||
password for Trojan/Shadowsocks, auth for Hysteria) are generated
|
||||
server-side when omitted, so callers can send only the universal
|
||||
fields.
|
||||
id: >-
|
||||
create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
|
||||
- content: >-
|
||||
Update an existing client by email. Changes propagate to every
|
||||
attached inbound. Body is the JSON client payload — supply the full
|
||||
set of fields you want to keep (the server replaces the row, it does
|
||||
not patch).
|
||||
id: >-
|
||||
update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
|
||||
- content: >-
|
||||
Delete a client by email. Removes it from every attached inbound and
|
||||
drops its traffic record unless keepTraffic=1 is passed.
|
||||
id: >-
|
||||
delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
|
||||
- content: >-
|
||||
Attach an existing client to one or more additional inbounds. Body is
|
||||
JSON.
|
||||
id: >-
|
||||
attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
|
||||
- content: Detach a client from one or more inbounds without deleting the client.
|
||||
id: detach-a-client-from-one-or-more-inbounds-without-deleting-the-client
|
||||
- content: >-
|
||||
Replace a client's external links (per-client share links and remote
|
||||
subscription URLs surfaced in their subscription). Sends the full set;
|
||||
the server replaces all rows.
|
||||
id: >-
|
||||
replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
|
||||
- content: >-
|
||||
Reset the up/down counters for every client globally. Quotas and
|
||||
expiry are not affected. Triggers an Xray restart if any counter
|
||||
actually moved.
|
||||
id: >-
|
||||
reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
|
||||
- content: >-
|
||||
Delete every client whose traffic quota is exhausted (used >= total,
|
||||
when reset is disabled) or whose expiry has passed. Returns the
|
||||
deleted count and triggers an Xray restart when any client was on a
|
||||
running inbound.
|
||||
id: >-
|
||||
delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
|
||||
- content: >-
|
||||
Delete every client that is not attached to any inbound, along with
|
||||
its traffic record, IP log, and external links. Useful for clearing
|
||||
clients left unattached after their inbounds were removed. Returns the
|
||||
deleted count. Cannot be undone.
|
||||
id: >-
|
||||
delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
|
||||
- content: >-
|
||||
Return every client as a {client, inboundIds} array — the same shape
|
||||
/bulkCreate and /import accept — so the payload round-trips straight
|
||||
back through /import. Clients with no inbound attachment are included
|
||||
with an empty inboundIds list. The UI shows this in a CodeMirror
|
||||
viewer (copy / download); programmatic callers get the array in obj.
|
||||
id: >-
|
||||
return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
|
||||
- content: >-
|
||||
Import clients from a JSON body { "data": "<json>" }, where data is a
|
||||
string-encoded array produced by /export ([{client, inboundIds}]).
|
||||
Items with inboundIds are created and attached to those inbounds;
|
||||
items with an empty inboundIds list are restored as unattached client
|
||||
records. Existing emails are never overwritten — they are returned in
|
||||
skipped. Triggers a single Xray restart at the end if any target
|
||||
inbound was running.
|
||||
id: >-
|
||||
import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Shift expiry and/or traffic quota for many clients in one call.
|
||||
addDays/addBytes may be negative. Clients with unlimited expiry
|
||||
(expiryTime=0) or unlimited traffic (totalGB=0) are skipped for the
|
||||
corresponding field — bulk extend never converts unlimited to limited.
|
||||
The optional flow directive sets the XTLS flow on every client: "none"
|
||||
clears it, "xtls-rprx-vision"/"xtls-rprx-vision-udp443" set it where
|
||||
the inbound supports it (omit or "" to leave it unchanged). Returns
|
||||
the adjusted count and per-email skip reasons.
|
||||
id: >-
|
||||
shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Enable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to add each user. Note that enabling
|
||||
a client whose quota is exhausted or whose expiry has passed only
|
||||
flips the flag — the traffic loop will disable it again on the next
|
||||
tick. Returns the changed count and per-email skip reasons.
|
||||
id: >-
|
||||
enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Disable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to remove each user. Returns the
|
||||
changed count and per-email skip reasons.
|
||||
id: >-
|
||||
disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Delete many clients in one call. The server processes the list
|
||||
sequentially so each delete sees the committed state of the previous
|
||||
one — avoids the race the per-email fan-out had on the panel side.
|
||||
Pass keepTraffic=true to retain the xray_client_traffic rows after
|
||||
deletion.
|
||||
id: >-
|
||||
delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
|
||||
- content: >-
|
||||
Create many clients in one call. Body is a JSON array of {client,
|
||||
inboundIds} payloads — the same shape /add accepts. Items are
|
||||
processed sequentially; per-email skip reasons are returned for items
|
||||
that fail (e.g., duplicate email). Triggers a single Xray restart at
|
||||
the end if any inbound was running.
|
||||
id: >-
|
||||
create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
|
||||
- content: >-
|
||||
Add many clients to a group in one call. Updates clients.group_name
|
||||
and patches the matching client entry inside every owning inbound's
|
||||
settings JSON in a single transaction. If the group name does not yet
|
||||
exist (in client_groups or as a derived label), it is auto-created as
|
||||
a persistent group. To clear the group label, use /groups/bulkRemove
|
||||
instead.
|
||||
id: >-
|
||||
add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
|
||||
- content: >-
|
||||
Clear the group label on many clients in one call. Inverse of
|
||||
/groups/bulkAdd. Clients themselves are kept — only the group label is
|
||||
cleared from clients.group_name and from each owning inbound's
|
||||
settings JSON. Groups become empty if all their members are removed.
|
||||
id: >-
|
||||
clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
|
||||
- content: >-
|
||||
Attach many existing clients to many inbounds in one call. Each client
|
||||
keeps its identity (email/UUID/password/subId) and a shared traffic
|
||||
row; all clients are added to a target inbound in a single
|
||||
AddInboundClient call. Clients already present on a target are
|
||||
reported under skipped. Returns per-email attached/skipped/errors
|
||||
lists and triggers a single Xray restart if any target inbound was
|
||||
running.
|
||||
id: >-
|
||||
attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Mirror of bulkAttach: detach many existing clients from many inbounds
|
||||
in one call. For each email, intersects the client's current inbounds
|
||||
with the requested set and detaches from those only; (email, inbound)
|
||||
pairs where the client is not currently attached are silently no-ops.
|
||||
Emails not attached to any of the requested inbounds are reported
|
||||
under skipped. Client records are kept even if they become orphaned —
|
||||
use bulkDel for full removal. Returns per-email
|
||||
detached/skipped/errors lists and triggers a single Xray restart if
|
||||
any target inbound was running.
|
||||
id: >-
|
||||
mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Zero up/down counters for many clients in one call. Loops the
|
||||
single-reset path so each client is re-enabled across its attached
|
||||
inbounds and pushed to Xray/remote nodes. Returns the count of
|
||||
successfully reset clients.
|
||||
id: >-
|
||||
zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
|
||||
- content: >-
|
||||
List all client groups with their member counts. Merges persisted
|
||||
groups (rows in client_groups, including empty placeholders) with the
|
||||
distinct group_name values currently set on clients. Sorted
|
||||
alphabetically (case-insensitive).
|
||||
id: >-
|
||||
list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
|
||||
- content: >-
|
||||
Return just the email list of clients that currently belong to the
|
||||
given group. Useful for fanning a single bulk action over an entire
|
||||
group without round-tripping the full client list.
|
||||
id: >-
|
||||
return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
|
||||
- content: >-
|
||||
Create a new empty (placeholder) group. The group becomes selectable
|
||||
in client forms and the filter drawer even before any client is added
|
||||
to it. Errors if a group with the same name already exists.
|
||||
id: >-
|
||||
create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
|
||||
- content: >-
|
||||
Rename a group. The new name is applied to the client_groups row AND
|
||||
propagated to every matching client (both clients.group_name and the
|
||||
client entry inside every owning inbound's settings JSON) in a single
|
||||
transaction. Returns the number of clients whose label was updated.
|
||||
id: >-
|
||||
rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
|
||||
- content: >-
|
||||
Remove a group. Deletes the client_groups row and clears the group
|
||||
label from every matching client (both clients.group_name and the
|
||||
inbound settings JSON). The clients themselves are NOT deleted — use
|
||||
/bulkDel after filtering by group for that. Returns the count of
|
||||
clients whose label was cleared.
|
||||
id: >-
|
||||
remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
|
||||
- content: >-
|
||||
Zero out a single client’s up/down counters. Re-enables the client
|
||||
across every attached inbound and pushes the change to Xray (or the
|
||||
remote node) so depleted users can connect again immediately.
|
||||
id: >-
|
||||
zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
|
||||
- content: >-
|
||||
Manually adjust a client’s upload + download counters. Useful for
|
||||
migrations from external accounting systems.
|
||||
id: >-
|
||||
manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
|
||||
- content: >-
|
||||
List source IPs that have connected with the given client’s
|
||||
credentials. Returns an array of "ip (timestamp)" strings.
|
||||
id: >-
|
||||
list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
|
||||
- content: Reset the recorded IP list for a client.
|
||||
id: reset-the-recorded-ip-list-for-a-client
|
||||
- content: >-
|
||||
List the emails of currently connected clients (last seen within the
|
||||
heartbeat window), deduped across every node.
|
||||
id: >-
|
||||
list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
|
||||
- content: >-
|
||||
Online client emails grouped by the panelGuid of the node that
|
||||
physically hosts each client. The local panel uses its own GUID; each
|
||||
node (at any depth in a chain) uses its GUID. Lets the inbounds page
|
||||
attribute online status to the real node instead of the intermediate
|
||||
one it syncs through.
|
||||
id: >-
|
||||
online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
|
||||
- content: >-
|
||||
Per-client source IPs grouped by the panelGuid of the node that
|
||||
observed them. Lets the central panel attribute and enforce per-client
|
||||
IP limits using the real visitor IPs each node sees, instead of the
|
||||
address of the intermediate panel it syncs through.
|
||||
id: >-
|
||||
per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
|
||||
- content: >-
|
||||
Inbound tags that carried traffic within the heartbeat window, grouped
|
||||
by the hosting node's panelGuid. Pairs with onlinesByGuid so the
|
||||
inbounds page only marks a multi-inbound client online on the inbounds
|
||||
it actually used. Nodes that do not report per-inbound activity are
|
||||
absent.
|
||||
id: >-
|
||||
inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
|
||||
- content: Map of client email → last-seen unix timestamp.
|
||||
id: map-of-client-email--last-seen-unix-timestamp
|
||||
- content: Traffic counters for a client identified by email.
|
||||
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
|
||||
- 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
|
||||
streamSettings.externalProxy is set, returns one URL per external
|
||||
proxy. Protocols without a URL form (socks, http, mixed, wireguard,
|
||||
dokodemo, tunnel) contribute nothing.
|
||||
id: >-
|
||||
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-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<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 />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Hosts
|
||||
description: >-
|
||||
Per-inbound override endpoints. Each enabled host renders one extra
|
||||
subscription link/proxy with its own address/port/TLS, superseding the legacy
|
||||
externalProxy array. All endpoints under /panel/api/hosts.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every host across all inbounds, grouped by inbound then ordered by
|
||||
sort order.
|
||||
url: >-
|
||||
#list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
|
||||
- depth: 2
|
||||
title: Fetch a single host by ID.
|
||||
url: '#fetch-a-single-host-by-id'
|
||||
- depth: 2
|
||||
title: Fetch one inbound's hosts, ordered by sort order then id.
|
||||
url: '#fetch-one-inbounds-hosts-ordered-by-sort-order-then-id'
|
||||
- depth: 2
|
||||
title: Distinct, sorted set of tags used across all hosts.
|
||||
url: '#distinct-sorted-set-of-tags-used-across-all-hosts'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a host on an inbound. inboundId and remark are required; security
|
||||
defaults to "same" (inherit the inbound).
|
||||
url: >-
|
||||
#create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace a host’s content. The inbound and sort order are immutable here
|
||||
(use /reorder for ordering).
|
||||
url: >-
|
||||
#replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
|
||||
- depth: 2
|
||||
title: Delete a host.
|
||||
url: '#delete-a-host'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Enable or disable a single host (disabled hosts are skipped in
|
||||
subscriptions).
|
||||
url: >-
|
||||
#enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
|
||||
- depth: 2
|
||||
title: Set host sort order by the position of each id in the array.
|
||||
url: '#set-host-sort-order-by-the-position-of-each-id-in-the-array'
|
||||
- depth: 2
|
||||
title: Enable or disable many hosts in one call.
|
||||
url: '#enable-or-disable-many-hosts-in-one-call'
|
||||
- depth: 2
|
||||
title: Delete many hosts in one call.
|
||||
url: '#delete-many-hosts-in-one-call'
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every host across all inbounds, grouped by inbound then ordered
|
||||
by sort order.
|
||||
id: >-
|
||||
list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
|
||||
- content: Fetch a single host by ID.
|
||||
id: fetch-a-single-host-by-id
|
||||
- content: Fetch one inbound's hosts, ordered by sort order then id.
|
||||
id: fetch-one-inbounds-hosts-ordered-by-sort-order-then-id
|
||||
- content: Distinct, sorted set of tags used across all hosts.
|
||||
id: distinct-sorted-set-of-tags-used-across-all-hosts
|
||||
- content: >-
|
||||
Create a host on an inbound. inboundId and remark are required;
|
||||
security defaults to "same" (inherit the inbound).
|
||||
id: >-
|
||||
create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
|
||||
- content: >-
|
||||
Replace a host’s content. The inbound and sort order are immutable
|
||||
here (use /reorder for ordering).
|
||||
id: >-
|
||||
replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
|
||||
- content: Delete a host.
|
||||
id: delete-a-host
|
||||
- content: >-
|
||||
Enable or disable a single host (disabled hosts are skipped in
|
||||
subscriptions).
|
||||
id: >-
|
||||
enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
|
||||
- content: Set host sort order by the position of each id in the array.
|
||||
id: set-host-sort-order-by-the-position-of-each-id-in-the-array
|
||||
- content: Enable or disable many hosts in one call.
|
||||
id: enable-or-disable-many-hosts-in-one-call
|
||||
- content: Delete many hosts in one call.
|
||||
id: delete-many-hosts-in-one-call
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/hosts/list","method":"get"},{"path":"/panel/api/hosts/get/{id}","method":"get"},{"path":"/panel/api/hosts/byInbound/{inboundId}","method":"get"},{"path":"/panel/api/hosts/tags","method":"get"},{"path":"/panel/api/hosts/add","method":"post"},{"path":"/panel/api/hosts/update/{id}","method":"post"},{"path":"/panel/api/hosts/del/{id}","method":"post"},{"path":"/panel/api/hosts/setEnable/{id}","method":"post"},{"path":"/panel/api/hosts/reorder","method":"post"},{"path":"/panel/api/hosts/bulk/setEnable","method":"post"},{"path":"/panel/api/hosts/bulk/del","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
---
|
||||
title: Inbounds
|
||||
description: >-
|
||||
Manage inbound configurations and their clients. All endpoints live under
|
||||
/panel/api/inbounds and require a logged-in session or Bearer token.
|
||||
Link-generating endpoints honour forwarded headers only when the request comes
|
||||
from a configured trusted proxy.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every inbound owned by the authenticated user, including each
|
||||
inbound’s clientStats traffic counters. settings, streamSettings, and
|
||||
sniffing are returned as nested JSON objects (no escaped strings);
|
||||
legacy callers that send them back as JSON-encoded strings are still
|
||||
accepted on write.
|
||||
url: >-
|
||||
#list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Same shape as /list but with settings.clients[] stripped down to {email,
|
||||
enable, comment} and ClientStats not enriched with UUID/SubId. Use this
|
||||
for list pages; fetch /get/:id when you need the full per-client payload
|
||||
(uuid, password, flow, ...).
|
||||
url: >-
|
||||
#same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
|
||||
- depth: 2
|
||||
title: >-
|
||||
Lightweight picker projection of the authenticated user’s inbounds.
|
||||
Returns id, remark, tag, protocol, port, a server-computed
|
||||
tlsFlowCapable flag (true for VLESS on TCP with tls or reality, or on
|
||||
XHTTP with VLESS encryption / vlessenc enabled), and ssMethod (the
|
||||
Shadowsocks cipher, empty for non-Shadowsocks inbounds — used by the
|
||||
client UI to generate a valid Shadowsocks 2022 PSK). Use this for
|
||||
dropdowns and attach pickers — it skips settings, streamSettings, and
|
||||
clientStats so the payload stays small even on panels with thousands of
|
||||
clients.
|
||||
url: >-
|
||||
#lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
|
||||
- depth: 2
|
||||
title: Fetch a single inbound by numeric ID.
|
||||
url: '#fetch-a-single-inbound-by-numeric-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new inbound. Send the full inbound payload (protocol, port,
|
||||
settings, streamSettings, sniffing, remark, expiryTime, total, enable).
|
||||
settings, streamSettings, and sniffing may be sent as nested JSON
|
||||
objects (preferred) or as JSON-encoded strings (legacy).
|
||||
url: >-
|
||||
#create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
|
||||
- depth: 2
|
||||
title: Delete an inbound by ID. Also removes its associated client stats rows.
|
||||
url: '#delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete many inbounds in one call. Processes the list sequentially;
|
||||
failures are reported per id and the rest still proceed. Restarts xray
|
||||
at most once.
|
||||
url: >-
|
||||
#delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
|
||||
inbounds with thousands of clients — prefer /setEnable for enable-only
|
||||
flips.
|
||||
url: >-
|
||||
#replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle only the enable flag without serialising the whole settings JSON.
|
||||
Recommended for UI switches on large inbounds.
|
||||
url: >-
|
||||
#toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero out upload + download counters for a single inbound. Does not touch
|
||||
per-client counters.
|
||||
url: >-
|
||||
#zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
|
||||
- depth: 2
|
||||
title: >-
|
||||
Remove every client attached to a single inbound while keeping the
|
||||
inbound itself. Collects emails from settings.clients[] and feeds them
|
||||
into the optimized bulk-delete path (runtime user removal + traffic-row
|
||||
cleanup + SyncInbound). Destructive and cannot be undone.
|
||||
url: >-
|
||||
#remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reset upload + download counters on every inbound. Destructive —
|
||||
accounting history is lost.
|
||||
url: >-
|
||||
#reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
|
||||
- depth: 2
|
||||
title: >-
|
||||
Bulk-import an inbound from a JSON blob (e.g. one exported via the UI).
|
||||
The body uses form encoding with a single "data" field.
|
||||
url: >-
|
||||
#bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
|
||||
- depth: 2
|
||||
title: >-
|
||||
Receive a master panel's aggregated per-client usage, keyed by the
|
||||
master's GUID. Stored in a side table used only for the UI display
|
||||
overlay and local quota enforcement — never folded into the local
|
||||
counters that masters poll, so delta accounting stays intact. Called
|
||||
panel-to-panel by the node traffic sync job.
|
||||
url: >-
|
||||
#receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
|
||||
- depth: 2
|
||||
title: >-
|
||||
List the fallback rules attached to a master VLESS/Trojan TCP-TLS
|
||||
inbound. Each rule links one child inbound (the dest) to optional
|
||||
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
|
||||
inbound's listen+port is used.
|
||||
url: >-
|
||||
#list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace the entire fallback list for a master inbound. Body is JSON.
|
||||
Triggers an Xray restart.
|
||||
url: >-
|
||||
#replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every inbound owned by the authenticated user, including each
|
||||
inbound’s clientStats traffic counters. settings, streamSettings, and
|
||||
sniffing are returned as nested JSON objects (no escaped strings);
|
||||
legacy callers that send them back as JSON-encoded strings are still
|
||||
accepted on write.
|
||||
id: >-
|
||||
list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
|
||||
- content: >-
|
||||
Same shape as /list but with settings.clients[] stripped down to
|
||||
{email, enable, comment} and ClientStats not enriched with UUID/SubId.
|
||||
Use this for list pages; fetch /get/:id when you need the full
|
||||
per-client payload (uuid, password, flow, ...).
|
||||
id: >-
|
||||
same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
|
||||
- content: >-
|
||||
Lightweight picker projection of the authenticated user’s inbounds.
|
||||
Returns id, remark, tag, protocol, port, a server-computed
|
||||
tlsFlowCapable flag (true for VLESS on TCP with tls or reality, or on
|
||||
XHTTP with VLESS encryption / vlessenc enabled), and ssMethod (the
|
||||
Shadowsocks cipher, empty for non-Shadowsocks inbounds — used by the
|
||||
client UI to generate a valid Shadowsocks 2022 PSK). Use this for
|
||||
dropdowns and attach pickers — it skips settings, streamSettings, and
|
||||
clientStats so the payload stays small even on panels with thousands
|
||||
of clients.
|
||||
id: >-
|
||||
lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
|
||||
- content: Fetch a single inbound by numeric ID.
|
||||
id: fetch-a-single-inbound-by-numeric-id
|
||||
- content: >-
|
||||
Create a new inbound. Send the full inbound payload (protocol, port,
|
||||
settings, streamSettings, sniffing, remark, expiryTime, total,
|
||||
enable). settings, streamSettings, and sniffing may be sent as nested
|
||||
JSON objects (preferred) or as JSON-encoded strings (legacy).
|
||||
id: >-
|
||||
create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
|
||||
- content: >-
|
||||
Delete an inbound by ID. Also removes its associated client stats
|
||||
rows.
|
||||
id: delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows
|
||||
- content: >-
|
||||
Delete many inbounds in one call. Processes the list sequentially;
|
||||
failures are reported per id and the rest still proceed. Restarts xray
|
||||
at most once.
|
||||
id: >-
|
||||
delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
|
||||
- content: >-
|
||||
Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
|
||||
inbounds with thousands of clients — prefer /setEnable for enable-only
|
||||
flips.
|
||||
id: >-
|
||||
replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
|
||||
- content: >-
|
||||
Toggle only the enable flag without serialising the whole settings
|
||||
JSON. Recommended for UI switches on large inbounds.
|
||||
id: >-
|
||||
toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
|
||||
- content: >-
|
||||
Zero out upload + download counters for a single inbound. Does not
|
||||
touch per-client counters.
|
||||
id: >-
|
||||
zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
|
||||
- content: >-
|
||||
Remove every client attached to a single inbound while keeping the
|
||||
inbound itself. Collects emails from settings.clients[] and feeds them
|
||||
into the optimized bulk-delete path (runtime user removal +
|
||||
traffic-row cleanup + SyncInbound). Destructive and cannot be undone.
|
||||
id: >-
|
||||
remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
|
||||
- content: >-
|
||||
Reset upload + download counters on every inbound. Destructive —
|
||||
accounting history is lost.
|
||||
id: >-
|
||||
reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
|
||||
- content: >-
|
||||
Bulk-import an inbound from a JSON blob (e.g. one exported via the
|
||||
UI). The body uses form encoding with a single "data" field.
|
||||
id: >-
|
||||
bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
|
||||
- content: >-
|
||||
Receive a master panel's aggregated per-client usage, keyed by the
|
||||
master's GUID. Stored in a side table used only for the UI display
|
||||
overlay and local quota enforcement — never folded into the local
|
||||
counters that masters poll, so delta accounting stays intact. Called
|
||||
panel-to-panel by the node traffic sync job.
|
||||
id: >-
|
||||
receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
|
||||
- content: >-
|
||||
List the fallback rules attached to a master VLESS/Trojan TCP-TLS
|
||||
inbound. Each rule links one child inbound (the dest) to optional
|
||||
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
|
||||
inbound's listen+port is used.
|
||||
id: >-
|
||||
list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
|
||||
- content: >-
|
||||
Replace the entire fallback list for a master inbound. Body is JSON.
|
||||
Triggers an Xray restart.
|
||||
id: >-
|
||||
replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/inbounds/list","method":"get"},{"path":"/panel/api/inbounds/list/slim","method":"get"},{"path":"/panel/api/inbounds/options","method":"get"},{"path":"/panel/api/inbounds/get/{id}","method":"get"},{"path":"/panel/api/inbounds/add","method":"post"},{"path":"/panel/api/inbounds/del/{id}","method":"post"},{"path":"/panel/api/inbounds/bulkDel","method":"post"},{"path":"/panel/api/inbounds/update/{id}","method":"post"},{"path":"/panel/api/inbounds/setEnable/{id}","method":"post"},{"path":"/panel/api/inbounds/{id}/resetTraffic","method":"post"},{"path":"/panel/api/inbounds/{id}/delAllClients","method":"post"},{"path":"/panel/api/inbounds/resetAllTraffics","method":"post"},{"path":"/panel/api/inbounds/import","method":"post"},{"path":"/panel/api/inbounds/pushClientTraffics","method":"post"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"get"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: API Reference
|
||||
description: The 3x-ui panel REST API — authentication, inbounds, clients, server stats, and more, generated from the OpenAPI spec.
|
||||
icon: Webhook
|
||||
---
|
||||
|
||||
The 3x-ui panel exposes a REST API for automation. These pages are generated from
|
||||
the panel's OpenAPI specification, so they always match the documented schema.
|
||||
|
||||
## Authentication
|
||||
|
||||
Requests authenticate with either a **session cookie** (from `POST /login`) or a
|
||||
**Bearer token**:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
Create API tokens in the panel; they are full-admin credentials, so store them
|
||||
securely. See [API Tokens](/docs/reference/api/api-tokens).
|
||||
|
||||
Build an authenticated request for any endpoint below:
|
||||
|
||||
<ApiRequestBuilder />
|
||||
|
||||
## Browse by area
|
||||
|
||||
<Cards>
|
||||
<Card title="Authentication" href="/docs/reference/api/authentication" />
|
||||
<Card title="Inbounds" href="/docs/reference/api/inbounds" />
|
||||
<Card title="Clients" href="/docs/reference/api/clients" />
|
||||
<Card title="Server" href="/docs/reference/api/server" />
|
||||
<Card title="Settings" href="/docs/reference/api/settings" />
|
||||
<Card title="Xray Settings" href="/docs/reference/api/xray-settings" />
|
||||
</Cards>
|
||||
|
||||
<Callout type="info">
|
||||
This reference is regenerated from `public/openapi.json` with `pnpm gen:api`.
|
||||
Don't edit the generated tag pages by hand.
|
||||
</Callout>
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "API Reference",
|
||||
"icon": "Webhook",
|
||||
"pages": [
|
||||
"index",
|
||||
"authentication",
|
||||
"api-tokens",
|
||||
"inbounds",
|
||||
"clients",
|
||||
"server",
|
||||
"settings",
|
||||
"xray-settings",
|
||||
"subscription-server",
|
||||
"hosts",
|
||||
"nodes",
|
||||
"backup",
|
||||
"websocket"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
---
|
||||
title: Nodes
|
||||
description: >-
|
||||
Manage remote 3x-ui panels acting as nodes for a central panel. All endpoints
|
||||
under /panel/api/nodes.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every configured node with its connection details, health, and last
|
||||
heartbeat patch.
|
||||
url: >-
|
||||
#list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
|
||||
- depth: 2
|
||||
title: >-
|
||||
This panel's node-auth CA certificate (public, PEM) to paste into a
|
||||
node's mTLS trust setting. Lazily mints the CA and the master client
|
||||
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
|
||||
url: >-
|
||||
#this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Set the CA certificate this panel trusts for incoming node-API client
|
||||
certificates (this panel acting as a node). Paste the managing panel's
|
||||
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty value
|
||||
must be a PEM certificate. Applied on the next panel restart.
|
||||
url: >-
|
||||
#set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
|
||||
- depth: 2
|
||||
title: Fetch a single node by ID.
|
||||
url: '#fetch-a-single-node-by-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch a node's own web TLS certificate/key file paths (proxied to the
|
||||
node). Used by the inbound form's "Set Cert from Panel" so a
|
||||
node-assigned inbound gets paths that exist on the node, not the central
|
||||
panel.
|
||||
url: >-
|
||||
#fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
||||
- depth: 2
|
||||
title: >-
|
||||
Register a new remote node. Provide its URL, apiToken, and optional
|
||||
remark / allowPrivateAddress flag.
|
||||
url: >-
|
||||
#register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
|
||||
- depth: 2
|
||||
title: Replace a node’s connection details. Same body shape as /add.
|
||||
url: '#replace-a-nodes-connection-details-same-body-shape-as-add'
|
||||
- depth: 2
|
||||
title: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||
url: '#delete-a-node-inbounds-bound-to-it-are-not-auto-migrated'
|
||||
- depth: 2
|
||||
title: Pause or resume traffic sync with this node.
|
||||
url: '#pause-or-resume-traffic-sync-with-this-node'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Probe a node without saving it. Uses the body as connection details and
|
||||
returns the same heartbeat snapshot a registered node would have.
|
||||
url: >-
|
||||
#probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
|
||||
- depth: 2
|
||||
title: >-
|
||||
Connect to the node over HTTPS without verifying its certificate and
|
||||
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
|
||||
Node dialog to fetch and pin a self-signed certificate. Uses the same
|
||||
body as /test.
|
||||
url: >-
|
||||
#connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
|
||||
- depth: 2
|
||||
title: >-
|
||||
Use unsaved node connection details to list the remote inbounds
|
||||
available for selective import.
|
||||
url: >-
|
||||
#use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
|
||||
- depth: 2
|
||||
title: Probe an existing node, updating its cached health state.
|
||||
url: '#probe-an-existing-node-updating-its-cached-health-state'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Trigger the official panel self-updater on each given node (downloads
|
||||
the latest release and restarts). Only enabled, online nodes are
|
||||
updated; offline/disabled ones are reported as skipped. Set "dev": true
|
||||
to move the nodes to the rolling per-commit dev channel instead of the
|
||||
latest stable release. Returns a per-node result list.
|
||||
url: >-
|
||||
#trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
|
||||
- depth: 2
|
||||
title: >-
|
||||
Aggregated metric history for a node — same shape as /server/history,
|
||||
scoped to one node.
|
||||
url: >-
|
||||
#aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every configured node with its connection details, health, and
|
||||
last heartbeat patch.
|
||||
id: >-
|
||||
list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
|
||||
- content: >-
|
||||
This panel's node-auth CA certificate (public, PEM) to paste into a
|
||||
node's mTLS trust setting. Lazily mints the CA and the master client
|
||||
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
|
||||
id: >-
|
||||
this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
|
||||
- content: >-
|
||||
Set the CA certificate this panel trusts for incoming node-API client
|
||||
certificates (this panel acting as a node). Paste the managing panel's
|
||||
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty
|
||||
value must be a PEM certificate. Applied on the next panel restart.
|
||||
id: >-
|
||||
set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
|
||||
- content: Fetch a single node by ID.
|
||||
id: fetch-a-single-node-by-id
|
||||
- content: >-
|
||||
Fetch a node's own web TLS certificate/key file paths (proxied to the
|
||||
node). Used by the inbound form's "Set Cert from Panel" so a
|
||||
node-assigned inbound gets paths that exist on the node, not the
|
||||
central panel.
|
||||
id: >-
|
||||
fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
||||
- content: >-
|
||||
Register a new remote node. Provide its URL, apiToken, and optional
|
||||
remark / allowPrivateAddress flag.
|
||||
id: >-
|
||||
register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
|
||||
- content: Replace a node’s connection details. Same body shape as /add.
|
||||
id: replace-a-nodes-connection-details-same-body-shape-as-add
|
||||
- content: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||
id: delete-a-node-inbounds-bound-to-it-are-not-auto-migrated
|
||||
- content: Pause or resume traffic sync with this node.
|
||||
id: pause-or-resume-traffic-sync-with-this-node
|
||||
- content: >-
|
||||
Probe a node without saving it. Uses the body as connection details
|
||||
and returns the same heartbeat snapshot a registered node would have.
|
||||
id: >-
|
||||
probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
|
||||
- content: >-
|
||||
Connect to the node over HTTPS without verifying its certificate and
|
||||
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
|
||||
Node dialog to fetch and pin a self-signed certificate. Uses the same
|
||||
body as /test.
|
||||
id: >-
|
||||
connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
|
||||
- content: >-
|
||||
Use unsaved node connection details to list the remote inbounds
|
||||
available for selective import.
|
||||
id: >-
|
||||
use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
|
||||
- content: Probe an existing node, updating its cached health state.
|
||||
id: probe-an-existing-node-updating-its-cached-health-state
|
||||
- content: >-
|
||||
Trigger the official panel self-updater on each given node (downloads
|
||||
the latest release and restarts). Only enabled, online nodes are
|
||||
updated; offline/disabled ones are reported as skipped. Set "dev":
|
||||
true to move the nodes to the rolling per-commit dev channel instead
|
||||
of the latest stable release. Returns a per-node result list.
|
||||
id: >-
|
||||
trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
|
||||
- content: >-
|
||||
Aggregated metric history for a node — same shape as /server/history,
|
||||
scoped to one node.
|
||||
id: >-
|
||||
aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/nodes/list","method":"get"},{"path":"/panel/api/nodes/mtls/ca","method":"post"},{"path":"/panel/api/nodes/mtls/trustCA","method":"post"},{"path":"/panel/api/nodes/get/{id}","method":"get"},{"path":"/panel/api/nodes/webCert/{id}","method":"get"},{"path":"/panel/api/nodes/add","method":"post"},{"path":"/panel/api/nodes/update/{id}","method":"post"},{"path":"/panel/api/nodes/del/{id}","method":"post"},{"path":"/panel/api/nodes/setEnable/{id}","method":"post"},{"path":"/panel/api/nodes/test","method":"post"},{"path":"/panel/api/nodes/certFingerprint","method":"post"},{"path":"/panel/api/nodes/inbounds","method":"post"},{"path":"/panel/api/nodes/probe/{id}","method":"post"},{"path":"/panel/api/nodes/updatePanel","method":"post"},{"path":"/panel/api/nodes/history/{id}/{metric}/{bucket}","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
---
|
||||
title: Server
|
||||
description: >-
|
||||
System status, log retrieval, certificate generators, Xray binary management,
|
||||
and backup/restore. All under /panel/api/server.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
|
||||
averages, open connections, Xray state. Cached and refreshed every 2
|
||||
seconds in the background.
|
||||
url: >-
|
||||
#real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reports whether per-client IP limits can be enforced on this host. The
|
||||
panel uses it to gate the "IP Limit" field, since enforcement depends on
|
||||
Fail2ban being installed.
|
||||
url: >-
|
||||
#reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead — same
|
||||
data with a uniform {t, v} shape.
|
||||
url: >-
|
||||
#legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
|
||||
- depth: 2
|
||||
title: >-
|
||||
Aggregated time-series for one metric. Returns an array of {t, v}
|
||||
samples covering the last ~6 hours.
|
||||
url: >-
|
||||
#aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
|
||||
- depth: 2
|
||||
title: >-
|
||||
Xray runtime metrics state — whether the xray config has a `metrics`
|
||||
block, which expvar keys are flowing, and the current snapshot values
|
||||
for each. Returns an empty state when metrics are not configured.
|
||||
url: >-
|
||||
#xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
|
||||
- depth: 2
|
||||
title: >-
|
||||
Time-series history for one Xray runtime metric over the last ~6 hours.
|
||||
Same {t, v} shape as /history/:metric/:bucket.
|
||||
url: >-
|
||||
#time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
|
||||
- depth: 2
|
||||
title: >-
|
||||
Latest snapshot from the Xray observatory — per-outbound latency, health
|
||||
status, and last-probe time. Only populated when the Xray config has an
|
||||
observatory configured.
|
||||
url: >-
|
||||
#latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
|
||||
- depth: 2
|
||||
title: >-
|
||||
Time-series of observatory probe results for one outbound tag. Same {t,
|
||||
v} shape as the other history endpoints.
|
||||
url: >-
|
||||
#time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
||||
- depth: 2
|
||||
title: List Xray binary versions available for install on this host.
|
||||
url: '#list-xray-binary-versions-available-for-install-on-this-host'
|
||||
- depth: 2
|
||||
title: Check whether a newer 3x-ui release is available on GitHub.
|
||||
url: '#check-whether-a-newer-3x-ui-release-is-available-on-github'
|
||||
- depth: 2
|
||||
title: Return the assembled Xray config that’s currently running on this host.
|
||||
url: '#return-the-assembled-xray-config-thats-currently-running-on-this-host'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Stream the SQLite database file as an attachment. Use as a manual
|
||||
backup.
|
||||
url: '#stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Stream a cross-engine migration file as an attachment: a .dump (SQL
|
||||
text) on SQLite, or a .db SQLite database built from the live data on
|
||||
PostgreSQL.
|
||||
url: >-
|
||||
#stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
|
||||
- depth: 2
|
||||
title: Generate a fresh UUID v4. Convenience helper for client IDs.
|
||||
url: '#generate-a-fresh-uuid-v4-convenience-helper-for-client-ids'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return this panel's own web TLS certificate and key file paths. The
|
||||
central panel calls it on a node (via the node API token) so "Set Cert
|
||||
from Panel" fills a node-assigned inbound with paths that exist on the
|
||||
node.
|
||||
url: >-
|
||||
#return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Read-only summaries (guid, parentGuid, name, address, status, versions)
|
||||
of the nodes this panel manages. A parent panel calls it on a node (via
|
||||
the node API token) to surface transitive sub-nodes in a chained
|
||||
topology. Counts are computed by the parent, not returned here.
|
||||
url: >-
|
||||
#read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
|
||||
- depth: 2
|
||||
title: Generate a new X25519 keypair for Reality.
|
||||
url: '#generate-a-new-x25519-keypair-for-reality'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
|
||||
{privateKey, publicKey, seed}.
|
||||
url: >-
|
||||
#generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
|
||||
{clientKey, serverKey}.
|
||||
url: >-
|
||||
#generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate VLESS encryption auth options. Returns an auths array each with
|
||||
id, label, encryption, and decryption fields.
|
||||
url: >-
|
||||
#generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
|
||||
- depth: 2
|
||||
title: Stop the Xray binary. All proxies go offline immediately.
|
||||
url: '#stop-the-xray-binary-all-proxies-go-offline-immediately'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reload Xray with the current config. Typically required after structural
|
||||
inbound or routing changes.
|
||||
url: >-
|
||||
#reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
|
||||
- depth: 2
|
||||
title: >-
|
||||
Download and install the specified Xray version. Pass "latest" for the
|
||||
newest release.
|
||||
url: >-
|
||||
#download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
|
||||
- depth: 2
|
||||
title: >-
|
||||
Self-update the panel to the latest version. The server restarts on
|
||||
success.
|
||||
url: >-
|
||||
#self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle the panel update channel between stable and the rolling
|
||||
per-commit dev release. Only effective on dev builds.
|
||||
url: >-
|
||||
#toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Refresh the default GeoIP / GeoSite data files. Body can include a
|
||||
fileName, or use the /:fileName variant.
|
||||
url: >-
|
||||
#refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
|
||||
- depth: 2
|
||||
title: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
|
||||
url: '#refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat'
|
||||
- depth: 2
|
||||
title: Return the last N lines of the panel’s own log.
|
||||
url: '#return-the-last-n-lines-of-the-panels-own-log'
|
||||
- depth: 2
|
||||
title: Return the last N lines of the Xray process log.
|
||||
url: '#return-the-last-n-lines-of-the-xray-process-log'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Restore the panel DB from an uploaded SQLite file (multipart form, field
|
||||
name "db"). The panel restarts after restore. Destructive.
|
||||
url: >-
|
||||
#restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ECH (Encrypted Client Hello) keypair and config list for
|
||||
the given SNI.
|
||||
url: >-
|
||||
#generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
|
||||
- depth: 2
|
||||
title: >-
|
||||
Compute the hex SHA-256 of a certificate (DER) for pinning
|
||||
(pinnedPeerCertSha256). Provide either a server file path or inline
|
||||
PEM/DER content.
|
||||
url: >-
|
||||
#compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
|
||||
- depth: 2
|
||||
title: >-
|
||||
Run `xray tls ping` against a remote server and return its live
|
||||
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
|
||||
url: >-
|
||||
#run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch the fully aggregated inbound_client_ips database table. Used by
|
||||
nodes to sync recently active IPs across the cluster.
|
||||
url: >-
|
||||
#fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
|
||||
- depth: 2
|
||||
title: >-
|
||||
Submit a list of recently active IP timestamps. The panel merges them
|
||||
with the existing database to maintain a unified global IP-limit view.
|
||||
url: >-
|
||||
#submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
|
||||
averages, open connections, Xray state. Cached and refreshed every 2
|
||||
seconds in the background.
|
||||
id: >-
|
||||
real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
|
||||
- content: >-
|
||||
Reports whether per-client IP limits can be enforced on this host. The
|
||||
panel uses it to gate the "IP Limit" field, since enforcement depends
|
||||
on Fail2ban being installed.
|
||||
id: >-
|
||||
reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
|
||||
- content: >-
|
||||
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead —
|
||||
same data with a uniform {t, v} shape.
|
||||
id: >-
|
||||
legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
|
||||
- content: >-
|
||||
Aggregated time-series for one metric. Returns an array of {t, v}
|
||||
samples covering the last ~6 hours.
|
||||
id: >-
|
||||
aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
|
||||
- content: >-
|
||||
Xray runtime metrics state — whether the xray config has a `metrics`
|
||||
block, which expvar keys are flowing, and the current snapshot values
|
||||
for each. Returns an empty state when metrics are not configured.
|
||||
id: >-
|
||||
xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
|
||||
- content: >-
|
||||
Time-series history for one Xray runtime metric over the last ~6
|
||||
hours. Same {t, v} shape as /history/:metric/:bucket.
|
||||
id: >-
|
||||
time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
|
||||
- content: >-
|
||||
Latest snapshot from the Xray observatory — per-outbound latency,
|
||||
health status, and last-probe time. Only populated when the Xray
|
||||
config has an observatory configured.
|
||||
id: >-
|
||||
latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
|
||||
- content: >-
|
||||
Time-series of observatory probe results for one outbound tag. Same
|
||||
{t, v} shape as the other history endpoints.
|
||||
id: >-
|
||||
time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
||||
- content: List Xray binary versions available for install on this host.
|
||||
id: list-xray-binary-versions-available-for-install-on-this-host
|
||||
- content: Check whether a newer 3x-ui release is available on GitHub.
|
||||
id: check-whether-a-newer-3x-ui-release-is-available-on-github
|
||||
- content: >-
|
||||
Return the assembled Xray config that’s currently running on this
|
||||
host.
|
||||
id: return-the-assembled-xray-config-thats-currently-running-on-this-host
|
||||
- content: >-
|
||||
Stream the SQLite database file as an attachment. Use as a manual
|
||||
backup.
|
||||
id: >-
|
||||
stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup
|
||||
- content: >-
|
||||
Stream a cross-engine migration file as an attachment: a .dump (SQL
|
||||
text) on SQLite, or a .db SQLite database built from the live data on
|
||||
PostgreSQL.
|
||||
id: >-
|
||||
stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
|
||||
- content: Generate a fresh UUID v4. Convenience helper for client IDs.
|
||||
id: generate-a-fresh-uuid-v4-convenience-helper-for-client-ids
|
||||
- content: >-
|
||||
Return this panel's own web TLS certificate and key file paths. The
|
||||
central panel calls it on a node (via the node API token) so "Set Cert
|
||||
from Panel" fills a node-assigned inbound with paths that exist on the
|
||||
node.
|
||||
id: >-
|
||||
return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
|
||||
- content: >-
|
||||
Read-only summaries (guid, parentGuid, name, address, status,
|
||||
versions) of the nodes this panel manages. A parent panel calls it on
|
||||
a node (via the node API token) to surface transitive sub-nodes in a
|
||||
chained topology. Counts are computed by the parent, not returned
|
||||
here.
|
||||
id: >-
|
||||
read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
|
||||
- content: Generate a new X25519 keypair for Reality.
|
||||
id: generate-a-new-x25519-keypair-for-reality
|
||||
- content: >-
|
||||
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
|
||||
{privateKey, publicKey, seed}.
|
||||
id: >-
|
||||
generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
|
||||
- content: >-
|
||||
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
|
||||
{clientKey, serverKey}.
|
||||
id: >-
|
||||
generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
|
||||
- content: >-
|
||||
Generate VLESS encryption auth options. Returns an auths array each
|
||||
with id, label, encryption, and decryption fields.
|
||||
id: >-
|
||||
generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
|
||||
- content: Stop the Xray binary. All proxies go offline immediately.
|
||||
id: stop-the-xray-binary-all-proxies-go-offline-immediately
|
||||
- content: >-
|
||||
Reload Xray with the current config. Typically required after
|
||||
structural inbound or routing changes.
|
||||
id: >-
|
||||
reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
|
||||
- content: >-
|
||||
Download and install the specified Xray version. Pass "latest" for the
|
||||
newest release.
|
||||
id: >-
|
||||
download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
|
||||
- content: >-
|
||||
Self-update the panel to the latest version. The server restarts on
|
||||
success.
|
||||
id: >-
|
||||
self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
|
||||
- content: >-
|
||||
Toggle the panel update channel between stable and the rolling
|
||||
per-commit dev release. Only effective on dev builds.
|
||||
id: >-
|
||||
toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
|
||||
- content: >-
|
||||
Refresh the default GeoIP / GeoSite data files. Body can include a
|
||||
fileName, or use the /:fileName variant.
|
||||
id: >-
|
||||
refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
|
||||
- content: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
|
||||
id: refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat
|
||||
- content: Return the last N lines of the panel’s own log.
|
||||
id: return-the-last-n-lines-of-the-panels-own-log
|
||||
- content: Return the last N lines of the Xray process log.
|
||||
id: return-the-last-n-lines-of-the-xray-process-log
|
||||
- content: >-
|
||||
Restore the panel DB from an uploaded SQLite file (multipart form,
|
||||
field name "db"). The panel restarts after restore. Destructive.
|
||||
id: >-
|
||||
restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
|
||||
- content: >-
|
||||
Generate a new ECH (Encrypted Client Hello) keypair and config list
|
||||
for the given SNI.
|
||||
id: >-
|
||||
generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
|
||||
- content: >-
|
||||
Compute the hex SHA-256 of a certificate (DER) for pinning
|
||||
(pinnedPeerCertSha256). Provide either a server file path or inline
|
||||
PEM/DER content.
|
||||
id: >-
|
||||
compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
|
||||
- content: >-
|
||||
Run `xray tls ping` against a remote server and return its live
|
||||
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
|
||||
id: >-
|
||||
run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
|
||||
- content: >-
|
||||
Fetch the fully aggregated inbound_client_ips database table. Used by
|
||||
nodes to sync recently active IPs across the cluster.
|
||||
id: >-
|
||||
fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
|
||||
- content: >-
|
||||
Submit a list of recently active IP timestamps. The panel merges them
|
||||
with the existing database to maintain a unified global IP-limit view.
|
||||
id: >-
|
||||
submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/server/status","method":"get"},{"path":"/panel/api/server/fail2banStatus","method":"get"},{"path":"/panel/api/server/cpuHistory/{bucket}","method":"get"},{"path":"/panel/api/server/history/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayMetricsState","method":"get"},{"path":"/panel/api/server/xrayMetricsHistory/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayObservatory","method":"get"},{"path":"/panel/api/server/xrayObservatoryHistory/{tag}/{bucket}","method":"get"},{"path":"/panel/api/server/getXrayVersion","method":"get"},{"path":"/panel/api/server/getPanelUpdateInfo","method":"get"},{"path":"/panel/api/server/getConfigJson","method":"get"},{"path":"/panel/api/server/getDb","method":"get"},{"path":"/panel/api/server/getMigration","method":"get"},{"path":"/panel/api/server/getNewUUID","method":"get"},{"path":"/panel/api/server/getWebCertFiles","method":"get"},{"path":"/panel/api/server/descendants","method":"get"},{"path":"/panel/api/server/getNewX25519Cert","method":"get"},{"path":"/panel/api/server/getNewmldsa65","method":"get"},{"path":"/panel/api/server/getNewmlkem768","method":"get"},{"path":"/panel/api/server/getNewVlessEnc","method":"get"},{"path":"/panel/api/server/stopXrayService","method":"post"},{"path":"/panel/api/server/restartXrayService","method":"post"},{"path":"/panel/api/server/installXray/{version}","method":"post"},{"path":"/panel/api/server/updatePanel","method":"post"},{"path":"/panel/api/server/setUpdateChannel","method":"post"},{"path":"/panel/api/server/updateGeofile","method":"post"},{"path":"/panel/api/server/updateGeofile/{fileName}","method":"post"},{"path":"/panel/api/server/logs/{count}","method":"post"},{"path":"/panel/api/server/xraylogs/{count}","method":"post"},{"path":"/panel/api/server/importDB","method":"post"},{"path":"/panel/api/server/getNewEchCert","method":"post"},{"path":"/panel/api/server/getCertHash","method":"post"},{"path":"/panel/api/server/getRemoteCertHash","method":"post"},{"path":"/panel/api/server/clientIps","method":"get"},{"path":"/panel/api/server/clientIps","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: Settings
|
||||
description: >-
|
||||
Panel configuration and user credentials. All endpoints live under
|
||||
/panel/api/setting and require a logged-in session or Bearer token.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return every panel setting: web server, Telegram bot, subscription,
|
||||
security, LDAP. The full JSON blob that the Settings page edits.
|
||||
url: >-
|
||||
#return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the computed default settings based on the request host. Useful
|
||||
to preview what a fresh install would use.
|
||||
url: >-
|
||||
#return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
|
||||
- depth: 2
|
||||
title: >-
|
||||
Persist every setting at once. The body mirrors the shape returned by
|
||||
/all. Invalid values (bad ports, missing cert pairs, etc.) are rejected
|
||||
before write.
|
||||
url: >-
|
||||
#persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Change the panel admin username and password. Requires the current
|
||||
credentials for verification. The session is refreshed with the new
|
||||
values on success.
|
||||
url: >-
|
||||
#change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
||||
- depth: 2
|
||||
title: >-
|
||||
Restart the entire 3x-ui process after a 3-second grace period. The
|
||||
connection drops immediately; the panel comes back online ~5-10 seconds
|
||||
later.
|
||||
url: >-
|
||||
#restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test SMTP connection with stage-by-stage reporting (connect, auth,
|
||||
send). Returns structured result with stage and message.
|
||||
url: >-
|
||||
#test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test Telegram bot connection by sending a test message to the configured
|
||||
chat.
|
||||
url: >-
|
||||
#test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the built-in default Xray JSON config template that ships with
|
||||
this panel version.
|
||||
url: >-
|
||||
#return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Return every panel setting: web server, Telegram bot, subscription,
|
||||
security, LDAP. The full JSON blob that the Settings page edits.
|
||||
id: >-
|
||||
return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
|
||||
- content: >-
|
||||
Return the computed default settings based on the request host. Useful
|
||||
to preview what a fresh install would use.
|
||||
id: >-
|
||||
return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
|
||||
- content: >-
|
||||
Persist every setting at once. The body mirrors the shape returned by
|
||||
/all. Invalid values (bad ports, missing cert pairs, etc.) are
|
||||
rejected before write.
|
||||
id: >-
|
||||
persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
|
||||
- content: >-
|
||||
Change the panel admin username and password. Requires the current
|
||||
credentials for verification. The session is refreshed with the new
|
||||
values on success.
|
||||
id: >-
|
||||
change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
||||
- content: >-
|
||||
Restart the entire 3x-ui process after a 3-second grace period. The
|
||||
connection drops immediately; the panel comes back online ~5-10
|
||||
seconds later.
|
||||
id: >-
|
||||
restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
||||
- content: >-
|
||||
Test SMTP connection with stage-by-stage reporting (connect, auth,
|
||||
send). Returns structured result with stage and message.
|
||||
id: >-
|
||||
test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
||||
- content: >-
|
||||
Test Telegram bot connection by sending a test message to the
|
||||
configured chat.
|
||||
id: >-
|
||||
test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
|
||||
- content: >-
|
||||
Return the built-in default Xray JSON config template that ships with
|
||||
this panel version.
|
||||
id: >-
|
||||
return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/all","method":"post"},{"path":"/panel/api/setting/defaultSettings","method":"post"},{"path":"/panel/api/setting/update","method":"post"},{"path":"/panel/api/setting/updateUser","method":"post"},{"path":"/panel/api/setting/restartPanel","method":"post"},{"path":"/panel/api/setting/testSmtp","method":"post"},{"path":"/panel/api/setting/testTgBot","method":"post"},{"path":"/panel/api/setting/getDefaultJsonConfig","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
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.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
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.
|
||||
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
|
||||
- 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
|
||||
- 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.
|
||||
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
|
||||
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.
|
||||
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
|
||||
- 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
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: WebSocket
|
||||
description: >-
|
||||
Real-time status updates via WebSocket. Connect once at
|
||||
<code>ws://<panel>/ws</code> to receive a stream of JSON messages without
|
||||
polling. Requires an authenticated session cookie (Bearer token auth is not
|
||||
supported). Each message has a <code>type</code> field that identifies the
|
||||
payload shape.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
|
||||
session cookie (Bearer token auth is not supported here). Returns 101
|
||||
Switching Protocols on success. The server then pushes JSON messages
|
||||
described below.
|
||||
url: >-
|
||||
#upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
|
||||
session cookie (Bearer token auth is not supported here). Returns 101
|
||||
Switching Protocols on success. The server then pushes JSON messages
|
||||
described below.
|
||||
id: >-
|
||||
upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/ws","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
---
|
||||
title: Xray Settings
|
||||
description: >-
|
||||
Xray configuration template, outbound management, Warp/Nord integration, and
|
||||
config testing. All endpoints under /panel/api/xray.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the Xray config template (JSON string), available inbound tags,
|
||||
client reverse tags, and the configured outbound test URL in one
|
||||
response.
|
||||
url: >-
|
||||
#return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the built-in default Xray config shipped with the panel
|
||||
(identical to /panel/api/setting/getDefaultJsonConfig).
|
||||
url: >-
|
||||
#return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return traffic statistics for every outbound. Each outbound shows
|
||||
up/down/total counters.
|
||||
url: >-
|
||||
#return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the most recent Xray process stdout/stderr output. Useful to
|
||||
check for startup errors or runtime warnings.
|
||||
url: >-
|
||||
#return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
|
||||
- depth: 2
|
||||
title: >-
|
||||
Save the Xray JSON config template and optionally the outbound test URL.
|
||||
Both are sent as form fields.
|
||||
url: >-
|
||||
#save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
|
||||
- depth: 2
|
||||
title: >-
|
||||
Manage Cloudflare Warp integration. The action parameter selects the
|
||||
operation.
|
||||
url: >-
|
||||
#manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
|
||||
- depth: 2
|
||||
title: Manage NordVPN integration. The action parameter selects the operation.
|
||||
url: '#manage-nordvpn-integration-the-action-parameter-selects-the-operation'
|
||||
- depth: 2
|
||||
title: Reset traffic counters for a specific outbound by tag.
|
||||
url: '#reset-traffic-counters-for-a-specific-outbound-by-tag'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test an outbound configuration. Sends the outbound JSON (required),
|
||||
optionally all outbounds (to resolve sockopt.dialerProxy dependencies),
|
||||
and a mode flag.
|
||||
url: >-
|
||||
#test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test a batch of outbounds (max 50) through one shared temp xray
|
||||
instance. Returns an array of results in input order, each with the
|
||||
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
|
||||
breakdown.
|
||||
url: >-
|
||||
#test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
|
||||
- depth: 2
|
||||
title: >-
|
||||
Live state of routing balancers in the running core
|
||||
(RoutingService.GetBalancerInfo): current override and the targets the
|
||||
strategy prefers. Returns a map keyed by balancer tag.
|
||||
url: >-
|
||||
#live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
|
||||
- depth: 2
|
||||
title: >-
|
||||
Force a balancer in the running core to always pick one outbound
|
||||
(RoutingService.OverrideBalancerTarget). Applied live without a restart;
|
||||
cleared automatically when Xray restarts.
|
||||
url: >-
|
||||
#force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
|
||||
- depth: 2
|
||||
title: >-
|
||||
Ask the running core which outbound its router would pick for a
|
||||
synthetic connection (RoutingService.TestRoute). No traffic is sent.
|
||||
url: >-
|
||||
#ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
|
||||
- depth: 2
|
||||
title: >-
|
||||
List all outbound subscriptions (remote URLs that supply additional
|
||||
outbounds), newest first.
|
||||
url: >-
|
||||
#list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create an outbound subscription. The URL is fetched, parsed into
|
||||
outbounds with stable tags, and merged additively into the running Xray
|
||||
config.
|
||||
url: >-
|
||||
#create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
|
||||
- depth: 2
|
||||
title: >-
|
||||
Update an existing outbound subscription by id. Accepts the same form
|
||||
fields as create.
|
||||
url: >-
|
||||
#update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
|
||||
- depth: 2
|
||||
title: Delete an outbound subscription by id.
|
||||
url: '#delete-an-outbound-subscription-by-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete an outbound subscription by id (POST alias of DELETE for
|
||||
axios-friendly clients).
|
||||
url: >-
|
||||
#delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
|
||||
- depth: 2
|
||||
title: >-
|
||||
Force an immediate re-fetch of the subscription and return the parsed
|
||||
outbounds. Signals Xray to reload.
|
||||
url: >-
|
||||
#force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reorder a subscription one step up or down in priority (controls its
|
||||
position in the merged outbounds).
|
||||
url: >-
|
||||
#reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Preview a subscription URL: fetch and parse it into outbounds without
|
||||
persisting anything.
|
||||
url: >-
|
||||
#preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Return the Xray config template (JSON string), available inbound tags,
|
||||
client reverse tags, and the configured outbound test URL in one
|
||||
response.
|
||||
id: >-
|
||||
return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
|
||||
- content: >-
|
||||
Return the built-in default Xray config shipped with the panel
|
||||
(identical to /panel/api/setting/getDefaultJsonConfig).
|
||||
id: >-
|
||||
return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
|
||||
- content: >-
|
||||
Return traffic statistics for every outbound. Each outbound shows
|
||||
up/down/total counters.
|
||||
id: >-
|
||||
return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
|
||||
- content: >-
|
||||
Return the most recent Xray process stdout/stderr output. Useful to
|
||||
check for startup errors or runtime warnings.
|
||||
id: >-
|
||||
return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
|
||||
- content: >-
|
||||
Save the Xray JSON config template and optionally the outbound test
|
||||
URL. Both are sent as form fields.
|
||||
id: >-
|
||||
save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
|
||||
- content: >-
|
||||
Manage Cloudflare Warp integration. The action parameter selects the
|
||||
operation.
|
||||
id: >-
|
||||
manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
|
||||
- content: >-
|
||||
Manage NordVPN integration. The action parameter selects the
|
||||
operation.
|
||||
id: manage-nordvpn-integration-the-action-parameter-selects-the-operation
|
||||
- content: Reset traffic counters for a specific outbound by tag.
|
||||
id: reset-traffic-counters-for-a-specific-outbound-by-tag
|
||||
- content: >-
|
||||
Test an outbound configuration. Sends the outbound JSON (required),
|
||||
optionally all outbounds (to resolve sockopt.dialerProxy
|
||||
dependencies), and a mode flag.
|
||||
id: >-
|
||||
test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
|
||||
- content: >-
|
||||
Test a batch of outbounds (max 50) through one shared temp xray
|
||||
instance. Returns an array of results in input order, each with the
|
||||
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
|
||||
breakdown.
|
||||
id: >-
|
||||
test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
|
||||
- content: >-
|
||||
Live state of routing balancers in the running core
|
||||
(RoutingService.GetBalancerInfo): current override and the targets the
|
||||
strategy prefers. Returns a map keyed by balancer tag.
|
||||
id: >-
|
||||
live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
|
||||
- content: >-
|
||||
Force a balancer in the running core to always pick one outbound
|
||||
(RoutingService.OverrideBalancerTarget). Applied live without a
|
||||
restart; cleared automatically when Xray restarts.
|
||||
id: >-
|
||||
force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
|
||||
- content: >-
|
||||
Ask the running core which outbound its router would pick for a
|
||||
synthetic connection (RoutingService.TestRoute). No traffic is sent.
|
||||
id: >-
|
||||
ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
|
||||
- content: >-
|
||||
List all outbound subscriptions (remote URLs that supply additional
|
||||
outbounds), newest first.
|
||||
id: >-
|
||||
list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
|
||||
- content: >-
|
||||
Create an outbound subscription. The URL is fetched, parsed into
|
||||
outbounds with stable tags, and merged additively into the running
|
||||
Xray config.
|
||||
id: >-
|
||||
create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
|
||||
- content: >-
|
||||
Update an existing outbound subscription by id. Accepts the same form
|
||||
fields as create.
|
||||
id: >-
|
||||
update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
|
||||
- content: Delete an outbound subscription by id.
|
||||
id: delete-an-outbound-subscription-by-id
|
||||
- content: >-
|
||||
Delete an outbound subscription by id (POST alias of DELETE for
|
||||
axios-friendly clients).
|
||||
id: >-
|
||||
delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
|
||||
- content: >-
|
||||
Force an immediate re-fetch of the subscription and return the parsed
|
||||
outbounds. Signals Xray to reload.
|
||||
id: >-
|
||||
force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
|
||||
- content: >-
|
||||
Reorder a subscription one step up or down in priority (controls its
|
||||
position in the merged outbounds).
|
||||
id: >-
|
||||
reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
|
||||
- content: >-
|
||||
Preview a subscription URL: fetch and parse it into outbounds without
|
||||
persisting anything.
|
||||
id: >-
|
||||
preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/xray/","method":"post"},{"path":"/panel/api/xray/getDefaultJsonConfig","method":"get"},{"path":"/panel/api/xray/getOutboundsTraffic","method":"get"},{"path":"/panel/api/xray/getXrayResult","method":"get"},{"path":"/panel/api/xray/update","method":"post"},{"path":"/panel/api/xray/warp/{action}","method":"post"},{"path":"/panel/api/xray/nord/{action}","method":"post"},{"path":"/panel/api/xray/resetOutboundsTraffic","method":"post"},{"path":"/panel/api/xray/testOutbound","method":"post"},{"path":"/panel/api/xray/testOutbounds","method":"post"},{"path":"/panel/api/xray/balancerStatus","method":"post"},{"path":"/panel/api/xray/balancerOverride","method":"post"},{"path":"/panel/api/xray/routeTest","method":"post"},{"path":"/panel/api/xray/outbound-subs","method":"get"},{"path":"/panel/api/xray/outbound-subs","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"delete"},{"path":"/panel/api/xray/outbound-subs/{id}/del","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/refresh","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/move","method":"post"},{"path":"/panel/api/xray/outbound-subs/parse","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: Database
|
||||
description: 3x-ui storage backends — SQLite (default) and PostgreSQL — the database path, connection pool, and SQLite-to-PostgreSQL migration.
|
||||
icon: Database
|
||||
---
|
||||
|
||||
3x-ui stores everything — inbounds, clients, settings — in a database. You choose
|
||||
the backend at install time; both are first-class.
|
||||
|
||||
## SQLite (default)
|
||||
|
||||
A single file at `/etc/x-ui/x-ui.db`. Zero setup, ideal for small and medium
|
||||
deployments. The folder is configurable with
|
||||
[`XUI_DB_FOLDER`](/docs/reference/env-vars#database) (on Windows it defaults next
|
||||
to the binary).
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
Recommended for high client counts or multi-node setups. The installer can
|
||||
install PostgreSQL locally for you, or accept a DSN to an existing server. At
|
||||
runtime the backend is selected via environment variables, which the installer
|
||||
writes to `/etc/default/x-ui`:
|
||||
|
||||
```bash title="/etc/default/x-ui"
|
||||
XUI_DB_TYPE=postgres
|
||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||
```
|
||||
|
||||
Tune the connection pool with `XUI_DB_MAX_OPEN_CONNS` and
|
||||
`XUI_DB_MAX_IDLE_CONNS`.
|
||||
|
||||
### Docker
|
||||
|
||||
`docker compose up -d` keeps using SQLite. To run with the bundled PostgreSQL
|
||||
service, uncomment the two `XUI_DB_*` lines in `docker-compose.yml` and start
|
||||
with the profile:
|
||||
|
||||
```bash
|
||||
docker compose --profile postgres up -d
|
||||
```
|
||||
|
||||
## Migrate SQLite → PostgreSQL
|
||||
|
||||
Move an existing SQLite install to PostgreSQL with the built-in command:
|
||||
|
||||
```bash
|
||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||
```
|
||||
|
||||
Then set `XUI_DB_TYPE` and `XUI_DB_DSN` in `/etc/default/x-ui` and restart:
|
||||
|
||||
```bash
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
The source SQLite file is left untouched — remove it manually only after you've
|
||||
verified the new backend works.
|
||||
</Callout>
|
||||
|
||||
## Backups
|
||||
|
||||
Whichever backend you use, back it up regularly — see
|
||||
[Backup & restore](/docs/operations/backup-restore).
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: Environment Variables
|
||||
description: Complete reference for 3x-ui's XUI_* environment variables — database, panel, logging, memory, and the tunnel health monitor.
|
||||
icon: Variable
|
||||
---
|
||||
|
||||
3x-ui reads its runtime configuration from `XUI_*` environment variables. On a
|
||||
script install the installer writes them to the service environment file
|
||||
(`/etc/default/x-ui`, or `/etc/conf.d/x-ui` / `/etc/sysconfig/x-ui` depending on
|
||||
the distro); for Docker you set them in `docker-compose.yml` or `docker run -e`.
|
||||
Defaults are sensible — set only what you need to change, then restart:
|
||||
`systemctl restart x-ui`.
|
||||
|
||||
## Database
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ----------- | -------------------------------------------------------------------- |
|
||||
| `XUI_DB_TYPE` | `sqlite` | Backend: `sqlite`, or `postgres` (also accepts `postgresql` / `pg`). |
|
||||
| `XUI_DB_FOLDER` | `/etc/x-ui` | Folder for the SQLite database file (`x-ui.db`). |
|
||||
| `XUI_DB_DSN` | — | PostgreSQL connection string (used when `XUI_DB_TYPE=postgres`). |
|
||||
| `XUI_DB_MAX_OPEN_CONNS` | — | Max open connections in the PostgreSQL pool. |
|
||||
| `XUI_DB_MAX_IDLE_CONNS` | — | Max idle connections in the PostgreSQL pool. |
|
||||
|
||||
The default SQLite database path is `/etc/x-ui/x-ui.db`. See
|
||||
[Database](/docs/reference/database) for the SQLite ↔ PostgreSQL details.
|
||||
|
||||
## Panel
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ------- | ------------------------------------------------------------------------ |
|
||||
| `XUI_PORT` | — | Override the panel port (1–65535). Takes precedence over the stored setting. |
|
||||
| `XUI_INIT_WEB_BASE_PATH` | `/` | Initial web base path on **first** launch (e.g. `/panel`). |
|
||||
| `XUI_ENABLE_FAIL2BAN` | `true` | Enable Fail2ban-based IP-limit enforcement. |
|
||||
| `XUI_SKIP_HSTS` | `false` | Skip the HSTS header — set `true` when TLS is terminated by a reverse proxy. |
|
||||
|
||||
## Logging & binaries
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ---------------- | ---------------- | ----------------------------------------------------------- |
|
||||
| `XUI_LOG_LEVEL` | `info` | `debug`, `info`, `notice`, `warning`, or `error`. |
|
||||
| `XUI_DEBUG` | `false` | Debug mode (forces log level to `debug`). |
|
||||
| `XUI_LOG_FOLDER` | `/var/log/x-ui` | Log output directory. |
|
||||
| `XUI_BIN_FOLDER` | `bin` | Folder for the Xray-core binary and geosite/geoip files. |
|
||||
|
||||
## Memory & profiling
|
||||
|
||||
The panel keeps memory low via `GOGC` and periodic releases. These are advanced
|
||||
knobs — leave them unset unless you're tuning a constrained host.
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ----------------------------- | ------- | ----------------------------------------------------------------- |
|
||||
| `XUI_GOGC` | — | Go GC target percentage; lower = less RAM, slightly more CPU. |
|
||||
| `XUI_MEMORY_RELEASE_INTERVAL` | — | Minutes between `FreeOSMemory` calls; `0` disables. |
|
||||
| `XUI_MEMORY_LIMIT` | — | Go soft memory limit in **MiB**. |
|
||||
| `GOMEMLIMIT` | — | Go-syntax soft limit (e.g. `400MiB`); takes precedence over above.|
|
||||
| `XUI_PPROF` | `false` | Expose pprof profiling on `127.0.0.1:6060`. |
|
||||
|
||||
## Xray
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ------- | --------------------- |
|
||||
| `XRAY_VMESS_AEAD_FORCED` | `false` | Force VMess AEAD. |
|
||||
|
||||
## Tunnel health monitor
|
||||
|
||||
Optional watchdog: it probes a URL (optionally **through** a local Xray inbound)
|
||||
and restarts Xray after repeated failures. A restart drops all connected
|
||||
clients, so enable it deliberately.
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ----------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `XUI_TUNNEL_HEALTH_MONITOR` | `false` | Enable the monitor. |
|
||||
| `XUI_TUNNEL_HEALTH_PROXY` | — | Proxy to send the probe through, e.g. `socks5://127.0.0.1:1080`. Empty = only checks host connectivity. |
|
||||
| `XUI_TUNNEL_HEALTH_URL` | `https://www.cloudflare.com/cdn-cgi/trace` | URL to probe. |
|
||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | `30s` | Interval between probes. |
|
||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | `10s` | Per-probe timeout. |
|
||||
| `XUI_TUNNEL_HEALTH_FAILURES` | `3` | Consecutive failures before a restart. |
|
||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | `5m` | Minimum delay between restarts. |
|
||||
|
||||
## Unattended install
|
||||
|
||||
| Variable | Description |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `XUI_NONINTERACTIVE` | Set to `1` (or run with no TTY) to install with zero prompts; generated credentials are written to `/etc/x-ui/install-result.env`. See [Installation](/docs/guide/installation#unattended--cloud-init). |
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Reference",
|
||||
"icon": "BookMarked",
|
||||
"pages": ["env-vars", "database", "ports-firewall", "api"]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Ports & Firewall
|
||||
description: The ports 3x-ui uses by default and ready-made ufw / nftables rules to open them.
|
||||
icon: Network
|
||||
---
|
||||
|
||||
Open only the ports you actually use. Below are the common ones and a generator
|
||||
for `ufw` and `nftables` rules.
|
||||
|
||||
## Common ports
|
||||
|
||||
| Port (default) | Purpose |
|
||||
| -------------- | ----------------------------------------- |
|
||||
| `22` | SSH (keep this open!). |
|
||||
| `2053` | Panel (configurable). |
|
||||
| `2096` | Subscription server (if separate). |
|
||||
| `443` | A common inbound port (TLS / REALITY). |
|
||||
| `80` / `443` | Reverse proxy (if you run one). |
|
||||
|
||||
Your actual inbound ports depend on the inbounds you create.
|
||||
|
||||
## Generate firewall rules
|
||||
|
||||
<FirewallRulesGenerator />
|
||||
|
||||
<Callout type="warn">
|
||||
Always keep SSH allowed before enabling a default-deny policy, and test from a
|
||||
second session so you don't lock yourself out.
|
||||
</Callout>
|
||||
|
||||
## Related
|
||||
|
||||
<Cards>
|
||||
<Card title="Security" href="/docs/operations/security" description="Fail2ban, IP limits, and hardening." />
|
||||
<Card title="Environment variables" href="/docs/reference/env-vars" description="XUI_PORT and friends." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: کلاینتها
|
||||
description: مدیریت کلاینتهای 3x-ui — اعتبارنامهها، محدودیت ترافیک و انقضا، محدودیت IP، گروهها، اقدامات گروهی، لینکهای خارجی و وضعیت آنلاین.
|
||||
icon: Users
|
||||
---
|
||||
|
||||
یک **کلاینت** یک کاربر منفرد است که با یک **ایمیل** یکتا شناسایی میشود. در پنل
|
||||
فعلی، کلاینتها رکوردهای درجهیک هستند که میتوانند همزمان به **چندین ورودی**
|
||||
متصل شوند و حسابداری ترافیک بهصورت جداگانه برای هر کلاینت انجام میشود.
|
||||
|
||||
## فیلدهای کلاینت
|
||||
|
||||
| فیلد | اعمال بر | معنی |
|
||||
| -------------- | --------------------- | ------------------------------------------------------------------ |
|
||||
| **Email** | همه | شناسهی یکتا که برای حسابداری و جستوجوها استفاده میشود. |
|
||||
| **ID (UUID)** | VLESS, VMess | اعتبارنامهی کلاینت. |
|
||||
| **Password** | Trojan, Shadowsocks | اعتبارنامهی کلاینت. |
|
||||
| **Auth** | Hysteria2 | اعتبارنامهی کلاینت. |
|
||||
| **Flow** | VLESS | جریان XTLS، برای مثال `xtls-rprx-vision`. |
|
||||
| **Limit IP** | همه | بیشینهی تعداد IPهای مبدأ همزمان (با Fail2ban اعمال میشود). |
|
||||
| **Total (GB)** | همه | سهمیهی ترافیک؛ هنگام اتمام، کلاینت غیرفعال میشود. |
|
||||
| **Expiry** | همه | تاریخی که پس از آن کلاینت از کار میافتد. |
|
||||
| **Reset** | همه | دورهی تمدید خودکار به **روز** (سهمیه را از نو میچرخاند). |
|
||||
| **Telegram ID**| همه | کلاینت را به یک کاربر Telegram برای سلفسرویس/اعلانها پیوند میدهد.|
|
||||
| **Sub ID** | همه | شناسهی اشتراک که لینکهای این کلاینت را گروهبندی میکند. |
|
||||
| **Group** | همه | گروه اختیاری کلاینت برای سازماندهی و فیلترکردن گروهی. |
|
||||
| **Comment** | همه | یادداشت متنی آزاد. |
|
||||
|
||||
<Callout type="info">
|
||||
رسیدن به محدودیت **ترافیک** یا **انقضا** کلاینت را غیرفعال میکند؛ پنل میتواند
|
||||
هنگام غیرفعالشدن خودکار کلاینتها، Xray را بهصورت خودکار راهاندازی مجدد کند
|
||||
(`restartXrayOnClientDisable`، بهصورت پیشفرض فعال).
|
||||
</Callout>
|
||||
|
||||
## محدودیتها و کنترل IP
|
||||
|
||||
- سقفهای **ترافیک / انقضا** هنگام رسیدن، کلاینت را غیرفعال میکنند؛ یک دورهی
|
||||
**Reset** سهمیه را بهصورت خودکار تمدید میکند.
|
||||
- **Limit IP** تعداد IPهای مبدأ همزمان را محدود میکند. اعمال آن به Fail2ban متکی
|
||||
است — به [امنیت](/docs/operations/security) مراجعه کنید. میتوانید IPهای اخیر یک
|
||||
کلاینت را مشاهده کرده و آنها را از بخش اقدامات کلاینت پاک کنید.
|
||||
- **وضعیت آنلاین** و زمانهای **آخرینبار آنلاین** برای هر کلاینت (و در پیکربندیهای
|
||||
چندنودی برای هر نود) ثبت میشوند.
|
||||
|
||||
## لینکهای اشتراکگذاری و لینکهای خارجی
|
||||
|
||||
هر کلاینت برای ورودیهایش لینکهای اشتراکگذاری و یک کد QR دارد، بهعلاوهی یک
|
||||
[اشتراک](/docs/config/subscription) ترکیبی. همچنین میتوانید **لینکهای خارجی** به
|
||||
یک کلاینت متصل کنید — لینکهای اضافی `vless://`، `vmess://`، `trojan://`، `ss://`،
|
||||
`hysteria2://` یا `wireguard://`، یا یک URL اشتراک از راه دور — تا در کنار
|
||||
لینکهای تولیدشده توسط پنل، در اشتراک کلاینت نمایش داده شوند.
|
||||
|
||||
برای بررسی دقیق محتویات یک لینک، آن را در
|
||||
[بازرس لینک اشتراکگذاری](/docs/config/share-links) جایگذاری کنید.
|
||||
|
||||
## اقدامات گروهی
|
||||
|
||||
برای مدیریت همزمان تعداد زیادی کلاینت، پنل از اقدامات گروهی **ساخت، فعالسازی،
|
||||
غیرفعالسازی، حذف، اتصال/قطع اتصال** (به ورودیها)، **بازنشانی ترافیک** و
|
||||
**تنظیم** (افزودن روز / افزودن بایت / تعیین flow) پشتیبانی میکند. اقدامات
|
||||
نگهداری همچنین به شما امکان میدهند کلاینتهای **تمامشده** (سهمیه/انقضای پایانیافته)
|
||||
و کلاینتهای **یتیم** (متصلنشده به هیچ ورودی) را حذف کنید.
|
||||
|
||||
<Callout type="warn">
|
||||
لینک اشتراکگذاری یک کلاینت حاوی اعتبارنامهی آن است. با لینکها و کدهای QR مانند
|
||||
رمز عبور رفتار کنید و در صورت نشت یکی از آنها، اعتبارنامه را تعویض کنید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: ورودیها و پروتکلها
|
||||
description: ساخت ورودیها در 3x-ui — پروتکلها، انتقالها، بازنشانی و انقضای ترافیک، و fallbackهایی که چند پروتکل را روی یک پورت سرویس میدهند.
|
||||
icon: ArrowDownToLine
|
||||
---
|
||||
|
||||
یک **ورودی (inbound)** شنوندهای است که اتصالهای کلاینت را روی یک پورت با
|
||||
پروتکل و انتقال مشخصی میپذیرد. بیشتر کارهای روزمره شما ساخت و مدیریت ورودیها و
|
||||
کلاینتهای درون آنهاست.
|
||||
|
||||
## ساخت یک ورودی
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### افزودن یک ورودی
|
||||
|
||||
به **Inbounds → Add** بروید، یک توضیح (remark) برای آن بگذارید، یک **پروتکل**
|
||||
انتخاب کنید، و یک **پورت** و آدرس شنود انتخاب کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### انتخاب انتقال و امنیت
|
||||
|
||||
انتقال (TCP، WebSocket، gRPC، HTTPUpgrade، XHTTP، …) و لایه امنیتی (هیچکدام،
|
||||
TLS یا REALITY) را انتخاب کنید. به [انتقالها](/docs/config/transports) و
|
||||
[REALITY](/docs/config/reality) مراجعه کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### افزودن کلاینتها
|
||||
|
||||
یک یا چند کلاینت اضافه کنید که هر کدام اعتبارنامه، محدودیتها و لینک اشتراک
|
||||
خودش را دارد. به [کلاینتها](/docs/config/clients) مراجعه کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### تنظیم محدودیت ترافیک، انقضا و بازنشانی
|
||||
|
||||
بهصورت اختیاری میتوانید کل ترافیک را محدود کنید و یک تاریخ انقضا برای ورودی
|
||||
تعیین کنید، و یک زمانبندی **بازنشانی ترافیک** دورهای انتخاب کنید: `never`
|
||||
(پیشفرض)، `hourly`، `daily`، `weekly` یا `monthly`.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## پروتکلهای پشتیبانیشده
|
||||
|
||||
ویرایشگر ورودی این پروتکلها را میپذیرد:
|
||||
|
||||
| پروتکل | توضیحات |
|
||||
| ---------------------- | ------------------------------------------------------------------------ |
|
||||
| **VLESS** | سبک؛ پایهی REALITY + XTLS-Vision. توصیهشده. |
|
||||
| **VMess** | قدیمیتر اما با پشتیبانی بسیار گسترده در کلاینتها. |
|
||||
| **Trojan** | مبتنی بر TLS؛ از XTLS و fallback پشتیبانی میکند. |
|
||||
| **Shadowsocks** | شامل رمزهای Shadowsocks-2022 (`2022-blake3-*`). |
|
||||
| **WireGuard** | تونل مدرن. |
|
||||
| **Hysteria2** | با عنوان `hysteria` انتخاب میشود؛ پنل لینکهای `hysteria2://` تولید میکند. |
|
||||
| **HTTP** | پراکسی HTTP. |
|
||||
| **Mixed (SOCKS/HTTP)** | یک شنونده ترکیبی SOCKS + HTTP. |
|
||||
| **Dokodemo-door / Tunnel** | فورواردینگ پورت / هدایت ترافیک. |
|
||||
| **MTProto** | پراکسی MTProto تلگرام که توسط یک فرایند همراه `mtg` سرویس میشود (نه Xray). |
|
||||
|
||||
<Callout type="info">
|
||||
Hysteria2 در سطح داخلی یک پروتکل جداگانه نیست — همان پروتکل `hysteria` است که
|
||||
نسخه انتقال آن روی ۲ تنظیم شده، و پنل برای آن لینکهای اشتراک `hysteria2://`
|
||||
تولید میکند.
|
||||
</Callout>
|
||||
|
||||
## Fallbackها — چند پروتکل روی یک پورت
|
||||
|
||||
Fallbackها به یک پورت TLS واحد (مثلاً `443`) اجازه میدهند بیش از یک پروتکل را
|
||||
سرویس دهد — برای مثال VLESS **و** Trojan — با هدایت دستدادنهای (handshake)
|
||||
ناهماهنگ به یک ورودی فرزند. در 3x-ui، fallbackها در پنل مدیریت میشوند (لیست
|
||||
**Fallbacks** یک ورودی اصلی) بهجای آنکه بهصورت دستی در JSON نوشته شوند.
|
||||
|
||||
Fallbackها تنها زمانی در دسترساند که ورودی اصلی اینگونه باشد:
|
||||
|
||||
- **VLESS** یا **Trojan**،
|
||||
- روی انتقال خام **TCP**،
|
||||
- با امنیت **TLS** یا **REALITY**.
|
||||
|
||||
هر قاعده fallback یک ورودی فرزند را هدف قرار میدهد و میتواند بر اساس `path`،
|
||||
`alpn` و `dest` تطبیق یابد. لینکهای اشتراک کلاینت برای یک فرزند fallback
|
||||
بهصورت خودکار بازنویسی میشوند تا آدرس، پورت و TLS ورودی اصلی را اعلام کنند.
|
||||
|
||||
## مطمئن نیستید کدام را انتخاب کنید؟
|
||||
|
||||
از این جادوگر استفاده کنید تا بر اساس اهداف و کلاینتهایتان یک پیشنهاد دریافت کنید:
|
||||
|
||||
<ProtocolWizard />
|
||||
|
||||
<Callout type="info">
|
||||
برای مقاومت در برابر سانسور با کلاینتهای مدرن، **VLESS + REALITY +
|
||||
XTLS-Vision** معمولاً بهترین انتخاب است — به
|
||||
[REALITY](/docs/config/reality) ادامه دهید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "پیکربندی",
|
||||
"icon": "Settings",
|
||||
"pages": [
|
||||
"panel",
|
||||
"ssl-certificates",
|
||||
"inbounds",
|
||||
"reality",
|
||||
"transports",
|
||||
"clients",
|
||||
"subscription",
|
||||
"share-links"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: تنظیمات پنل
|
||||
description: تمام تنظیمات پنل 3x-ui — وبسرور، TLS، نمایش، امنیت و اعلانها — همراه با مقادیر پیشفرض برگرفته از سورس.
|
||||
icon: SlidersHorizontal
|
||||
---
|
||||
|
||||
**تنظیمات پنل** نحوهی ارائه و ایمنسازی خودِ پنل را کنترل میکند (جدا از ورودیها
|
||||
و کلاینتهای شما). تنظیمات بهصورت جفتهای کلید/مقدار ذخیره میشوند؛ مقادیر
|
||||
پیشفرض زیر مستقیماً از سورس پنل گرفته شدهاند. اطلاعات محرمانه (توکنها، گذرواژهها)
|
||||
فقط با نشانگرِ «تنظیمشده / تنظیمنشده» نمایش داده میشوند و هرگز بهصورت کامل به
|
||||
مرورگر بازگردانده نمیشوند.
|
||||
|
||||
## وبسرور
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
||||
| `webPort` | `2053` | پورت پنل (۱ تا ۶۵۵۳۵). متغیر محیطی `XUI_PORT` در زمان اجرا آن را بازنویسی میکند. |
|
||||
| `webListen` | _(همهی واسطها)_ | پنل را به یک IP مشخص مقید کنید. |
|
||||
| `webBasePath` | `/` | مسیر URLی که پنل زیر آن ارائه میشود (همیشه به شکل `/…/` نرمالسازی میشود). |
|
||||
| `webCertFile` / `webKeyFile` | _(هیچکدام)_ | گواهی + کلید TLS. وقتی هر دو تنظیم شوند، پنل با **HTTPS** ارائه میشود. |
|
||||
| `sessionMaxAge` | `360` | طول عمر نشست بر حسب **دقیقه** (پیشفرض ۶ ساعت). |
|
||||
| `trustedProxyCIDRs` | `127.0.0.1/32,::1/128` | IPها/CIDRهایی که هدرهای فورواردشدهشان (IP واقعی کلاینت) مورد اعتماد است. |
|
||||
| `panelOutbound` | _(هیچکدام)_ | مسیریابی خروجیِ خود پنل (بررسی بهروزرسانیها، Telegram، واکشی geo/sub) از طریق یک خروجی Xray با نام مشخص. |
|
||||
|
||||
پس از تغییر پورت یا مسیر پایه، آدرس پنل بهصورت
|
||||
`http(s)://<server>:<port><web-base-path>` درمیآید. میتوانید مسیر پایه را در
|
||||
نخستین اجرا با [`XUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars) از پیش تعیین کنید.
|
||||
|
||||
### TLS
|
||||
|
||||
ارائهی پنل روی HTTPS از اطلاعات احراز هویت شما در حین انتقال محافظت میکند. یا
|
||||
`webCertFile` + `webKeyFile` را تنظیم کنید — [منوی SSL در `x-ui`](/docs/config/ssl-certificates)
|
||||
میتواند یک گواهی Let's Encrypt برای شما تهیه کند — یا TLS را روی یک
|
||||
[پروکسی معکوس](/docs/operations/reverse-proxy) خاتمه دهید.
|
||||
|
||||
<Callout type="warn">
|
||||
هرگز پنل را روی اینترنت عمومی با HTTP ساده در دسترس قرار ندهید. از TLS، یک پورت
|
||||
غیرپیشفرض، و یک مسیر پایهی وب تصادفیِ بلند استفاده کنید.
|
||||
</Callout>
|
||||
|
||||
## نمایش
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ---------------- | ------------------------------------------------ | ------------------------------------------------------------- |
|
||||
| `pageSize` | `25` | تعداد ردیف در هر صفحه از فهرستها (`0` صفحهبندی را غیرفعال میکند). |
|
||||
| `expireDiff` | `0` | تعداد روز پیش از انقضا برای شروع هشدار. |
|
||||
| `trafficDiff` | `0` | درصد باقیمانده از سهمیه که در آن هشدار آغاز میشود. |
|
||||
| `remarkTemplate` | `{{INBOUND}}-{{EMAIL}}\|📊{{TRAFFIC_LEFT}}\|⏳{{DAYS_LEFT}}D` | الگوی پیشفرض یادداشت کلاینت (نگاه کنید به [لینکهای اشتراکگذاری](/docs/config/share-links#remark-template-variables)). |
|
||||
| `timeLocation` | `Local` | منطقهی زمانی برای آمار و انقضا. |
|
||||
| `datepicker` | `gregorian` | تقویم برای ورودیهای تاریخ (میلادی یا جلالی/شمسی). |
|
||||
|
||||
## امنیت و احراز هویت
|
||||
|
||||
اطلاعات احراز هویت، احراز هویت دومرحلهای، محدودکنندهی حملات جستجوی فراگیر،
|
||||
نشستها و LDAP در [نخستین ورود](/docs/guide/first-login) و
|
||||
[امنیت](/docs/operations/security) پوشش داده شدهاند. بهطور خلاصه:
|
||||
|
||||
- گذرواژهها بهصورت هشهای **bcrypt** ذخیره میشوند؛ تغییر آنها همهی نشستها را از سیستم خارج میکند.
|
||||
- **۲FA (TOTP)** میتواند در زمان ورود الزامی شود.
|
||||
- یک سازوکار جایگزین **LDAP** میتواند زمانی که بررسی گذرواژهی محلی ناموفق باشد، کاربران را احراز هویت کند.
|
||||
- دسترسی API از **توکنهای API** استفاده میکند که زیر تنظیمات پنل مدیریت میشوند (نگاه کنید به
|
||||
[مرجع API](/docs/reference/api/api-tokens)).
|
||||
|
||||
## اعلانها و اشتراک
|
||||
|
||||
این موارد گروههای تنظیمات و صفحههای مخصوص خود را دارند:
|
||||
|
||||
<Cards>
|
||||
<Card title="ربات Telegram" href="/docs/operations/telegram-bot" description="توکن، شناسههای چت، هشدارها و گزارشها." />
|
||||
<Card title="اشتراک" href="/docs/config/subscription" description="سرور اشتراک، قالبها و مسیرها." />
|
||||
<Card title="امنیت" href="/docs/operations/security" description="۲FA، محدودیتهای IP و سختسازی." />
|
||||
</Cards>
|
||||
|
||||
<Callout type="info">
|
||||
اعلانهای ایمیل (SMTP) نیز قابل پیکربندیاند (میزبان، پورت، رمزنگاری،
|
||||
گیرندگان) با همان انواع رویدادهای ربات Telegram.
|
||||
</Callout>
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
title: REALITY
|
||||
description: راهاندازی یک ورودی VLESS + REALITY همراه با XTLS-Vision در 3x-ui — کلیدها، short IDها، SNI، اثرانگشتها و اشتباهات رایج.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
**REALITY** یک لایهی امنیتی انتقال در Xray است که پروکسی شما را بهشکل ترافیک
|
||||
عادی به یک وبسایت واقعی و پرطرفدار جلوه میدهد. برخلاف TLS کلاسیک، سرور شما به
|
||||
**هیچ گواهی اختصاصی** نیاز ندارد — دستدهی (handshake) TLS سایت مقصد (`dest`) را
|
||||
قرض میگیرد. در ترکیب با جریان **XTLS-Vision**، سریع است و در برابر بازرسی عمیق
|
||||
بستهها (DPI) مقاومت میکند.
|
||||
|
||||
REALITY همراه با **VLESS** (و Trojan) بهکار میرود. جریان توصیهشده
|
||||
`xtls-rprx-vision` است.
|
||||
|
||||
## تنظیمات کلیدی
|
||||
|
||||
وقتی **REALITY** را بهعنوان حالت امنیتی روی یک ورودی VLESS انتخاب میکنید، 3x-ui
|
||||
این فیلدها را نمایش میدهد:
|
||||
|
||||
| فیلد | چیست |
|
||||
| ------------------------ | ------------------------------------------------------------------ |
|
||||
| **Dest (target)** | یک سایت TLS واقعی برای جعل هویت، برای مثال `www.microsoft.com:443`. |
|
||||
| **SNI / Server Names** | نام میزبانی که کلاینتها ارسال میکنند؛ باید با گواهی مقصد بخواند. |
|
||||
| **Public / Private key** | یک جفتکلید **x25519**. کلید خصوصی روی سرور باقی میماند. |
|
||||
| **Short IDs** | رشتههای Hex برای احراز هویت کلاینتها (میتوانید چندتا داشته باشید).|
|
||||
| **Flow** | روی `xtls-rprx-vision` تنظیم شود. |
|
||||
| **Fingerprint (uTLS)** | اثرانگشت TLS کلاینت برای تقلید، برای مثال `chrome`. |
|
||||
|
||||
کلید خصوصی با ابزار `x25519` از Xray تولید میشود (پنل میتواند این جفتکلید را
|
||||
برای شما بسازد):
|
||||
|
||||
```bash title="generate an x25519 keypair"
|
||||
xray x25519
|
||||
```
|
||||
|
||||
## راهاندازی در پنل
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### ساخت یک ورودی VLESS
|
||||
|
||||
یک ورودی جدید اضافه کنید، پروتکل **VLESS** را انتخاب کنید و **Security** را روی
|
||||
**reality** تنظیم کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### انتخاب مقصد (dest) و SNI
|
||||
|
||||
سایتی معتبر که از TLS 1.3 و HTTP/2 پشتیبانی میکند و هم از سرور و هم از کلاینتهای
|
||||
شما در دسترس است انتخاب کنید (برای مثال `www.microsoft.com:443`). نام سرورها / SNI
|
||||
را طوری تنظیم کنید که با گواهی آن سایت بخواند.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### تولید کلیدها و short IDها
|
||||
|
||||
جفتکلید x25519 و یک یا چند short ID تولید کنید. **کلید خصوصی** را محرمانه نگه
|
||||
دارید؛ کلاینتها فقط **کلید عمومی** را دریافت میکنند.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### تنظیم جریان و اثرانگشت
|
||||
|
||||
از جریان `xtls-rprx-vision` و یک اثرانگشت رایج uTLS مانند `chrome` استفاده کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### افزودن کلاینت و اشتراکگذاری لینک
|
||||
|
||||
یک کلاینت بسازید، سپس از لینک اشتراکگذاری یا کد QR آن در یک برنامهی سازگار
|
||||
(v2rayNG، Hiddify، Mihomo و دیگران) استفاده کنید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## پیکربندی چه شکلی است
|
||||
|
||||
روی سرور، `streamSettings` یک ورودی REALITY تقریباً به این شکل است:
|
||||
|
||||
```json title="server inbound (excerpt)"
|
||||
{
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "www.microsoft.com:443",
|
||||
"serverNames": ["www.microsoft.com"],
|
||||
"privateKey": "<x25519 private key>",
|
||||
"shortIds": ["<hex short id>"],
|
||||
"fingerprint": "chrome"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
لینک اشتراکگذاری متناظر کلاینت، پارامترهای **عمومی** را حمل میکند:
|
||||
|
||||
```text title="vless:// (excerpt)"
|
||||
vless://<uuid>@<server>:443?security=reality&pbk=<public-key>&sid=<short-id>&sni=www.microsoft.com&fp=chrome&spx=%2F&flow=xtls-rprx-vision#my-reality
|
||||
```
|
||||
|
||||
- `pbk` — کلید **عمومی** REALITY
|
||||
- `sid` — short ID (با یکی از موارد روی سرور میخواند)
|
||||
- `sni` — نام سرور (با گواهی مقصد میخواند)
|
||||
- `fp` — اثرانگشت کلاینت
|
||||
- `spx` — مسیر spiderX
|
||||
- `flow` — `xtls-rprx-vision`
|
||||
|
||||
## اشتباهات رایج
|
||||
|
||||
<Callout type="warn">
|
||||
|
||||
- **مقصد نامناسب.** مقدار `dest` باید یک سایت واقعی باشد که از **TLS 1.3** و
|
||||
**HTTP/2** پشتیبانی میکند، در دسترس است و در منطقهی شما مسدود نیست. سایتی را
|
||||
انتخاب کنید که مالک آن نیستید و ترافیک زیادی دارد.
|
||||
- **عدم تطابق SNI.** مقدار SNI / نام سرورها باید با گواهی واقعی مقصد بخواند، وگرنه
|
||||
دستدهی، استتار را لو میدهد.
|
||||
- **نشت کلید خصوصی.** فقط و فقط **کلید عمومی** را میان کلاینتها توزیع کنید.
|
||||
- **جریان نادرست.** REALITY + XTLS-Vision به `flow = xtls-rprx-vision` هم در ورودیِ
|
||||
مدخل کلاینت و هم در لینک اشتراکگذاری نیاز دارد.
|
||||
|
||||
</Callout>
|
||||
|
||||
## تولید یک پیکربندی
|
||||
|
||||
از تولیدکنندهی زیر برای ساخت یک جفتکلید تازهی X25519، UUID و short ID استفاده
|
||||
کنید، سپس JSON ورودی سرور و لینک اشتراکگذاری کلاینت را کپی کنید. همهچیز **در
|
||||
مرورگر شما** محاسبه میشود — هیچ کلید یا لینکی به جایی ارسال نمیشود.
|
||||
|
||||
<RealityConfigGenerator />
|
||||
|
||||
<Callout type="info">
|
||||
**کلید خصوصی** فقط به سرور شما تعلق دارد. لینک تولیدشدهی `vless://` (که حاوی
|
||||
**کلید عمومی** است) را با کلاینتها به اشتراک بگذارید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: لینکهای اشتراکگذاری
|
||||
description: قالبهای لینک اشتراکگذاری 3x-ui (vless، vmess، trojan، ss، hysteria2، mtproto)، متغیرهای قالب توضیحات، و بازرس لینک درونمرورگری.
|
||||
icon: Link
|
||||
---
|
||||
|
||||
3x-ui برای هر کلاینت یک **لینک اشتراکگذاری** (و کد QR) تولید میکند. برنامههای کلاینت
|
||||
مانند v2rayNG، Hiddify و Mihomo این لینکها را برای پیکربندی خودشان وارد میکنند.
|
||||
|
||||
## قالبهای لینک
|
||||
|
||||
| Scheme | ساختار |
|
||||
| -------------- | --------------------------------------------------------------- |
|
||||
| `vless://` | `vless://<uuid>@<host>:<port>?<params>#<remark>` |
|
||||
| `vmess://` | `vmess://<base64-json>` (یک شیء JSON کدشده با base64) |
|
||||
| `trojan://` | `trojan://<password>@<host>:<port>?<params>#<remark>` |
|
||||
| `ss://` | `ss://<userinfo>@<host>:<port>?<params>#<remark>` (SIP002؛ Shadowsocks-2022 از userinfo کدگذاریشده با درصد استفاده میکند) |
|
||||
| `hysteria2://` | `hysteria2://<auth>@<host>:<port>?<params>#<remark>` |
|
||||
| `tg://proxy` | `tg://proxy?server=…&port=…&secret=…` (MTProto) |
|
||||
|
||||
پارامترهای کوئری تنظیمات انتقال و امنیت را حمل میکنند — `security`،
|
||||
`sni`، `fp`، `pbk`، `sid`، `spx`، `flow`، `type`، `path`، `host`، `alpn` و
|
||||
بیشتر.
|
||||
|
||||
## بازرسی یک لینک
|
||||
|
||||
هر لینک اشتراکگذاری را بچسبانید تا تکتک فیلدها رمزگشایی شوند. تجزیه **بهطور کامل در
|
||||
مرورگر شما** انجام میشود — لینک هرگز روی شبکه ارسال نمیشود.
|
||||
|
||||
<ShareLinkInspector />
|
||||
|
||||
<Callout type="warn">
|
||||
لینکهای اشتراکگذاری همهی آنچه را برای اتصال بهعنوان یک کلاینت لازم است در بر دارند، از جمله
|
||||
اعتبارنامهی کلاینت. با آنها مانند رمز عبور رفتار کنید.
|
||||
</Callout>
|
||||
|
||||
## متغیرهای قالب توضیحات
|
||||
|
||||
متنی که در هر لینک پس از `#` میآید (**توضیحات** یا remark) از یک قالب تولید میشود
|
||||
که شما در تنظیمات پنل کنترل میکنید (`remarkTemplate`). مقدار پیشفرض این است:
|
||||
|
||||
```text
|
||||
{{INBOUND}}-{{EMAIL}}|📊{{TRAFFIC_LEFT}}|⏳{{DAYS_LEFT}}D
|
||||
```
|
||||
|
||||
توکنها از نحو `{{UPPER_CASE}}` استفاده میکنند. قالب بر اساس `|` به بخشهایی تقسیم میشود؛
|
||||
بخشی که تنها مقدارش نشانگر نامحدود `∞` باشد (برای `TRAFFIC_LEFT`،
|
||||
`TRAFFIC_TOTAL`، `DAYS_LEFT` یا `TIME_LEFT`) حذف میشود، تا کلاینتهای نامحدود
|
||||
تزئینات خالی نشان ندهند.
|
||||
|
||||
### توکنهای در دسترس
|
||||
|
||||
| توکن | مقدار |
|
||||
| ----- | ----- |
|
||||
| `{{EMAIL}}` / `{{USERNAME}}` | ایمیل کلاینت (شناسه) |
|
||||
| `{{INBOUND}}` | توضیحات اینباند |
|
||||
| `{{HOST}}` | توضیحات ردیف هاست (هاستهای مدیریتشده) |
|
||||
| `{{ID}}` / `{{SHORT_ID}}` | UUID کلاینت / ۸ کاراکتر نخست آن |
|
||||
| `{{TELEGRAM_ID}}` · `{{SUB_ID}}` · `{{COMMENT}}` | شناسه Telegram، شناسه اشتراک، توضیح |
|
||||
| `{{STATUS}}` / `{{STATUS_EMOJI}}` | `active`/`expired`/`depleted`/`disabled` (یا ✅⏳🚫) |
|
||||
| `{{DAYS_LEFT}}` / `{{TIME_LEFT}}` | روزهای باقیمانده، یا `Xd Xh Xm` (`∞` در صورت نامحدود بودن) |
|
||||
| `{{EXPIRE_DATE}}` / `{{JALALI_EXPIRE_DATE}}` / `{{EXPIRE_UNIX}}` | تاریخ انقضا بهصورت میلادی / شمسی / ثانیههای Unix |
|
||||
| `{{CREATED_UNIX}}` | زمان ایجاد (ثانیههای Unix) |
|
||||
| `{{TRAFFIC_USED}}` / `{{TRAFFIC_LEFT}}` / `{{TRAFFIC_TOTAL}}` | مصرف خوانا برای انسان (`∞` در صورت نامحدود بودن) |
|
||||
| `{{TRAFFIC_USED_BYTES}}` / `{{TRAFFIC_LEFT_BYTES}}` / `{{TRAFFIC_TOTAL_BYTES}}` | همان، بر حسب بایت |
|
||||
| `{{UP}}` / `{{DOWN}}` | آپلود / دانلود (خوانا برای انسان) |
|
||||
| `{{RESET_DAYS}}` · `{{USAGE_PERCENTAGE}}` | دوره بازنشانی (روز) · درصد مصرفشده |
|
||||
| `{{PROTOCOL}}` / `{{TRANSPORT}}` / `{{SECURITY}}` | مثلاً `VLESS` / `ws` / `REALITY` |
|
||||
|
||||
<Callout type="info">
|
||||
توکنهای مصرف (ترافیک، روزها، وضعیت) در **بدنه**ی اشتراک ظاهر میشوند اما
|
||||
از نمای نمایش/QR حذف میگردند، تا یک QR اشتراکگذاریشده سهمیهی باقیماندهی یک کلاینت
|
||||
را افشا نکند. توکنهای تاریخ از تنظیم `datepicker` پیروی میکنند (میلادی یا شمسی).
|
||||
</Callout>
|
||||
|
||||
## مرتبط
|
||||
|
||||
<Cards>
|
||||
<Card title="REALITY" href="/docs/config/reality" description="یک پیکربندی و لینک VLESS + REALITY بسازید." />
|
||||
<Card title="اشتراک" href="/docs/config/subscription" description="همهی لینکهای یک کلاینت را از یک URL ارائه دهید." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,179 @@
|
||||
---
|
||||
title: گواهیهای SSL
|
||||
description: دریافت و تمدید گواهیهای TLS برای پنل و ورودیهای 3x-ui — با منوی ACME در x-ui (دامنه یا IP خام)، گواهی wildcard از طریق Cloudflare DNS-01، یا Certbot دستی.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
یک گواهی TLS به شما امکان میدهد **پنل** را روی HTTPS سرویسدهی کنید (تا ترافیک ورود و
|
||||
API شما رمزگذاری شود) و TLS را روی **ورودیها** خاتمه دهید (VLESS-TLS، Trojan،
|
||||
Shadowsocks-TLS و موارد مشابه). سه راه برای بهدستآوردن گواهی وجود دارد:
|
||||
|
||||
- **منوی `x-ui`** — کلاینت داخلی [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment).
|
||||
آسانترین گزینه برای یک دامنهی واحد یا یک IP خام.
|
||||
- **Cloudflare DNS-01** — این هم از همان منو؛ برای گواهیهای **wildcard** یا
|
||||
زمانی که پورت 80 مسدود است / سرور پشت پراکسی Cloudflare قرار دارد لازم است.
|
||||
- **Certbot دستی** — اگر ترجیح میدهید `acme.sh`/Certbot را خودتان مدیریت کنید.
|
||||
|
||||
<Callout type="info">
|
||||
اگر پنل را پشت Nginx یا Caddy قرار میدهید، بگذارید پراکسی بهجای شما گواهی را
|
||||
مدیریت کند — به [پراکسی معکوس](/docs/operations/reverse-proxy) مراجعه کنید.
|
||||
ورودیهای [REALITY](/docs/config/reality) **هیچ** گواهیای نیاز ندارند؛ آنها
|
||||
TLS یک سایت واقعی را قرض میگیرند. این صفحه برای پنل و برای ورودیهای کلاسیک TLS است.
|
||||
</Callout>
|
||||
|
||||
## منوی SSL در `x-ui` (Let's Encrypt)
|
||||
|
||||
`x-ui` را اجرا کنید و **`20` — SSL Certificate Management** را انتخاب کنید. این گزینه
|
||||
[acme.sh](https://github.com/acmesh-official/acme.sh) را به کار میگیرد و موارد زیر را ارائه میدهد:
|
||||
|
||||
| گزینه | کاری که انجام میدهد |
|
||||
| ------------------------------ | ------------------------------------------------------------------- |
|
||||
| Get SSL (Domain) | صدور گواهی برای یک دامنه از طریق اعتبارسنجی HTTP. |
|
||||
| Get SSL for IP Address | صدور یک گواهی کوتاهمدت (۶ روزه، با تمدید خودکار) برای یک **IP خام**. |
|
||||
| Revoke | باطلکردن یک گواهی موجود. |
|
||||
| Force Renew | تمدید همین حالا، پیش از انقضا. |
|
||||
| Show Existing Domains | فهرستکردن گواهیهایی که از پیش روی سرور هستند. |
|
||||
| Set Cert paths for the panel | اشارهدادن TLS پنل به یک گواهی صادرشده (فیلدها را برای شما تنظیم میکند). |
|
||||
|
||||
### صدور گواهی برای یک دامنه
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### دامنه را به سرور اشاره دهید
|
||||
|
||||
یک رکورد `A` (و/یا `AAAA`) برای دامنهی خود بسازید که به IP عمومی این سرور
|
||||
اشاره کند. تا زمانی که DNS منتشر (propagate) نشده باشد، اعتبارسنجی ناموفق خواهد بود.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پورت 80 را آزاد کنید
|
||||
|
||||
اعتبارسنجی HTTP نیاز دارد که **پورت 80** از اینترنت در دسترس باشد و از پیش در حال
|
||||
استفاده نباشد. هر چیزی را که به آن متصل است برای این مدت متوقف کنید و آن را از
|
||||
[فایروال](/docs/reference/ports-firewall) عبور دهید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### صادرکننده را اجرا کنید
|
||||
|
||||
`x-ui` ← `20` ← **Get SSL (Domain)**، سپس دامنه را وارد کنید. acme.sh گواهی را
|
||||
درخواست میکند و آن را زیر `/root/cert/<domain>/` بهصورت `fullchain.pem`
|
||||
(زنجیرهی گواهی) و `privkey.pem` (کلید خصوصی) ذخیره میکند.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### آن را به پنل متصل کنید
|
||||
|
||||
گزینهی **Set Cert paths for the panel** را انتخاب کنید تا `webCertFile` و
|
||||
`webKeyFile` پر شوند و پنل راهاندازی مجدد شود، یا آنها را خودتان در
|
||||
[تنظیمات پنل](/docs/config/panel#tls) تنظیم کنید. بهمحض تنظیمشدن هر دو، پنل HTTPS را
|
||||
سرویسدهی میکند.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
### صدور گواهی برای یک IP خام
|
||||
|
||||
دامنهای ندارید؟ گزینهی **Get SSL for IP Address** را انتخاب کنید تا یک گواهی
|
||||
کوتاهمدت (با اعتبار حدود ۶ روز، که بهصورت خودکار تمدید میشود) متصل به IP سرور
|
||||
بهدست آورید. برای دسترسی به پنل روی HTTPS پیش از آنکه دامنهای راهاندازی کنید مفید است.
|
||||
|
||||
## Cloudflare (گواهی wildcard با DNS-01)
|
||||
|
||||
اعتبارسنجی DNS بهجای پاسخدادن روی پورت 80، با ساختن یک رکورد TXT ثابت میکند که شما
|
||||
دامنه را در اختیار دارید — بنابراین **پشت پراکسی Cloudflare**، روی سرورهایی که
|
||||
پورت 80 در آنها مسدود است، و برای گواهیهای **wildcard** (`*.example.com`) کار میکند.
|
||||
|
||||
DNS دامنهی شما باید توسط Cloudflare مدیریت شود و به یکی از این موارد نیاز دارید:
|
||||
|
||||
- یک **توکن API محدودشده** با مجوز `Zone:DNS:Edit` (توصیهشده)، یا
|
||||
- **ایمیل حساب + Global API Key**.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### یک توکن API محدودشده بسازید
|
||||
|
||||
در داشبورد Cloudflare به **My Profile → API Tokens →
|
||||
[Create Token](https://dash.cloudflare.com/profile/api-tokens)** بروید، قالب
|
||||
**Edit zone DNS** را انتخاب کنید، آن را به zoneای که برایش گواهی صادر میکنید محدود
|
||||
کنید و آن را بسازید. توکن را کپی کنید — فقط یکبار نمایش داده میشود.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### صادرکنندهی Cloudflare را اجرا کنید
|
||||
|
||||
`x-ui` ← **`21` — Cloudflare SSL Certificate**. هنگام پرسش، **`t`** را برای یک
|
||||
توکن API (پیشفرض) یا **`g`** را برای Global API Key انتخاب کنید، سپس دامنهی خود را
|
||||
وارد کنید (و برای Global API Key، ایمیل حساب و کلید خود را). acme.sh رکورد TXT را
|
||||
میسازد، اعتبارسنجی میکند و آن را پاکسازی میکند.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پنل را به آن اشاره دهید
|
||||
|
||||
مانند جریان دامنه، از **Set Cert paths for the panel** (منوی `20`) استفاده کنید یا
|
||||
`webCertFile` / `webKeyFile` را در [تنظیمات پنل](/docs/config/panel#tls) تنظیم کنید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
یک توکن محدودشده را به Global API Key ترجیح دهید — آن فقط اجازهی ویرایش DNS را روی
|
||||
zoneای که انتخاب میکنید میدهد، بنابراین نشت آن نمیتواند به بقیهی حساب Cloudflare شما دست بزند.
|
||||
</Callout>
|
||||
|
||||
## دستی (Certbot)
|
||||
|
||||
اگر ترجیح میدهید از منو استفاده نکنید، یک گواهی را با افزونهی standalone مربوط به
|
||||
Certbot صادر کنید (این هم نیاز دارد که پورت 80 آزاد باشد و دامنه به سرور اشاره کند):
|
||||
|
||||
```bash
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
Certbot گواهی را در `/etc/letsencrypt/live/yourdomain.com/` مینویسد
|
||||
(`fullchain.pem` و `privkey.pem`). پنل را در [تنظیمات پنل](/docs/config/panel#tls) به آن
|
||||
دو فایل اشاره دهید و تمدید را راهاندازی کنید — `certbot renew` بهصورت پیشفرض روی یک
|
||||
تایمر systemd اجرا میشود.
|
||||
|
||||
## استفاده از گواهی
|
||||
|
||||
- **پنل** — `webCertFile` (زنجیرهی کامل) و `webKeyFile` (کلید خصوصی) را در
|
||||
[تنظیمات پنل](/docs/config/panel#tls) تنظیم کنید. برای آنکه پنل به HTTPS سوئیچ کند،
|
||||
هر دو باید تنظیم شوند. گزینهی منوی **`11` — View Current Settings** مسیرهای
|
||||
درحالاستفادهی فعلی را چاپ میکند.
|
||||
- **ورودیها** — وقتی TLS را روی یک ورودی فعال میکنید، در تنظیمات TLS همان ورودی به
|
||||
همان فایلهای گواهی و کلید ارجاع دهید (یا محتوای آنها را جایگذاری کنید). به
|
||||
[ورودیها](/docs/config/inbounds) و [ترابریها](/docs/config/transports) مراجعه کنید.
|
||||
|
||||
<Callout type="warn">
|
||||
گواهیها منقضی میشوند (Let's Encrypt: ۹۰ روز؛ گواهیهای IP: حدود ۶ روز). هم منو و هم
|
||||
Certbot بهصورت خودکار تمدید میکنند، اما پنل همچنان **فایلها** را در مسیرهای ثابتشان
|
||||
میخواند — بنابراین **در همان محل** تمدید کنید نه با جابهجاکردن فایلها، و پنل در
|
||||
راهاندازی مجدد بعدیاش گواهی جدید را برمیدارد. **Force Renew** (منوی `20`) یک تمدید
|
||||
را بهصورت درخواستی فعال میکند.
|
||||
</Callout>
|
||||
|
||||
## گامهای بعدی
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="تنظیمات پنل"
|
||||
href="/docs/config/panel#tls"
|
||||
description="webCertFile / webKeyFile و بقیهی تنظیمات وبسرور."
|
||||
/>
|
||||
<Card
|
||||
title="پراکسی معکوس"
|
||||
href="/docs/operations/reverse-proxy"
|
||||
description="بهجای آن، بگذارید Nginx یا Caddy کار خاتمهدادن TLS را برایتان انجام دهد."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="TLS مخفیانه برای ورودیها — بدون نیاز به گواهی."
|
||||
/>
|
||||
</Cards>
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: Subscription
|
||||
description: راهاندازی سرور اشتراک 3x-ui — قالبهای base64/JSON/Clash، پورتها و مسیرها، TLS، هدرهای پاسخ و قالبهای سفارشی.
|
||||
icon: Rss
|
||||
---
|
||||
|
||||
یک **اشتراک** (subscription) یک URL واحد است که همهی پیکربندیهای یک کلاینت را
|
||||
برمیگرداند. برنامههای کلاینت آن را بهصورت دورهای تازهسازی میکنند، بنابراین وقتی
|
||||
یک ورودی را تغییر میدهید، کلاینتها این تغییر را بهصورت خودکار دریافت میکنند. سرور
|
||||
اشتراک بهعنوان یک سرور **جداگانه** از پنل اجرا میشود.
|
||||
|
||||
## فعالسازی و پیکربندی
|
||||
|
||||
سرور اشتراک بهصورت **پیشفرض روشن** است (`subEnable`). آن را در تنظیمات اشتراک
|
||||
پنل پیکربندی کنید:
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ------------- | ------- | --------------------------------------------------------------- |
|
||||
| `subPort` | `2096` | پورت گوشدادن (جدا از پنل). |
|
||||
| `subListen` | _(همه)_ | آدرس اتصال (bind). |
|
||||
| `subPath` | `/sub/` | مسیر پایه برای URLهای خام اشتراک. |
|
||||
| `subDomain` | _(هیچ)_ | میزبان عمومی؛ اگر تنظیم شود، سرور فقط به همان Host پاسخ میدهد. |
|
||||
| `subCertFile` / `subKeyFile` | _(هیچ)_ | گواهی و کلید TLS — هنگام تنظیم، سرور **HTTPS** ارائه میدهد. |
|
||||
| `subEncrypt` | `true` | بدنهی خام اشتراک را با base64 رمزگذاری میکند. |
|
||||
| `subUpdates` | `12` | بازهی پیشنهادی تازهسازی (ساعت) که به کلاینتها ارسال میشود. |
|
||||
|
||||
یک URL اشتراک به این شکل است:
|
||||
|
||||
```text
|
||||
https://<sub-host>:<sub-port>/sub/<sub-id>
|
||||
```
|
||||
|
||||
که در آن `<sub-id>` همان **Sub ID** کلاینت است.
|
||||
|
||||
همان Sub ID در چند قالب روی مسیرهای مختلف ارائه میشود — فهرست **Base64** در
|
||||
`subPath` و پیکربندی **JSON** (Xray-json) در مسیر JSON. URLها را بسازید و هر دو
|
||||
بدنه را اینجا پیشنمایش کنید:
|
||||
|
||||
<SubscriptionBuilder />
|
||||
|
||||
## قالبهای خروجی
|
||||
|
||||
**قالب بر اساس مسیر انتخاب میشود** و هرکدام کلید فعالسازی مخصوص خود را دارند:
|
||||
|
||||
| Format | Path | Enabled by | Output |
|
||||
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
|
||||
| **لینکهای خام** | `/sub/` | همیشه (اگر روشن باشد) | فهرستی از لینکهای `vless://`، `vmess://`، … (هنگام فعالبودن `subEncrypt` با base64 رمزگذاری میشود). |
|
||||
| **JSON** | `/json/` | `subJsonEnable` | پیکربندی(های) کامل کلاینت Xray. |
|
||||
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | پروفایل YAML. |
|
||||
|
||||
فقط ورودیهای فعالی که از **VLESS، VMess، Trojan، Shadowsocks یا Hysteria2**
|
||||
استفاده میکنند در یک اشتراک ظاهر میشوند و بر اساس شاخص sub-sort آنها مرتب میشوند.
|
||||
درخواست `/sub/` همراه با هدر `Accept: text/html` (یا `?html=1`) بهجای بدنهی خام،
|
||||
یک صفحهی اطلاعات خوانا برای انسان برمیگرداند.
|
||||
|
||||
### Base64 vs JSON
|
||||
|
||||
بدنهی **Base64** صرفاً همان لینکهای اشتراکگذاری است که با خط جدید به هم پیوسته و
|
||||
با standard-base64 رمزگذاری شدهاند (با `subEncrypt` قابل تغییر است). بدنهی **JSON**
|
||||
هر کلاینت را در یک پیکربندی کامل کلاینت Xray میپیچد — یک اسکلت ثابت (ورودیهای محلی
|
||||
mixed/HTTP، DNS، مسیریابی، policy) بهعلاوهی یک outbound از نوع `proxy` که به ورودی
|
||||
اشاره میکند. 3x-ui **برای یک کلاینت یک شیء پیکربندی واحد و برای چند کلاینت یک آرایه**
|
||||
تولید میکند، از فرم تخت `settings` در outbound استفاده میکند
|
||||
(`address`/`port`/`id`، `level: 8`) و `sockopt` را از `streamSettings` حذف میکند.
|
||||
|
||||
## هدرهای پاسخ
|
||||
|
||||
اشتراکها هدرهای استانداردی برمیگردانند که برنامههای سازگار آنها را میخوانند:
|
||||
|
||||
- **`Subscription-Userinfo`** — `upload`، `download`، `total` (بایت؛ `total=0`
|
||||
یعنی نامحدود) و `expire` (ثانیههای Unix).
|
||||
- **`Profile-Update-Interval`** — بازهی تازهسازی برحسب ساعت (`subUpdates`).
|
||||
- **`Profile-Title`**، **`Support-Url`**، **`Profile-Web-Page-Url`**،
|
||||
**`Announce`** — برندینگ اختیاری که برخی کلاینتها نمایش میدهند.
|
||||
|
||||
## قالبهای سفارشی صفحه
|
||||
|
||||
برای برندینگ صفحهی HTML اشتراک، `subThemeDir` را به یک پوشهی حاوی قالب سفارشیِ
|
||||
صفحهی اطلاعات اشاره دهید. توضیح (remark) هر کلاینت روی هر لینک کاملاً قابل
|
||||
قالببندی است — به [لینکهای اشتراکگذاری ← متغیرهای remark](/docs/config/share-links#remark-template-variables) مراجعه کنید.
|
||||
|
||||
<Callout type="info">
|
||||
سرور اشتراک را پشت TLS قرار دهید (با تنظیم `subCertFile`/`subKeyFile`، یا یک
|
||||
[پروکسی معکوس](/docs/operations/reverse-proxy)) تا محتوای اشتراک در حین انتقال
|
||||
افشا نشود.
|
||||
</Callout>
|
||||
@@ -0,0 +1,201 @@
|
||||
---
|
||||
title: انتقالها و امنیت
|
||||
description: هر انتقالی که 3x-ui ارائه میدهد — TCP، mKCP، WebSocket، gRPC، HTTPUpgrade، XHTTP، Hysteria — بههمراه تنظیماتشان، و نیز مبهمسازی FinalMask، sockopt، TLS/REALITY، XTLS-Vision و رمزنگاری VLESS.
|
||||
icon: Network
|
||||
---
|
||||
|
||||
یک **انتقال** تعیین میکند که بستهها چگونه میان کلاینت و سرور حمل شوند، یک
|
||||
لایه **امنیتی** تعیین میکند که چگونه رمزنگاری و استتار شوند، و **FinalMask**
|
||||
میتواند آنچه باقی مانده را مبهم کند. پنل تنها ترکیبهای معتبر را ارائه میدهد؛ این
|
||||
صفحه تنظیمات هر انتقال و قواعدی را که پنل اعمال میکند فهرست میکند.
|
||||
|
||||
## انتقالها
|
||||
|
||||
انتقال (مقدار `network` مربوط به inbound) را در فرم inbound/outbound انتخاب کنید. هر
|
||||
شبکه کلید تنظیمات خود را روی سیم مینویسد (`tcpSettings`، `kcpSettings`، …).
|
||||
|
||||
| انتقال | کلید تنظیمات | چه زمانی از آن استفاده کنید |
|
||||
| --------------- | --------------------- | ---------------------------------------------------------------------- |
|
||||
| **TCP (Raw)** | `tcpSettings` | کمترین سربار. پایهای برای REALITY + XTLS-Vision و fallbackها؛ استتار اختیاری هدر HTTP/1.1. |
|
||||
| **mKCP** | `kcpSettings` | پروتکل قابلاعتماد روی **UDP** — پهنای باند را با تأخیر کمتر روی لینکهای پُرافت معاوضه میکند. هیچ TLS/REALITY حمل نمیکند. |
|
||||
| **WebSocket** | `wsSettings` | از طریق CDNها و پراکسیهای معکوس HTTP کار میکند؛ بسیار سازگار است. |
|
||||
| **gRPC** | `grpcSettings` | مبتنی بر HTTP/2؛ مالتیپلکس خوبی دارد و بهخوبی از طریق Nginx پراکسی میشود. |
|
||||
| **HTTPUpgrade** | `httpupgradeSettings` | `Upgrade` مربوط به HTTP/1.1 و سازگار با CDN؛ سبکتر از WebSocket کامل. |
|
||||
| **XHTTP** | `xhttpSettings` | انتقال HTTP مدرن با مالتیپلکس جریانی؛ سازگار با CDN و توانمند برای REALITY. |
|
||||
| **Hysteria** | `hysteriaSettings` | انتقال مبتنی بر QUIC — تنها برای پروتکل **Hysteria2**. |
|
||||
|
||||
<Callout type="info">
|
||||
inboundهای **WireGuard** و **Tunnel** (dokodemo-door) هیچ انتخابگر انتقالی
|
||||
نمایش نمیدهند — جریان آنها تنها security/sockopt را حمل میکند. پنلهای قدیمیتر
|
||||
یک انتقال خام **HTTP/2 (`http`)** نیز نمایش میدادند؛ این انتقال جای خود را به
|
||||
**XHTTP** داده و دیگر قابل انتخاب نیست.
|
||||
</Callout>
|
||||
|
||||
### TCP (Raw) — `tcpSettings`
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| ------------------------------ | ------- | ----------------------------------------------------------------------- |
|
||||
| `acceptProxyProtocol` | `false` | پذیرش پروتکل PROXY از یک پراکسی بالادست تا IP واقعی کلاینت حفظ شود. |
|
||||
| `header.type` | `none` | `none`، یا `http` برای استتار HTTP/1.1. |
|
||||
| `header.request` / `response` | — | هنگام `type: http`: متد، مسیر، نسخه و یک نگاشت هدر که یک تبادل HTTP معمولی را تقلید میکنند. |
|
||||
|
||||
### mKCP — `kcpSettings`
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| ------------------ | ----------- | ---------------------------------------------------------------- |
|
||||
| `mtu` | `1350` | بیشینه واحد انتقال، بر حسب بایت (576–1460). |
|
||||
| `tti` | `20` | بازه زمانی انتقال، بر حسب میلیثانیه (10–100). کمتر = پاسخگوتر، سربار بیشتر. |
|
||||
| `uplinkCapacity` | `5` | بودجه پهنای باند آپلود، بر حسب **MB/s**. |
|
||||
| `downlinkCapacity` | `20` | بودجه پهنای باند دانلود، بر حسب **MB/s**. |
|
||||
| `cwndMultiplier` | `1` | ضریب پنجره ازدحام؛ برای فشار بیشتر روی لینکهای خوب آن را بالا ببرید. |
|
||||
| `maxSendingWindow` | `2097152` | کران بالای بستههای در حال پرواز. |
|
||||
|
||||
<Callout type="info">
|
||||
mKCP نمیتواند TLS یا REALITY حمل کند. برای استتار آن، یک ماسک UDP از نوع
|
||||
**FinalMask** اضافه کنید — ماسک `mkcp-legacy` همان مبهمسازی کلاسیک هدر را
|
||||
بازتولید میکند که Xray قدیمیتر در `kcpSettings.header`/`seed` ذخیره میکرد
|
||||
(آن فیلدها دیگر اینجا وجود ندارند).
|
||||
</Callout>
|
||||
|
||||
### WebSocket — `wsSettings`
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| --------------------- | ------- | ---------------------------------------------------------------- |
|
||||
| `path` | `/` | مسیر درخواست — وقتی چند سرویس یک میزبان را به اشتراک میگذارند، بر اساس آن مسیریابی کنید. |
|
||||
| `host` | _(none)_| بازنویسی هدر `Host` (پشت یک CDN مفید است). |
|
||||
| `headers` | `{}` | هدرهای درخواست اضافی. |
|
||||
| `heartbeatPeriod` | `0` | ثانیههای بین پینگهای keepalive؛ `0` آنها را غیرفعال میکند. |
|
||||
| `acceptProxyProtocol` | `false` | پذیرش پروتکل PROXY از یک بالادست. |
|
||||
|
||||
### gRPC — `grpcSettings`
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| ------------- | ------- | --------------------------------------------------------- |
|
||||
| `serviceName` | _(none)_| مسیر سرویس gRPC؛ مانند یک مسیر مخفی عمل میکند. |
|
||||
| `authority` | _(none)_| بازنویسی شبههدر `:authority`. |
|
||||
| `multiMode` | `false` | مالتیپلکس چند جریان روی یک اتصال. |
|
||||
|
||||
### HTTPUpgrade — `httpupgradeSettings`
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| --------------------- | ------- | --------------------------------------------- |
|
||||
| `path` | `/` | مسیر درخواست. |
|
||||
| `host` | _(none)_| بازنویسی هدر `Host`. |
|
||||
| `headers` | `{}` | هدرهای درخواست اضافی. |
|
||||
| `acceptProxyProtocol` | `false` | پذیرش پروتکل PROXY از یک بالادست. |
|
||||
|
||||
HTTPUpgrade یک `Upgrade` تکمرحلهای HTTP/1.1 بدون قاببندی WebSocket است — هیچ
|
||||
فیلد heartbeat ندارد.
|
||||
|
||||
### XHTTP — `xhttpSettings`
|
||||
|
||||
XHTTP (SplitHTTP) مجموعه فیلد بزرگی دارد؛ پنل پیشفرضهای معقولی را پر میکند.
|
||||
آنهایی که معمولاً سراغشان میروید:
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| ---------------------- | ----------- | ---------------------------------------------------------------------- |
|
||||
| `path` | `/` | مسیر درخواست. |
|
||||
| `host` | _(none)_ | بازنویسی هدر `Host`. |
|
||||
| `mode` | `auto` | `auto`، `packet-up`، `stream-up` یا `stream-one`. `packet-up` بیشترین سازگاری با CDN را دارد؛ `stream-*` تأخیر کمتری دارند. |
|
||||
| `xPaddingBytes` | `100-1000` | بازه padding تصادفی که اندازه بستهها را محو میکند. |
|
||||
| `scMaxBufferedPosts` | `30` | بافر سمت سرور برای POSTهای آپلودشده. |
|
||||
| `scStreamUpServerSecs` | `20-80` | پنجره stream-up سمت سرور (بازه با خط تیره). |
|
||||
| `xmux` (`enableXmux`) | _(off)_ | مالتیپلکس اتصال — `maxConcurrency` `16-32`، `maxConnections` `6`، … برای همزمانی بالا روشن کنید. |
|
||||
|
||||
فیلدهای Session-ID (`sessionIDPlacement`، `sessionIDKey`، `sessionIDTable`،
|
||||
`sessionIDLength`) و کلیدهای `scMin/MaxEachPostBytes` پیشرفتهاند؛ آنها را خالی
|
||||
بگذارید مگر آنکه با یک بالادست مشخص هماهنگ میشوید.
|
||||
|
||||
### Hysteria — `hysteriaSettings`
|
||||
|
||||
تنها زمانی معتبر است که پروتکل **Hysteria2** باشد.
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| ---------------- | ------- | ----------------------------------------------------------------------- |
|
||||
| `version` | `2` | نسخه پروتکل Hysteria. |
|
||||
| `auth` | _(none)_| رشته احراز هویت مشترک. |
|
||||
| `udpIdleTimeout` | `60` | ثانیه (2–600) پیش از حذف نشستهای بیکار UDP. |
|
||||
| `masquerade` | — | استتار بهعنوان یک سرور HTTP/3: `type` با مقدار `proxy`/`file`/`string` و `url`/`dir`/`content`، بهعلاوه `headers` و `statusCode`. |
|
||||
|
||||
## FinalMask — مبهمسازی لایه پایانی
|
||||
|
||||
**FinalMask** ترافیک را **پس از** لایههای انتقال و امنیت میپیچد، بنابراین میتواند
|
||||
انتقالهایی را که TLS حمل نمیکنند (مانند mKCP) استتار کند یا پوستهای دوم روی TLS
|
||||
بیفزاید. ماسکها برای هر جهت پیکربندی میشوند:
|
||||
|
||||
- **ماسکهای TCP** — `fragment`، `sudoku`، `header-custom`.
|
||||
- **ماسکهای UDP** — `salamander`، `mkcp-legacy`، `header-custom`، `xdns`، `xicmp`،
|
||||
`noise`، `sudoku`، `realm`. (`mkcp-legacy` همان مبهمسازی قدیمی هدر mKCP را
|
||||
بازتولید میکند.)
|
||||
- **پارامترهای QUIC** — کنترل ازدحام (`reno`، `bbr`، `brutal`، `force-brutal`)،
|
||||
نرخهای آپلود/دانلود Brutal، `udpHop` (چرخاندن پورت QUIC در یک بازه برای دور زدن
|
||||
مسدودسازی پورت)، و تنظیم پنجره دریافت.
|
||||
|
||||
FinalMask جایگزین مبهمسازی `header`/`seed` بهازای هر انتقال میشود که بیلدهای
|
||||
قدیمیتر Xray نمایش میدادند.
|
||||
|
||||
## sockopt — گزینههای سطح پایین سوکت
|
||||
|
||||
`sockopt` در کنار هر انتقالی سوار میشود و سوکت زیرین را تنظیم میکند. مفیدترین
|
||||
فیلدها:
|
||||
|
||||
| فیلد | پیشفرض | معنی |
|
||||
| --------------------- | ------- | ---------------------------------------------------------------- |
|
||||
| `tcpFastOpen` | `false` | فعالسازی TCP Fast Open. |
|
||||
| `tcpcongestion` | `bbr` | کنترل ازدحام: `bbr`، `cubic` یا `reno`. |
|
||||
| `tproxy` | `off` | حالت پراکسی شفاف: `off`، `redirect` یا `tproxy`. |
|
||||
| `domainStrategy` | `AsIs` | نحوه تفکیک نشانیها (`UseIP`، `ForceIPv4`، …). |
|
||||
| `dialerProxy` | _(none)_| زنجیر کردن شمارهگیری این outbound از طریق یک تگ outbound دیگر. |
|
||||
| `interface` | _(none)_| اتصال به یک رابط شبکه مشخص. |
|
||||
| `mark` | `0` | SO_MARK برای مسیریابی سیاستی (`0` = تنظیمنشده). |
|
||||
|
||||
فیلدهای عددی که روی `0` رها شوند روی سیم حذف میشوند تا Xray پیشفرضهای سیستمعامل
|
||||
را حفظ کند. ورودیهای پیشرفته (`happyEyeballs`، `customSockopt[]`، تایمرهای
|
||||
keepalive) برای موارد خاص در دسترساند.
|
||||
|
||||
## امنیت
|
||||
|
||||
لایه امنیتی یکی از **`none`**، **`tls`** یا **`reality`** است، با این
|
||||
قواعد واجد شرایط بودن:
|
||||
|
||||
| امنیت | انتقالهای واجد شرایط | پروتکلهای واجد شرایط |
|
||||
| ----------- | -------------------------------------------- | --------------------------------------------------- |
|
||||
| **TLS** | `tcp`، `ws`، `grpc`، `httpupgrade`، `xhttp` | VLESS، VMess، Trojan، Shadowsocks (Hysteria2 همیشه TLS است) |
|
||||
| **REALITY** | `tcp`، `grpc`، `xhttp` | VLESS، Trojan |
|
||||
|
||||
mKCP و Hysteria لایه TLS/REALITY جداگانهای نمیگیرند — mKCP بهصورت متن ساده اجرا
|
||||
میشود (با FinalMask استتارش کنید)، و Hysteria بهطور ذاتی QUIC/TLS است. REALITY
|
||||
سرور شما را بهعنوان یک سایت واقعی TLS استتار میکند و به هیچ گواهی نیازی ندارد — به
|
||||
[REALITY](/docs/config/reality) مراجعه کنید.
|
||||
|
||||
## جریان XTLS-Vision
|
||||
|
||||
جریان `xtls-rprx-vision` سریع و مقاوم در برابر DPI است. این جریان برای
|
||||
**VLESS** در یکی از این دو حالت در دسترس است:
|
||||
|
||||
- انتقال، **TCP** خام با امنیت **TLS** یا **REALITY** باشد (XTLS-Vision
|
||||
کلاسیک)، یا
|
||||
- انتقال، **XHTTP** با رمزنگاری VLESS فعال باشد (به ادامه مراجعه کنید).
|
||||
|
||||
جریان را روی **کلاینت** VLESS تنظیم کنید، نه روی inbound. با Vision کلاسیک روی
|
||||
TCP، پنل میتواند پس از آنکه یک کلاینت از جریان استفاده کرد، یک **Vision seed** نیز
|
||||
ارائه دهد.
|
||||
|
||||
## رمزنگاری VLESS (ML-KEM)
|
||||
|
||||
VLESS از **رمزنگاری** پساکوانتومی (ML-KEM / `mlkem768x25519`) پشتیبانی میکند که در
|
||||
`decryption` مربوط به inbound (سمت سرور) و `encryption` کلاینتها (برای تولید
|
||||
لینک) ذخیره میشود. وقتی فعال باشد، جریان Vision را روی XHTTP باز میکند. کلیدها
|
||||
را از تنظیمات VLESS در پنل تولید کنید.
|
||||
|
||||
## رمزهای Shadowsocks
|
||||
|
||||
inboundهای Shadowsocks هم از رمزهای کلاسیک و هم از **Shadowsocks-2022**
|
||||
پشتیبانی میکنند (نام روشهایی که با `2022-blake3-` آغاز میشوند). بیشتر رمزها چندکاربره هستند؛
|
||||
`2022-blake3-chacha20-poly1305` تککاربره است.
|
||||
|
||||
<Callout type="info">
|
||||
انتقالها و امنیت باید در هر دو سر یکسان باشند. لینک اشتراک کلاینت آنها را
|
||||
کدگذاری میکند (`type=ws`، `security=reality`، `flow=xtls-rprx-vision`، …) —
|
||||
هر لینکی را با [بازرس لینک اشتراک](/docs/config/share-links) رمزگشایی کنید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: نخستین ورود
|
||||
description: مشخصات ورود تولیدشدهٔ 3x-ui را بیابید، به پنل دسترسی پیدا کنید، احراز هویت دومرحلهای را فعال کنید و پیش از در معرض قرار دادن هر چیزی، پنل را ایمنسازی کنید.
|
||||
icon: KeyRound
|
||||
---
|
||||
|
||||
پس از نصب، نخستین کار شما این است که وارد پنل شوید و **آن را ایمن کنید**، پیش از
|
||||
آنکه چیز دیگری را در معرض دسترس قرار دهید.
|
||||
|
||||
## دسترسی به پنل
|
||||
|
||||
پنل در این نشانی ارائه میشود:
|
||||
|
||||
```text
|
||||
http://<your-server-ip>:<port>/<web-base-path>
|
||||
```
|
||||
|
||||
پورت پیشفرض **2053** و مسیر پایهٔ پیشفرض `/` است — اما نصب با اسکریپت، نام
|
||||
کاربری، رمز عبور، **پورت** و مسیر پایهٔ وب را **بهصورت تصادفی تولید میکند**،
|
||||
پس مقادیر واقعی خود را بررسی کنید.
|
||||
|
||||
### یافتن مشخصات ورود
|
||||
|
||||
نصب با اسکریپت پس از پایان، خلاصهای از مشخصات ورود را چاپ میکند و آن را در یک
|
||||
فایل ویژهٔ root نیز مینویسد:
|
||||
|
||||
```bash title="/etc/x-ui/install-result.env (mode 600)"
|
||||
XUI_USERNAME=...
|
||||
XUI_PASSWORD=...
|
||||
XUI_PANEL_PORT=...
|
||||
XUI_WEB_BASE_PATH=...
|
||||
XUI_ACCESS_URL=...
|
||||
XUI_API_TOKEN=...
|
||||
XUI_DB_TYPE=sqlite
|
||||
```
|
||||
|
||||
اگر آنها را از دست دادید، از ابزارهای مدیریتی استفاده کنید:
|
||||
|
||||
```bash
|
||||
x-ui # menu → 11 (View Current Settings)
|
||||
x-ui settings # or the one-shot form
|
||||
```
|
||||
|
||||
برای **Docker**، مشخصات ورود تولیدشده را از لاگهای کانتینر بخوانید، یا دستور
|
||||
`docker exec -it <container> x-ui setting -show` را اجرا کنید.
|
||||
|
||||
<Callout type="warn">
|
||||
اگر پنل شما هنوز از مقادیر پیشفرض `admin` / `admin` استفاده میکند (پنل در این
|
||||
حالت هشدار میدهد)، بیدرنگ آن را تغییر دهید — پیش از ساختن هر inbound.
|
||||
</Callout>
|
||||
|
||||
## تغییر مشخصات ورود، پورت و مسیر
|
||||
|
||||
یک پورت غیرپیشفرض و یک **مسیر پایهٔ وب** طولانی و تصادفی، یافتن پنل را بسیار
|
||||
دشوارتر میکند. آنها را از بخش **Panel Settings** در رابط کاربری، یا از منوی
|
||||
`x-ui` تغییر دهید:
|
||||
|
||||
- **7 — Reset Username & Password** (با امکان غیرفعالسازی همزمان 2FA)
|
||||
- **8 — Reset Web Base Path** (آن را تصادفی میکند)
|
||||
- **10 — Change Port**
|
||||
|
||||
تغییر نام کاربری یا رمز عبور **همهٔ نشستهای موجود را از سیستم خارج میکند** و
|
||||
اگر احراز هویت دومرحلهای فعال بود، آن را غیرفعال میسازد.
|
||||
|
||||
## احراز هویت دومرحلهای (2FA)
|
||||
|
||||
3x-ui از احراز هویت دومرحلهای TOTP پشتیبانی میکند (سازگار با Google
|
||||
Authenticator، Aegis و غیره). آن را در بخش **Panel Settings** فعال کنید — پس از
|
||||
فعالسازی، صفحهٔ ورود علاوه بر رمز عبور، یک کد ۶ رقمی نیز درخواست میکند و
|
||||
فعال کردن آن همه را وادار به ورود مجدد میکند. میتوانید آن را از مرحلهٔ **Reset
|
||||
Username & Password** در منو یا با دستور `x-ui setting -resetTwoFactor` غیرفعال
|
||||
کنید.
|
||||
|
||||
## محافظت داخلی از ورود
|
||||
|
||||
- **محدودکنندهٔ حملهٔ جستجوی فراگیر:** پس از **۵** ورود ناموفق از یک IP/نام
|
||||
کاربری یکسان در بازهٔ ۵ دقیقه، آن ترکیب برای **۱۵ دقیقه** مسدود میشود.
|
||||
- **خطاهای عمومی:** صفحهٔ ورود هم برای مشخصات نادرست و هم برای کدهای 2FA نادرست،
|
||||
پیام «wrong username or password» را نمایش میدهد، پس هیچ چیزی فاش نمیکند.
|
||||
- **نشستها** به مدت `sessionMaxAge` دقیقه (پیشفرض **۳۶۰** = ۶ ساعت) معتبرند و
|
||||
هنگام تغییر مشخصات ورود باطل میشوند.
|
||||
- **LDAP** را میتوان بهعنوان روش جایگزین احراز هویت در Panel Settings فعال کرد.
|
||||
|
||||
## چکلیست ضروری ایمنسازی
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### مشخصات ورود قوی و یکتا تعیین کنید
|
||||
|
||||
نام کاربری و رمز عبور تولیدشده (یا `admin/admin`) را با مقادیر قوی جایگزین کنید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### از پورت غیرپیشفرض و مسیر پایهٔ تصادفی استفاده کنید
|
||||
|
||||
پنل را از `2053` جابهجا کنید و آن را زیر یک مسیر تصادفی و طولانی ارائه دهید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### احراز هویت دومرحلهای را فعال کنید
|
||||
|
||||
2FA را فعال کنید تا یک رمز عبور لو رفته بهتنهایی نتواند دسترسی بدهد.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پنل را پشت TLS قرار دهید
|
||||
|
||||
از یک گواهی معتبر (از طریق مدیریت SSL در منوی `x-ui` یا یک reverse proxy)
|
||||
استفاده کنید تا پنل تنها از طریق HTTPS در دسترس باشد.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### دسترسی را با فایروال محدود کنید
|
||||
|
||||
تنها پورتهایی را که واقعاً نیاز دارید باز کنید و محدود کردن دسترسی به پنل بر
|
||||
اساس IP را در نظر بگیرید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
میخواهید پنل روی یک دامنهٔ تمیز با HTTPS خودکار باشد؟ به
|
||||
[Reverse proxy](/docs/operations/reverse-proxy) مراجعه کنید. برای ایمنسازی
|
||||
عمیقتر، به [Security](/docs/operations/security) مراجعه کنید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: آشنایی با 3x-ui
|
||||
description: یک پنل تحت وب برای Xray-core — ورودیها، پروتکلها، کلاینتها و اشتراکها را بهجای ویرایش دستی JSON، از مرورگر خود مدیریت کنید.
|
||||
icon: Info
|
||||
---
|
||||
|
||||
**3x-ui** یک پنل کنترل تحت وب است که روی
|
||||
[Xray-core](https://github.com/XTLS/Xray-core)، همان موتور پروکسی که در واقع
|
||||
ترافیک شما را جابهجا میکند، قرار میگیرد. بهجای نوشتن و بارگذاری مجدد پیکربندی
|
||||
JSON Xray بهصورت دستی، همهچیز — ورودیها، پروتکلها، کلاینتها، گواهیها،
|
||||
اشتراکها — را از یک داشبورد مرورگری مدیریت میکنید.
|
||||
|
||||
## اجزا چگونه کنار هم کار میکنند
|
||||
|
||||
<Mermaid
|
||||
chart={`
|
||||
flowchart LR
|
||||
Admin["Admin browser"] -->|HTTPS panel| Panel["3x-ui panel"]
|
||||
Panel -->|writes config, reloads| Xray["Xray-core"]
|
||||
Panel --- DB[("SQLite or PostgreSQL")]
|
||||
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
||||
Xray -->|proxied traffic| Internet["Internet"]
|
||||
`}
|
||||
/>
|
||||
|
||||
- **پنل** لایهٔ مدیریت است: پیکربندی شما را در یک پایگاهداده ذخیره میکند،
|
||||
داشبورد را رندر میکند، یک REST API ارائه میدهد و پیکربندی زندهٔ Xray را
|
||||
مینویسد.
|
||||
- **Xray-core** لایهٔ داده است: اتصالات کلاینت را روی **ورودیهای** شما
|
||||
پایان میدهد و ترافیک را به مقصدش هدایت میکند.
|
||||
- **اپلیکیشنهای کلاینت** (مانند v2rayNG، Clash/Mihomo، Hiddify و دیگران) با
|
||||
استفاده از یک لینک اشتراکگذاری یا اشتراکی که پنل برای هر کلاینت تولید میکند
|
||||
متصل میشوند.
|
||||
|
||||
## چه چیزی در اختیار شما میگذارد
|
||||
|
||||
- داشبوردی برای **ورودیها** در تمام پروتکلهای اصلی — VLESS، VMess،
|
||||
Trojan، Shadowsocks، WireGuard، Hysteria2، SOCKS، HTTP و Dokodemo-door.
|
||||
- پشتیبانی درجهیک از **REALITY** و **XTLS-Vision** برای ترانسپورتهای مخفی
|
||||
و سریع.
|
||||
- سهمیههای ترافیک **بهازای هر کلاینت**، تاریخهای انقضا، محدودیتهای IP،
|
||||
وضعیت آنلاین و لینکهای اشتراکگذاری / کدهای QR با یک کلیک.
|
||||
- **اشتراکها** در قالبهای VLESS، Clash/Mihomo و JSON.
|
||||
- ابزارهای عملیاتی: مدیریت **چندنودی**، یک **ربات Telegram**، پشتیبانگیری،
|
||||
محدودسازی IP مبتنی بر Fail2ban و یک REST API مستندشده.
|
||||
|
||||
## پشت صحنه
|
||||
|
||||
| لایه | فناوری |
|
||||
| ------------ | -------------------------------------------- |
|
||||
| بکاند | Go با فریمورک وب Gin |
|
||||
| فرانتاند | TypeScript / React |
|
||||
| پایگاهداده | SQLite (پیشفرض) یا PostgreSQL |
|
||||
| موتور پروکسی | Xray-core (همراه و مدیریتشده توسط پنل) |
|
||||
|
||||
پایگاهدادهٔ پیشفرض SQLite در مسیر `/etc/x-ui/x-ui.db` قرار دارد و پنل بهصورت
|
||||
پیشفرض روی پورت **2053** گوش میدهد. هر دو قابل پیکربندی هستند — به
|
||||
[نخستین ورود](/docs/guide/first-login) و مرجع متغیرهای محیطی مراجعه کنید.
|
||||
|
||||
## برای چه کسانی است
|
||||
|
||||
3x-ui برای هر کسی که سرور Xray خودش را اجرا میکند طراحی شده است: از یک
|
||||
VPS شخصی منفرد تا اپراتورهایی که نودها و کلاینتهای فراوانی را مدیریت میکنند. اگر
|
||||
قدرت Xray-core را میخواهید بدون اینکه در فایلهای پیکربندی JSON زندگی کنید، این
|
||||
برای شماست.
|
||||
|
||||
<Callout type="info">
|
||||
3x-ui یک فورک ارتقایافته از پروژهٔ اصلی X-UI است که پشتیبانی گستردهتری از
|
||||
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت
|
||||
چندنودی و بسیاری از قابلیتهای راحتیبخش را اضافه میکند.
|
||||
</Callout>
|
||||
|
||||
آمادهاید نصب کنید؟ به [نصب](/docs/guide/installation) ادامه دهید.
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
title: نصب
|
||||
description: نصب 3x-ui با اسکریپت رسمی (نسخهٔ پایدار، نسخهٔ مشخص یا dev-latest)، نصب خودکار/cloud-init یا Docker — و انتخاب میان SQLite و PostgreSQL.
|
||||
icon: Download
|
||||
---
|
||||
|
||||
3x-ui روی طیف گستردهای از توزیعهای Linux اجرا میشود — Ubuntu، Debian، Armbian،
|
||||
Fedora، CentOS، RHEL، AlmaLinux، Rocky Linux، Oracle Linux، Amazon Linux،
|
||||
Virtuozzo، Arch، Manjaro، openSUSE (Tumbleweed/Leap)، Alpine — و همچنین Windows،
|
||||
روی معماریهای `amd64`، `386`، `arm64`، `armv7`، `armv6`، `armv5` و `s390x`.
|
||||
|
||||
<Callout type="warn">
|
||||
نصبکنندهٔ اسکریپتی را بهصورت **root** (یا با `sudo`) اجرا کنید. این اسکریپت یک
|
||||
سرویس نصب میکند، دستور مدیریتی `x-ui` را راهاندازی میکند و پنل را در زمان
|
||||
بوت فعال میسازد.
|
||||
</Callout>
|
||||
|
||||
<Tabs items={['Script', 'Docker', 'Manual']}>
|
||||
|
||||
<Tab value="Script">
|
||||
|
||||
اسکریپت رسمی مسیر توصیهشده است. این اسکریپت در طول نصب یک نام کاربری، رمز عبور و
|
||||
مسیر دسترسی (مسیر پایهٔ وب) **تصادفی** تولید میکند، سرویس را راهاندازی میکند و
|
||||
دستور مدیریتی `x-ui` را نصب میکند.
|
||||
|
||||
```bash title="latest stable"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
برای نصب یک **نسخهٔ مشخص**، تگ آن را در انتها اضافه کنید:
|
||||
|
||||
```bash title="pinned version"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
||||
```
|
||||
|
||||
برای نصب نسخهٔ **dev** غلتان (آخرین پیشانتشار بهازای هر کامیت از شاخهٔ `main`
|
||||
— نه یک نسخهٔ پایدار) عبارت `dev-latest` را پاس دهید:
|
||||
|
||||
```bash title="rolling dev build"
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
||||
```
|
||||
|
||||
پس از پایان نصب، مشخصات ورود چاپشده را یادداشت کنید و دستور `x-ui` را اجرا کنید تا
|
||||
[منوی مدیریت](/docs/guide/update-uninstall#the-x-ui-management-menu) باز شود، سپس
|
||||
به [نخستین ورود](/docs/guide/first-login) ادامه دهید.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab value="Docker">
|
||||
|
||||
پیکربندی پیشفرض Compose از SQLite استفاده میکند. مخزن را کلون کنید (یا فایلهای
|
||||
`docker-compose.yml` و `Dockerfile` آن را کپی کنید) و آن را اجرا کنید:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
برای اجرا با سرویس **PostgreSQL** همراه، دو خط `XUI_DB_*` را در
|
||||
`docker-compose.yml` از حالت کامنت خارج کنید و با پروفایل مربوطه اجرا کنید:
|
||||
|
||||
```bash
|
||||
docker compose --profile postgres up -d
|
||||
```
|
||||
|
||||
ترجیح میدهید از ایمیج ازپیشساخته استفاده کنید؟ این ایمیج روی GitHub Container Registry
|
||||
منتشر شده است. این ایمیج Fail2ban را بههمراه دارد (برای [محدودیتهای IP](/docs/operations/security))
|
||||
که با `iptables` مسدودسازی انجام میدهد و بنابراین به `NET_ADMIN` (و `NET_RAW` برای IPv6)
|
||||
نیاز دارد — در غیر این صورت مسدودسازیها فقط ثبت میشوند ولی هرگز اعمال نمیشوند:
|
||||
|
||||
```bash title="docker run"
|
||||
docker run -d \
|
||||
--cap-add=NET_ADMIN \
|
||||
--cap-add=NET_RAW \
|
||||
-e XUI_ENABLE_FAIL2BAN=true \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/mhsanaei/3x-ui:latest
|
||||
```
|
||||
|
||||
والیوم `db/` پایگاهدادهٔ SQLite (`/etc/x-ui/x-ui.db`) را نگه میدارد و `cert/`
|
||||
گواهیهای TLS را، بنابراین دادههای شما در ارتقاها حفظ میشوند.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab value="Manual">
|
||||
|
||||
برای کاربران پیشرفته، یک آرشیو انتشار متناسب با معماری خود را از
|
||||
[صفحهٔ releases](https://github.com/MHSanaei/3x-ui/releases) دانلود کنید، آن را
|
||||
استخراج کنید و باینری را بهعنوان یک سرویس systemd اجرا کنید. اسکریپت نصب دقیقاً
|
||||
همین مراحل را خودکار میکند، بنابراین مگر اینکه دلیل خاصی برای نصب دستی داشته
|
||||
باشید، روش اسکریپتی ترجیح داده میشود.
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## دستور نصب خود را بسازید
|
||||
|
||||
دستور را متناسب با تنظیمات خود سفارشی کنید:
|
||||
|
||||
<InstallCommandBuilder />
|
||||
|
||||
## انتخاب یک پایگاهداده
|
||||
|
||||
شما بکاند ذخیرهسازی را در زمان نصب انتخاب میکنید:
|
||||
|
||||
- **SQLite** (پیشفرض) — یک فایل واحد در مسیر `/etc/x-ui/x-ui.db`. بدون نیاز به هیچ تنظیماتی.
|
||||
- **PostgreSQL** — برای تعداد کلاینت بالا یا پیکربندیهای چندنودی. نصبکننده
|
||||
میتواند آن را بهصورت محلی نصب کند یا از یک DSN که شما ارائه میدهید استفاده کند.
|
||||
|
||||
برای جزئیات و مهاجرت SQLite→PostgreSQL به [پایگاهداده](/docs/reference/database)
|
||||
مراجعه کنید.
|
||||
|
||||
## نصب خودکار / cloud-init
|
||||
|
||||
نصبکننده برای خودکارسازی بهصورت **غیرتعاملی** نیز اجرا میشود.
|
||||
`XUI_NONINTERACTIVE=1` را تنظیم کنید (یا بدون TTY اجرا کنید) تا نصب بهصورت
|
||||
سرتاسری و بدون هیچ پرسشی انجام شود، مشخصات تصادفی تولید کند و آنها را در
|
||||
`/etc/x-ui/install-result.env` بنویسد:
|
||||
|
||||
```bash
|
||||
XUI_NONINTERACTIVE=1 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
دایرکتوری [`deploy/`](https://github.com/MHSanaei/3x-ui/tree/main/deploy) در مخزن
|
||||
یک user-data آمادهٔ **cloud-init** برای نصبهای خودکار روی هر ابری (Hetzner، AWS،
|
||||
DigitalOcean، Vultr، GCP، Azure، Oracle) دارد.
|
||||
|
||||
## گامهای بعدی
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="نخستین ورود"
|
||||
href="/docs/guide/first-login"
|
||||
description="به پنل دسترسی پیدا کنید و آن را ایمن کنید."
|
||||
/>
|
||||
<Card
|
||||
title="بهروزرسانی و حذف نصب"
|
||||
href="/docs/guide/update-uninstall"
|
||||
description="منوی x-ui، بهروزرسانیها و حذف."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="نخستین ورودی مخفی خود را پیکربندی کنید."
|
||||
/>
|
||||
</Cards>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "شروع به کار",
|
||||
"icon": "Rocket",
|
||||
"pages": ["index", "installation", "first-login", "update-uninstall"]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: بهروزرسانی و حذف
|
||||
description: مدیریت 3x-ui با منوی x-ui و خط فرمان — بهروزرسانی (پایدار، dev یا نسخههای قدیمی)، تغییر تنظیمات و حذف تمیز و کامل.
|
||||
icon: RefreshCw
|
||||
---
|
||||
|
||||
پس از نصب با اسکریپت، دستور `x-ui` مرکز کنترل شماست. آن را بدون هیچ آرگومانی اجرا
|
||||
کنید تا منوی تعاملی باز شود، یا یک زیردستور به آن بدهید تا یک عملیات تکمرحلهای انجام شود.
|
||||
|
||||
```bash
|
||||
x-ui
|
||||
```
|
||||
|
||||
## منوی مدیریت `x-ui`
|
||||
|
||||
منو (آیتمهای `0`–`28`) وضعیت پنل/Xray را در بالا نشان میدهد و سپس:
|
||||
|
||||
| # | آیتم | کاری که انجام میدهد |
|
||||
| ----- | -------------------------------------- | --------------------------------------------------------- |
|
||||
| 1 | Install | (دوباره) نصب از روی اسکریپت راه دور |
|
||||
| 2 | Update | بهروزرسانی به آخرین نسخهٔ **پایدار** |
|
||||
| 3 | Update to Dev Channel (latest commit) | بهروزرسانی به بیلد غلتان `dev-latest` |
|
||||
| 4 | Update Menu | بهروزرسانی فقط اسکریپت منوی `x-ui` |
|
||||
| 5 | Legacy Version | نصب یک نسخهٔ قدیمی مشخص (تگ را میپرسد) |
|
||||
| 6 | Uninstall | حذف 3x-ui (در ادامه ببینید) |
|
||||
| 7 | Reset Username & Password | تنظیم مشخصات جدید؛ اختیاراً غیرفعالکردن 2FA |
|
||||
| 8 | Reset Web Base Path | تصادفیکردن مسیر پایهٔ وب |
|
||||
| 9 | Reset Settings | بازنشانی تنظیمات پنل (حساب شما حفظ میشود) |
|
||||
| 10 | Change Port | تغییر پورت پنل |
|
||||
| 11 | View Current Settings | نمایش نام کاربری، پورت، مسیر پایهٔ وب، مسیرهای گواهی |
|
||||
| 12–14 | Start / Stop / Restart | کنترل سرویس پنل |
|
||||
| 15 | Restart Xray | بارگذاری مجدد فقط Xray-core |
|
||||
| 16 | Check Status | وضعیت سرویس |
|
||||
| 17 | Logs Management | مشاهدهٔ لاگهای دیباگ / پاکسازی لاگها |
|
||||
| 18–19 | Enable / Disable Autostart | فعال/غیرفعالکردن اجرای خودکار در زمان بوت |
|
||||
| 20 | SSL Certificate Management | Let's Encrypt (دامنه یا IP)، مسیرهای سفارشی، تمدید/ابطال |
|
||||
| 21 | Cloudflare SSL Certificate | گواهی wildcard از طریق DNS-01 با Cloudflare |
|
||||
| 22 | IP Limit Management | محدودیت IP بهازای هر کلاینت مبتنی بر Fail2ban |
|
||||
| 23 | Firewall Management | نصب `ufw` و قواعد پورت |
|
||||
| 24 | SSH Port Forwarding Management | اتصال پنل به localhost و تونلزدن روی SSH |
|
||||
| 25 | PostgreSQL Management | نصب/مهاجرت/مدیریت PostgreSQL |
|
||||
| 26 | Enable BBR | فعال/غیرفعالکردن sysctl کنترل ازدحام BBR |
|
||||
| 27 | Update Geo Files | بهروزرسانی دادهٔ geoip/geosite (Loyalsoldier، IR، RU) |
|
||||
| 28 | Speedtest by Ookla | اجرای تست سرعت Ookla |
|
||||
| 0 | Exit | — |
|
||||
|
||||
برخی از این موارد صفحهٔ مخصوص خود را دارند: [گواهیهای SSL](/docs/config/ssl-certificates)
|
||||
(آیتمهای 20–21)، [امنیت](/docs/operations/security) (محدودیت IP، فایروال)،
|
||||
[پروکسی معکوس](/docs/operations/reverse-proxy) و [تنظیمات پنل](/docs/config/panel)
|
||||
(TLS)، و [پایگاهداده](/docs/reference/database) (PostgreSQL).
|
||||
|
||||
## زیردستورهای خط فرمان
|
||||
|
||||
برای اسکریپتها و اقدامهای سریع، `x-ui` یک زیردستور را هم مستقیماً میپذیرد:
|
||||
|
||||
| دستور | عملیات |
|
||||
| -------------------------- | --------------------------------------------------- |
|
||||
| `x-ui start` / `stop` / `restart` | کنترل سرویس |
|
||||
| `x-ui restart-xray` | بارگذاری مجدد فقط Xray-core |
|
||||
| `x-ui status` | نمایش وضعیت |
|
||||
| `x-ui settings` | نمایش تنظیمات فعلی |
|
||||
| `x-ui enable` / `disable` | فعال/غیرفعالکردن اجرای خودکار در زمان بوت |
|
||||
| `x-ui log` | دنبالکردن لاگ دیباگ |
|
||||
| `x-ui banlog` | نمایش لاگ مسدودسازی Fail2ban |
|
||||
| `x-ui update` | بهروزرسانی به آخرین نسخهٔ پایدار |
|
||||
| `x-ui update-dev` | بهروزرسانی به بیلد غلتان `dev-latest` |
|
||||
| `x-ui legacy` | نصب یک نسخهٔ قدیمی مشخص (میپرسد) |
|
||||
| `x-ui update-all-geofiles` | بهروزرسانی همهٔ فایلهای geo و راهاندازی مجدد در صورت تغییر |
|
||||
| `x-ui migrate-db --dsn …` | مهاجرت SQLite ← PostgreSQL (نگاه کنید به [پایگاهداده](/docs/reference/database)) |
|
||||
| `x-ui install` / `uninstall` | نصب / حذف |
|
||||
|
||||
## بهروزرسانی
|
||||
|
||||
- **پایدار:** گزینهٔ منوی **۲** یا `x-ui update`. اجرای دوبارهٔ اسکریپت نصب هم
|
||||
در همان محل بهروزرسانی میکند.
|
||||
- **کانال dev:** گزینهٔ منوی **۳** یا `x-ui update-dev` — بیلد غلتان
|
||||
`dev-latest` بهازای هر کامیت (نه یک نسخهٔ پایدار).
|
||||
- **یک نسخهٔ قدیمی مشخص:** گزینهٔ منوی **۵** (Legacy Version).
|
||||
|
||||
بهروزرسانی، پایگاهداده و تنظیمات شما را حفظ میکند. پیش از یک جهش نسخهٔ اصلی، یک
|
||||
[پشتیبان](/docs/operations/backup-restore) بگیرید.
|
||||
|
||||
<Callout type="info">
|
||||
کاربران Docker به شیوهٔ دیگری بهروزرسانی میکنند — بهجای استفاده از دستورهای
|
||||
بهروزرسانی `x-ui`، ایمیج جدید را pull کرده و کانتینر را از نو بسازید
|
||||
(`docker compose pull && docker compose up -d`).
|
||||
</Callout>
|
||||
|
||||
## حذف
|
||||
|
||||
گزینهٔ منوی **۶** یا `x-ui uninstall`. سرویس را متوقف و غیرفعال میکند، یونیت سرویس
|
||||
را حذف میکند و `/etc/x-ui/` و پوشهٔ نصب را پاک میکند. اگر پنل از یک PostgreSQL
|
||||
نصبشده بهصورت محلی استفاده میکرده، پیشنهاد میدهد آن را هم پاکسازی کند (یک تأیید
|
||||
جداگانه و برگشتناپذیر).
|
||||
|
||||
<Callout type="warn">
|
||||
حذف، پایگاهداده (`/etc/x-ui/x-ui.db`) و پیکربندی شما را پاک میکند. اگر ممکن است
|
||||
بعداً به آن نیاز داشته باشید، ابتدا [پشتیبان بگیرید](/docs/operations/backup-restore).
|
||||
</Callout>
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: مشارکت
|
||||
description: چگونه در توسعه 3x-ui مشارکت کنید و این مستندات را ترجمه کنید.
|
||||
icon: GitPullRequestArrow
|
||||
---
|
||||
|
||||
3x-ui یک پروژه جامعهمحور است. مشارکت در پنل و در این مستندات با آغوش باز پذیرفته
|
||||
میشود.
|
||||
|
||||
## حمایت از توسعهدهنده
|
||||
|
||||
3x-ui رایگان و متنباز است و بهصورت عمومی ساخته و نگهداری میشود. اگر برایتان
|
||||
مفید بوده است، حمایت از ادامه توسعه را در نظر بگیرید:
|
||||
|
||||
- در [donate.sanaei.dev](https://donate.sanaei.dev/) **کمک مالی** کنید — این صفحه
|
||||
**اهداف و سقفهای** جاری تأمین مالی را که میتوانید در رسیدن به آنها کمک کنید نشان میدهد.
|
||||
- به [مخزن](https://github.com/MHSanaei/3x-ui) **ستاره** بدهید و پروژه را به اشتراک
|
||||
بگذارید.
|
||||
- به کانال Telegram یعنی [@XrayUI](https://t.me/XrayUI) **بپیوندید** تا اخبار را
|
||||
دنبال کنید و به دیگران کمک کنید.
|
||||
|
||||
## مشارکت در 3x-ui
|
||||
|
||||
- فایل `CONTRIBUTING.md` پروژه را در
|
||||
[مخزن](https://github.com/MHSanaei/3x-ui) بخوانید.
|
||||
- برای باگها و درخواستهای امکانات جدید، با گامهای بازتولید روشن، issue باز کنید.
|
||||
- از Conventional Commits استفاده کنید و pull requestها را متمرکز نگه دارید.
|
||||
|
||||
## ترجمه مستندات
|
||||
|
||||
این سایت برای ترجمه ساخته شده است. محتوا در مسیر `content/docs/<locale>/`
|
||||
قرار دارد (`en`، `fa`، `ru`، `zh`) و صفحات ترجمهنشده **به انگلیسی بازمیگردند**، بنابراین
|
||||
میتوانید بهصورت تدریجی ترجمه کنید.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### کپی کردن یک صفحه
|
||||
|
||||
یک صفحه را از `content/docs/en/...` به همان مسیر زیر زبان خودتان کپی کنید، برای مثال
|
||||
`content/docs/fa/guide/installation.mdx`.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### فقط متن را ترجمه کنید
|
||||
|
||||
متن اصلی و `title`/`description` در frontmatter را ترجمه کنید. کد، دستورات،
|
||||
نام متغیرهای محیطی، نام پروتکلها یا لینکهای اشتراکگذاری را ترجمه **نکنید**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### به جهت متن توجه کنید
|
||||
|
||||
فارسی (`fa`) از راست به چپ نمایش داده میشود. بلوکهای کد و لینکها را از چپ به راست
|
||||
نگه دارید (طرحبندی این مورد را بهطور خودکار مدیریت میکند) و صفحه را در هر دو جهت بررسی کنید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
نبودن یک صفحه در زبان شما اشکالی ندارد — بهجای خطای 404 به انگلیسی بازمیگردد.
|
||||
ابتدا صفحات با بیشترین بازدید را ترجمه کنید (نصب، نخستین ورود،
|
||||
REALITY).
|
||||
</Callout>
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: سؤالات متداول
|
||||
description: پرسشهای پرتکرار درباره 3x-ui — مجوز، سیستمهای پشتیبانیشده، پایگاههای داده و کلاینتها.
|
||||
icon: CircleQuestionMark
|
||||
---
|
||||
|
||||
## آیا 3x-ui رایگان و متنباز است؟
|
||||
|
||||
بله. 3x-ui تحت مجوز GPL-3.0 متنباز است. کد منبع آن روی
|
||||
[GitHub](https://github.com/MHSanaei/3x-ui) در دسترس است.
|
||||
|
||||
## روی چه سیستمهایی اجرا میشود؟
|
||||
|
||||
روی بیشتر توزیعهای اصلی Linux (Ubuntu، Debian، CentOS/RHEL و مشتقات آنها،
|
||||
Fedora، Arch، Alpine و موارد دیگر) روی معماریهای `amd64`، `arm64` و دیگر معماریها.
|
||||
همچنین بهصورت یک کانتینر Docker اجرا میشود. به [نصب](/docs/guide/installation) مراجعه کنید.
|
||||
|
||||
## SQLite یا PostgreSQL؟
|
||||
|
||||
SQLite گزینه پیشفرض است و برای بیشتر استقرارها مناسب است. PostgreSQL برای
|
||||
راهاندازیهای بزرگتر از طریق `XUI_DB_TYPE=postgres` و `XUI_DB_DSN` در دسترس است — به
|
||||
[متغیرهای محیطی](/docs/reference/env-vars) مراجعه کنید.
|
||||
|
||||
## کدام اپلیکیشنهای کلاینت با آن کار میکنند؟
|
||||
|
||||
هر کلاینت سازگار با Xray — برای مثال v2rayNG، Hiddify و Clash/Mihomo.
|
||||
لینک اشتراکگذاری یا کد QR یک کلاینت را وارد کنید، یا از
|
||||
[سابسکریپشن](/docs/config/subscription) استفاده کنید.
|
||||
|
||||
## 3x-ui چه تفاوتی با x-ui دارد؟
|
||||
|
||||
3x-ui یک فورک ارتقایافته از پروژه اصلی X-UI است. این پروژه پشتیبانی گستردهتری از
|
||||
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت چندنودی،
|
||||
یک رابط کاربری ۱۳ زبانه و بسیاری از امکانات رفاهی را اضافه میکند.
|
||||
|
||||
## چگونه بهروزرسانی کنم؟
|
||||
|
||||
اسکریپت نصب را دوباره اجرا کنید (بهصورت درجا بهروزرسانی میشود)، یا ایمیج جدید Docker را دریافت کنید.
|
||||
به [نصب](/docs/guide/installation) و
|
||||
[صفحه نسخهها](https://github.com/MHSanaei/3x-ui/releases) مراجعه کنید.
|
||||
|
||||
## از کجا میتوانم کمک بگیرم؟
|
||||
|
||||
به کانال رسمی Telegram با نشانی [@XrayUI](https://t.me/XrayUI) برای
|
||||
اطلاعیهها و پشتیبانی انجمن بپیوندید، یا یک ایشو روی
|
||||
[GitHub](https://github.com/MHSanaei/3x-ui/issues) باز کنید. برای مشکلات رایج، با
|
||||
[عیبیابی](/docs/help/troubleshooting) شروع کنید.
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "راهنما",
|
||||
"icon": "LifeBuoy",
|
||||
"pages": ["troubleshooting", "faq", "migration", "contributing"]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: مهاجرت
|
||||
description: مهاجرت به 3x-ui از x-ui، بین سرورها یا بین نسخههای 3x-ui.
|
||||
icon: ArrowRightLeft
|
||||
---
|
||||
|
||||
## بین سرورها
|
||||
|
||||
انتقال به سرور جدید در واقع یک جابهجایی پایگاهداده است:
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### از سرور قدیمی نسخه پشتیبان بگیرید
|
||||
|
||||
از پایگاهداده (بهصورت پیشفرض `/etc/x-ui/x-ui.db`) و گواهینامههای خود یک کپی تهیه کنید.
|
||||
[پشتیبانگیری و بازیابی](/docs/operations/backup-restore) را ببینید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### 3x-ui را روی سرور جدید نصب کنید
|
||||
|
||||
از همان روش نصب و یک نسخهٔ سازگار استفاده کنید.
|
||||
[نصب](/docs/guide/installation) را ببینید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پایگاهداده را بازیابی کنید
|
||||
|
||||
پنل را متوقف کنید، پایگاهداده را در جای خود قرار دهید، گواهینامهها را بازیابی کرده و پنل را راهاندازی کنید. هر تنظیم وابسته به IP یا دامنه را بهروزرسانی کنید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## بین نسخههای 3x-ui
|
||||
|
||||
در محدودهٔ یک backend یکسان، ارتقا معمولاً تنها به اجرای دوبارهٔ نصبکننده یا
|
||||
کشیدن یک image جدید خلاصه میشود — پنل خودش پایگاهدادهاش را مهاجرت میدهد. هنگام تغییر بین نسخههای **اصلی**،
|
||||
ابتدا [یادداشتهای انتشار](https://github.com/MHSanaei/3x-ui/releases)
|
||||
را بخوانید و یک نسخهٔ پشتیبان تهیه کنید.
|
||||
|
||||
## از x-ui
|
||||
|
||||
وارد کردن مستقیم پایگاهدادهٔ یک پنل قدیمی x-ui به 3x-ui **پشتیبانی نمیشود** —
|
||||
چون ساختار schema آنها متفاوت است. 3x-ui را از نو نصب کنید و inboundها/کلاینتها را
|
||||
دوباره بسازید و در همین حین لینکهای اشتراکگذاری را از پنل قدیمی خروجی بگیرید.
|
||||
|
||||
<Callout type="warn">
|
||||
پیش از هر مهاجرتی همیشه یک نسخهٔ پشتیبان تهیه کنید و سرور قدیمی را تا زمانی که
|
||||
از درستی عملکرد سرور جدید مطمئن نشدهاید، روشن نگه دارید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: عیبیابی
|
||||
description: رفع مشکلات رایج 3x-ui — اجرا نشدن پنل، خطاهای 502، مشکلات گواهی و کلاینتهایی که نمیتوانند متصل شوند.
|
||||
icon: Wrench
|
||||
---
|
||||
|
||||
فهرستی برای رسیدگی به رایجترین مشکلات. هرگاه مطمئن نبودید، سطح لاگ را بالا ببرید
|
||||
(`XUI_LOG_LEVEL=debug`) و لاگهای پنل و Xray را بررسی کنید.
|
||||
|
||||
## پنل اجرا نمیشود
|
||||
|
||||
- وضعیت سرویس و لاگها را بررسی کنید (منوی `x-ui` ← وضعیت/لاگها).
|
||||
- مطمئن شوید که **پورت پنل از قبل توسط سرویس دیگری اشغال نشده** باشد.
|
||||
- بررسی کنید که مسیر دیتابیس قابل نوشتن باشد (پیشفرض `/etc/x-ui/x-ui.db`).
|
||||
|
||||
## خطای 502 / در دسترس نبودن پنل پشت یک پروکسی
|
||||
|
||||
- مطمئن شوید که پنل واقعاً روی پورت upstream در حال شنود است (مثلاً `2053`).
|
||||
- اطمینان حاصل کنید که [پروکسی معکوس](/docs/operations/reverse-proxy) شما هدرهای
|
||||
ارتقای WebSocket را عبور میدهد و به پورت درست و **مسیر پایه وب** صحیح اشاره میکند.
|
||||
- بررسی کنید که فایروال اتصال پروکسی ← پنل را مسدود نکرده باشد.
|
||||
|
||||
## مشکلات گواهی
|
||||
|
||||
- پیش از صدور گواهی، DNS دامنه باید به سرور اشاره کند.
|
||||
- پورتهای 80/443 باید برای اعتبارسنجی HTTP/TLS در دسترس باشند (یا از اعتبارسنجی DNS استفاده کنید).
|
||||
- برای REALITY به یاد داشته باشید که **به هیچ گواهی نیازی ندارد** — مشکل معمولاً یک
|
||||
`dest`/SNI نادرست است (به [نکات کلیدی REALITY](/docs/config/reality) مراجعه کنید).
|
||||
|
||||
## یک کلاینت نمیتواند متصل شود
|
||||
|
||||
- لینک کلاینت را با
|
||||
[بازرس لینک اشتراک](/docs/config/share-links) رمزگشایی کنید و تکتک پارامترها را تأیید کنید.
|
||||
- بررسی کنید که **transport و security در دو طرف مطابقت داشته باشند**.
|
||||
- مطمئن شوید که کلاینت به **محدودیت ترافیک، انقضا یا IP** خود نرسیده باشد.
|
||||
- اطمینان حاصل کنید که پورت inbound در فایروال باز است.
|
||||
|
||||
<Callout type="info">
|
||||
همچنان به مشکل خوردهاید؟ در میان
|
||||
[مسائل GitHub](https://github.com/MHSanaei/3x-ui/issues) جستوجو کنید — احتمالاً
|
||||
علامت مشکل شما قبلاً دیده شده است.
|
||||
</Callout>
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: مستندات 3x-ui
|
||||
description: مستندات رسمی 3x-ui — یک پنل وب پیشرفته برای مدیریت سرورهای Xray-core، پروکسیها، کلاینتها و سابسکریپشنها.
|
||||
icon: House
|
||||
---
|
||||
|
||||
**3x-ui** یک پنل وب متنباز برای استقرار و مدیریت سرورهای
|
||||
[Xray-core](https://github.com/XTLS/Xray-core) است. این پنل یک داشبورد مدرن برای
|
||||
اینباندها، پروتکلها، کلاینتها، حسابداری ترافیک، سابسکریپشنها و موارد دیگر در
|
||||
اختیار شما میگذارد — بدون نیاز به ویرایش دستی JSON مربوط به Xray از طریق خط فرمان.
|
||||
|
||||
این سایت، مستندات رسمی و مجموعهای از **ابزارهای تعاملی و درونمرورگری**
|
||||
(تولیدکنندههای پیکربندی) است که کاملاً روی دستگاه شما اجرا میشوند — هیچ دادهای
|
||||
هرگز از صفحه خارج نمیشود.
|
||||
|
||||
## از اینجا شروع کنید
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="3x-ui چیست؟"
|
||||
href="/docs/guide"
|
||||
description="نمای کلی: Xray-core، پنل، و اینکه برای چه کسانی مناسب است."
|
||||
/>
|
||||
<Card
|
||||
title="نصب"
|
||||
href="/docs/guide/installation"
|
||||
description="نصب از طریق اسکریپت، Docker یا بهصورت دستی."
|
||||
/>
|
||||
<Card
|
||||
title="نخستین ورود"
|
||||
href="/docs/guide/first-login"
|
||||
description="به پنل دسترسی پیدا کنید و پیش از هر کار دیگری آن را ایمنسازی کنید."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="راهاندازی VLESS + REALITY همراه با XTLS-Vision."
|
||||
/>
|
||||
</Cards>
|
||||
|
||||
## ویژگیهای شاخص
|
||||
|
||||
- **همه پروتکلهای اصلی** — VLESS، VMess، Trojan، Shadowsocks، WireGuard،
|
||||
Hysteria2، SOCKS، HTTP و Dokodemo-door.
|
||||
- **REALITY و XTLS-Vision** — ترنسپورتهای مدرن و مقاوم در برابر سانسور.
|
||||
- **کنترلهای اختصاصی هر کلاینت** — سهمیه ترافیک، تاریخ انقضا، محدودیت IP، لینکهای
|
||||
اشتراکگذاری و کدهای QR.
|
||||
- **سابسکریپشنها** — قالبهای VLESS، Clash/Mihomo و JSON.
|
||||
- **عملیات** — مدیریت چندنودی، ربات Telegram، پشتیبانگیری و یک REST API.
|
||||
|
||||
<Callout type="info">
|
||||
با Xray تازه آشنا شدهاید؟ ابتدا [3x-ui چیست؟](/docs/guide) را بخوانید — توضیح میدهد که پنل، Xray-core و
|
||||
اپلیکیشنهای کلاینت شما چگونه در کنار هم کار میکنند.
|
||||
</Callout>
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"pages": ["index", "guide", "config", "operations", "reference", "help"]
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: پشتیبانگیری و بازیابی
|
||||
description: از پایگاهداده و گواهیهای 3x-ui خود بهصورت دستی یا از طریق ربات Telegram پشتیبان بگیرید و آنها را بازیابی کنید.
|
||||
icon: DatabaseBackup
|
||||
---
|
||||
|
||||
تمام پیکربندی شما — ورودیها، کلاینتها و تنظیمات — در پایگاهدادهی پنل
|
||||
قرار دارد. مرتب از آن پشتیبان بگیرید تا بتوانید بازیابی یا مهاجرت کنید.
|
||||
|
||||
## از چه چیزی پشتیبان بگیریم
|
||||
|
||||
- **پایگاهداده** — بهصورت پیشفرض یک SQLite در `/etc/x-ui/x-ui.db` (یا پایگاهدادهی
|
||||
PostgreSQL شما اگر از آن backend استفاده میکنید).
|
||||
- **گواهیها** — هر چیزی که زیر `/root/cert/` (یا هر جایی که گواهیهای TLS را نگه میدارید)
|
||||
قرار دارد.
|
||||
|
||||
## پشتیبانگیری دستی
|
||||
|
||||
میتوانید یک نسخهی پشتیبان را از صفحهی نمای کلی پنل دانلود کنید، یا فایل پایگاهداده را
|
||||
مستقیماً از سرور کپی نمایید:
|
||||
|
||||
```bash title="copy the SQLite database"
|
||||
cp /etc/x-ui/x-ui.db /root/x-ui-backup-$(date +%F).db
|
||||
```
|
||||
|
||||
برای بازیابی، پنل را متوقف کنید، پایگاهداده را سر جای خود برگردانید و دوباره آن را اجرا کنید.
|
||||
|
||||
<Callout type="warn">
|
||||
هر وقت ممکن است، یک نسخهی پشتیبان را روی **همان نسخهی اصلی (major)** که از آن گرفته شده
|
||||
بازیابی کنید. در ارتقاهای میاننسخهای اصلی، بهجای تحمیل یک شِمای قدیمی، بگذارید پنل
|
||||
مهاجرتهای خود را اجرا کند.
|
||||
</Callout>
|
||||
|
||||
## پشتیبانگیری با Telegram
|
||||
|
||||
اگر [ربات Telegram](/docs/operations/telegram-bot) را پیکربندی کردهاید، گزینهی
|
||||
**`tgBotBackup`** را فعال کنید تا یک نسخهی پشتیبان به گزارش دورهای ضمیمه شود (بر اساس
|
||||
زمانبندی `tgRunTime`، بهصورت پیشفرض روزانه). ربات هم **پایگاهداده** و هم **`config.json`
|
||||
مربوط به Xray** را به چت ادمین شما میفرستد، بنابراین همیشه یک نسخهی خارج از سرور در اختیار
|
||||
دارید. ادمینها همچنین میتوانند بهصورت درخواستی از منوی ربات یک نسخهی پشتیبان بخواهند.
|
||||
|
||||
## دامپ / بازیابی SQLite
|
||||
|
||||
دستور `x-ui migrate-db` پایگاهدادهی SQLite را به یک دامپ متنی SQL ساده و بالعکس تبدیل
|
||||
میکند (برای بررسی یا انتقال میان دستگاهها کاربردی است):
|
||||
|
||||
```bash
|
||||
x-ui migrate-db --dump /root/x-ui.sql # SQLite -> SQL text
|
||||
x-ui migrate-db --restore /root/x-ui.sql # SQL text -> SQLite
|
||||
```
|
||||
|
||||
برای مهاجرت به PostgreSQL، به [پایگاهداده](/docs/reference/database) مراجعه کنید.
|
||||
|
||||
<Callout type="info">
|
||||
از هر روشی که استفاده میکنید، نسخههای پشتیبان را **خارج از سرور** نگه دارید و هرازگاهی
|
||||
یک بازیابی را آزمایش کنید — یک نسخهی پشتیبانِ آزمایشنشده، پشتیبان بهحساب نمیآید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "عملیات",
|
||||
"icon": "ServerCog",
|
||||
"pages": [
|
||||
"reverse-proxy",
|
||||
"multi-node",
|
||||
"outbounds-routing",
|
||||
"backup-restore",
|
||||
"telegram-bot",
|
||||
"security"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: چندنودی و میزبانهای مدیریتشده
|
||||
description: مدیریت چند پنل 3x-ui از یک مستر، با اعتماد مبتنی بر توکن API یا mTLS، ضربان قلب، و بازنویسی میزبان برای هر inbound جهت اشتراکها.
|
||||
icon: Boxes
|
||||
---
|
||||
|
||||
3x-ui میتواند **چندین سرور** را از یک پنل مستر واحد مدیریت کند و با **میزبانهای مدیریتشده** نحوهٔ معرفی هر inbound در اشتراکها را بازنویسی کند.
|
||||
|
||||
## نودها
|
||||
|
||||
یک **نود** پنل 3x-ui دیگری است که پنل مستر شما آن را از طریق API نود مدیریت میکند. مستر هر نود را فراخوانی (poll) میکند و وضعیت، نسخهها، CPU/حافظه، آپتایم و ترافیک آن را در یک مکان نمایش میدهد.
|
||||
|
||||
### افزودن یک نود
|
||||
|
||||
جزئیات اتصال نود را وارد کنید:
|
||||
|
||||
| فیلد | توضیحات |
|
||||
| ----------------- | --------------------------------------------------------------------- |
|
||||
| **Name** | برچسب یکتا (مثلاً `de-fra-1`). |
|
||||
| **Scheme** | `https` (پیشفرض) یا `http`. |
|
||||
| **Address / Port**| میزبان و پورت پنل نود. |
|
||||
| **Base path** | مسیر پایهٔ وب نود. |
|
||||
| **API token** | یک توکن Bearer که روی نود ساخته میشود (در حالت mTLS لازم نیست). |
|
||||
| **TLS verify** | `verify` (پیشفرض)، `skip`، `pin` (پینکردن SHA-256 گواهی) یا `mtls`. |
|
||||
| **Inbound sync** | همهٔ inboundها (`all`) یا انتخابشده (`selected`) بر اساس تگ. |
|
||||
| **Outbound tag** | بهاختیار از طریق یک outbound نامدار به نود برسید (پل خروجی). |
|
||||
|
||||
مستر هنگام افزودن یا آزمودن یک نود، قابلیت دسترسی به آن را بررسی میکند. سپس هر چند ثانیه یک **ضربان قلب (heartbeat)** ارسال میکند، وضعیت نود را بهروزرسانی میکند (`online` / `offline`) و رویدادهای `node.up` / `node.down` را منتشر میکند (به [بات Telegram](/docs/operations/telegram-bot) مراجعه کنید).
|
||||
|
||||
<Callout type="info">
|
||||
نودها با یک GUID پایدار بهازای هر پنل شناسایی میشوند، بنابراین یک نود هویت خود
|
||||
را در طول راهاندازیهای مجدد حفظ میکند. یک نود میتواند خودش نودهای دیگری را
|
||||
مدیریت کند — مستر آنها را بهصورت زیرنودهای **گذرا (transitive)** فقطخواندنی نمایش
|
||||
میدهد (Node 1 ← Node 2 ← Node 3).
|
||||
</Callout>
|
||||
|
||||
### TLS دوطرفه (mTLS) بین مستر و نود
|
||||
|
||||
برای قویترین سطح اعتماد، از `tlsVerifyMode = mtls` استفاده کنید (نیازمند `https`):
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### CA مستر را دریافت کنید
|
||||
|
||||
روی مستر، گواهی CA احراز هویت نود آن را دریافت کنید (کلید خصوصی CA هرگز از پنل
|
||||
خارج نمیشود).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### آن را روی نود مورد اعتماد قرار دهید
|
||||
|
||||
آن CA را در تنظیم «trusted CA» نود جایگذاری کنید. در راهاندازی مجدد بعدی نود
|
||||
اعمال میشود.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### نود را به حالت mTLS تغییر دهید
|
||||
|
||||
حالت TLS verify نود را روی `mtls` تنظیم کنید. اکنون مستر بهجای یک توکن API یک
|
||||
گواهی کلاینت ارائه میدهد.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## میزبانهای مدیریتشده
|
||||
|
||||
یک **میزبان مدیریتشده** یک نقطهٔ پایانی بازنویسی است که به یک inbound متصل میشود. در زمان اشتراک، هر میزبان فعال یک لینک اشتراکگذاری / پراکسی اضافی با آدرس، پورت، TLS، SNI، هدر host، مسیر و موارد دیگر مخصوص خود تولید میکند — که جایگزین فهرست قدیمیتر «external proxy» میشود. از آنها برای موارد زیر استفاده کنید:
|
||||
|
||||
- قراردادن یک inbound پشت یک **CDN** (Cloudflare) با آدرس/SNI متفاوت،
|
||||
- معرفی **چند دامنه** یا نقاط پایانی بهازای هر منطقه برای یک inbound،
|
||||
- تنظیم ALPN، fingerprint، ECH یا mux بهازای هر نقطهٔ پایانی.
|
||||
|
||||
هر میزبان یک ملاحظه (remark) دارد (که از همان [متغیرهای قالب](/docs/config/share-links#remark-template-variables) پشتیبانی میکند)، یک کلید فعالسازی، یک ترتیب مرتبسازی، و میتواند **از قالبهای اشتراک خاصی مستثنا شود** یا **به نودهای مشخصی محدود گردد**.
|
||||
|
||||
<Callout type="info">
|
||||
میزبانهایی که آدرس/پورت آنها به یک CDN اشاره میکند، به شما اجازه میدهند آدرس
|
||||
واقعی سرور را خصوصی نگه دارید در حالی که کلاینتها از طریق لبهٔ CDN متصل میشوند.
|
||||
</Callout>
|
||||
|
||||
## مرتبط
|
||||
|
||||
<Cards>
|
||||
<Card title="Outboundها و مسیریابی" href="/docs/operations/outbounds-routing" description="WARP، NordVPN، اشتراکهای outbound و مسیریابی." />
|
||||
<Card title="اشتراک" href="/docs/config/subscription" description="چگونه میزبانها خروجی اشتراک را شکل میدهند." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
title: خروجیها و مسیریابی
|
||||
description: مدیریت ترافیک خروجی در 3x-ui — خروجیهای WARP و NordVPN، اشتراکهای خروجی (مجموعه سرورها)، قواعد مسیریابی و متعادلکنندههای بار.
|
||||
icon: Route
|
||||
---
|
||||
|
||||
ورودیها کلاینتها را میپذیرند؛ **خروجیها** تعیین میکنند ترافیک آنها در ادامه به کجا برود.
|
||||
3x-ui میتواند ترافیک را از طریق Cloudflare WARP، NordVPN یا مجموعههای خروجی دلخواه
|
||||
واردشده از یک اشتراک مسیریابی کند و با قواعد مسیریابی و متعادلکنندهها میان آنها
|
||||
انتخاب نماید.
|
||||
|
||||
## ویرایش خروجیها و مسیریابی
|
||||
|
||||
خروجیها، قواعد مسیریابی، متعادلکنندهها، DNS و ثبت رویداد همگی در **پیکربندی Xray**
|
||||
قرار دارند (همان قالب پیکربندی که زیر Xray Settings ویرایش میکنید). رابط کاربری جداگانهای
|
||||
برای هر قاعده وجود ندارد — شما JSON را ویرایش میکنید و پنل Xray را بارگذاری مجدد میکند. پنل
|
||||
همچنین یک **آزمون اتصالپذیری خروجی** و یک **آزمون مسیر** ارائه میدهد (از هسته در حال اجرا
|
||||
بپرسید که برای یک مقصد مشخص از کدام خروجی استفاده خواهد شد).
|
||||
|
||||
## ساخت یک خروجی
|
||||
|
||||
هر خروجی یک شیء JSON است با حداکثر چهار بخش: یک **`tag`** (که قواعد مسیریابی و
|
||||
متعادلکنندهها به آن ارجاع میدهند)، یک **`protocol`**، **`settings`** مخصوص پروتکل،
|
||||
و — برای پروتکلهای proxy — **`streamSettings`** که باید با انتقال و امنیت ورودی راه دور
|
||||
مطابقت داشته باشد. دو خروجی تقریباً همیشه حضور دارند:
|
||||
|
||||
- **`freedom`** ترافیک را مستقیماً به مقصدش میفرستد — خروجی پیشفرض.
|
||||
بهصورت اختیاری میتوانید یک `domainStrategy` (مثلاً `UseIP`) تنظیم کنید تا نحوه تفکیک نامهای میزبان را کنترل کنید.
|
||||
- **`blackhole`** ترافیک را دور میاندازد. مقصدهای ناخواسته (تبلیغات، تورنتها) را به اینجا هدایت کنید.
|
||||
|
||||
```json title="freedom + blackhole"
|
||||
{
|
||||
"outbounds": [
|
||||
{ "tag": "direct", "protocol": "freedom", "settings": {} },
|
||||
{ "tag": "block", "protocol": "blackhole", "settings": {} }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
یک خروجی **proxy** (VLESS، VMess، Trojan، Shadowsocks) به سرور دیگری ارسال میکند —
|
||||
که برای زنجیرهکردن یا فرستادن ترافیک منتخب به خارج مفید است. به شکلهای سیمی که 3x-ui
|
||||
استفاده میکند توجه کنید: **VLESS شکل تخت است** (`address`/`port`/`id`/`flow`/
|
||||
`encryption`)، **VMess از `settings.vnext[]` استفاده میکند**، و **Trojan/Shadowsocks از
|
||||
`settings.servers[]` استفاده میکنند**. مقدار `streamSettings` باید با
|
||||
[انتقال و امنیت](/docs/config/transports) مقصد همخوانی داشته باشد.
|
||||
|
||||
هر خروجی را در زیر سرهم کنید و JSON را در **Xray Settings → Outbounds** بچسبانید:
|
||||
|
||||
<OutboundGenerator />
|
||||
|
||||
## Cloudflare WARP
|
||||
|
||||
WARP به سرور شما امکان میدهد ترافیک خود را از طریق شبکه Cloudflare خارج کند. 3x-ui میتواند
|
||||
یک حساب WARP برای شما ثبت کند و آن را به یک خروجی WireGuard با برچسب **`warp`** متصل نماید:
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### افزودن یک خروجی با برچسب `warp`
|
||||
|
||||
یک خروجی WireGuard با برچسب `warp` در پیکربندی Xray خود بسازید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### ثبت WARP
|
||||
|
||||
از کنترلهای WARP در پنل، یک حساب ثبت کنید. 3x-ui کلیدها، نشانیها، بایتهای رزروشده و نقطه
|
||||
انتهایی peer مربوط به خروجی را بهصورت خودکار پر میکند.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### (اختیاری) چرخش خودکار IP
|
||||
|
||||
یک بازه بهروزرسانی WARP (بر حسب **روز**) تنظیم کنید تا IP مربوط به WARP بهصورت دورهای چرخش
|
||||
یابد. یک لایسنس رایگان نیز میتواند اعمال شود.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
ترافیک موردنظر خود (برای مثال دامنههای خاص) را با یک قاعده مسیریابی به خروجی `warp` هدایت
|
||||
کنید.
|
||||
|
||||
## NordVPN
|
||||
|
||||
3x-ui میتواند اعتبارنامههای NordVPN (NordLynx/WireGuard) را از یک توکن دسترسی دریافت کند (یا
|
||||
یک کلید خصوصی را مستقیماً بپذیرد) و کشورها/سرورها را فهرست کند تا بتوانید یک خروجی NordVPN
|
||||
بسازید.
|
||||
|
||||
## اشتراکهای خروجی (مجموعه سرورها)
|
||||
|
||||
یک **اشتراک خروجی** یک اشتراک share-link از راه دور را وارد میکند و سرورهای آن را بهعنوان
|
||||
**خروجی** به پیکربندی در حال اجرای Xray تزریق میکند — بدون دستزدن به قالب ذخیرهشده شما. این
|
||||
روش توصیهشده برای اشتراک در یک *مجموعه* از سرورهاست.
|
||||
|
||||
| فیلد | پیشفرض | معنا |
|
||||
| ---------------- | ------- | -------------------------------------------------------------- |
|
||||
| `url` | — | نشانی اشتراک از راه دور (محافظتشده در برابر SSRF). |
|
||||
| `tagPrefix` | auto | پیشوند برچسبهای خروجی تولیدشده (مثلاً `hk-`)؛ خالی = `subN-`. |
|
||||
| `updateInterval` | `600` | بازه تازهسازی بر حسب **ثانیه**. |
|
||||
| `prepend` | `false` | این خروجیها را پیش از خروجیهای دستی شما قرار میدهد. |
|
||||
| `priority` | `0` | ترتیب ادغام (مقدار کمتر، زودتر). |
|
||||
|
||||
خروجیهای واردشده **برچسبهای پایدار** میگیرند: همان سرور در طول تازهسازیها همان برچسب را
|
||||
حفظ میکند، بنابراین انتخابگرهای مسیریابی/متعادلکننده مبتنی بر برچسب دقیق پایدار میمانند —
|
||||
در حالی که انتخابگرهای پیشوندی/wildcard (مثلاً `hk-*`) با تغییر مجموعه، بهصورت خودکار سرورهای
|
||||
جدید را در بر میگیرند. طرحهای پیوند پشتیبانیشده: `vmess`، `vless`، `trojan`، `ss`،
|
||||
`hysteria2` (`hy2`) و `wireguard` (`wg`). پنل اشتراکهای فعال را روی یک زمانسنج تازه میکند و
|
||||
هنگام تغییر چیزی، Xray را بارگذاری مجدد میکند.
|
||||
|
||||
## قواعد مسیریابی
|
||||
|
||||
**قواعد مسیریابی** تعیین میکنند هر اتصال از کدام خروجی (یا متعادلکننده) استفاده کند. هر
|
||||
قاعده یک تطبیقدهنده از نوع `field` است: هر یک از `domain`، `ip`، `port`، `network`،
|
||||
`protocol`، `inboundTag`، `sourceIP`، … را تنظیم کنید و آن را به یک **`outboundTag`** یا یک
|
||||
**`balancerTag`** اشاره دهید. قواعد **از بالا به پایین — نخستین تطبیق برنده است** ارزیابی میشوند، بنابراین
|
||||
قواعد خاص را بالای قواعد عمومی قرار دهید.
|
||||
|
||||
```json title="route ads to blackhole, private IPs direct"
|
||||
{
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{ "type": "field", "domain": ["geosite:category-ads-all"], "outboundTag": "block" },
|
||||
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## متعادلکنندهها
|
||||
|
||||
یک **متعادلکننده** خروجیها را با یک **انتخابگر** (پیشوندهای برچسب، از جمله مجموعههای
|
||||
wildcard حاصل از اشتراکهای خروجی) گروهبندی میکند و ترافیک را با یک **استراتژی** میان آنها
|
||||
توزیع یا در صورت خرابی منتقل میکند:
|
||||
|
||||
| استراتژی | انتخاب میکند… | به مانیتور نیاز دارد |
|
||||
| ------------- | ----------------------------------------------- | ------------------------ |
|
||||
| `random` | یک عضو تصادفی برای هر اتصال | خیر |
|
||||
| `roundRobin` | اعضا بهصورت چرخشی | خیر |
|
||||
| `leastPing` | عضو با کمترین تأخیر | **`observatory`** |
|
||||
| `leastLoad` | پایدارترین عضو بر اساس بار نمونهبرداریشده | **`burstObservatory`** |
|
||||
|
||||
از یک قاعده با `balancerTag` به یک متعادلکننده ارجاع دهید. `leastPing` و `leastLoad`
|
||||
به یک مانیتور سلامت نیاز دارند که Xray آن را در **سطح بالای** پیکربندی قرار میدهد
|
||||
(`observatory` / `burstObservatory`، **نه** درون `routing`). پنل میتواند وضعیت
|
||||
متعادلکننده را گزارش کند و برای آزمایش یک متعادلکننده را به یک خروجی مشخص **بازنویسی** کند.
|
||||
|
||||
بلوک مسیریابی — قواعد، متعادلکنندهها و observatory متناظر — را در اینجا بسازید:
|
||||
|
||||
<RoutingBuilder />
|
||||
|
||||
<Callout type="warn">
|
||||
خروجیهایی که به سرویسهای خارجی دسترسی مییابند با محافظت SSRF واکشی میشوند — بهصورت
|
||||
پیشفرض نشانیهای خصوصی/داخلی مسدود هستند مگر آنکه بهطور صریح آنها را بهازای هر منبع مجاز
|
||||
کنید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: پراکسی معکوس
|
||||
description: قرار دادن پنل و اشتراک 3x-ui پشت Nginx یا Caddy همراه با TLS از Let's Encrypt.
|
||||
icon: Waypoints
|
||||
---
|
||||
|
||||
پراکسی معکوس به شما امکان میدهد پنل و اشتراک را روی یک دامنه تمیز با HTTPS خودکار
|
||||
ارائه دهید و پورتهای واقعی را پشت پورتهای 80/443 پنهان کنید. ترجیح میدهید خودِ
|
||||
پنل مستقیماً TLS را مدیریت کند؟ بهجای آن، گواهی را از طریق
|
||||
[منوی SSL در `x-ui`](/docs/config/ssl-certificates) دریافت کنید.
|
||||
|
||||
## ساخت یک پیکربندی
|
||||
|
||||
<ReverseProxyGenerator />
|
||||
|
||||
<Callout type="info">
|
||||
پنل برای بهروزرسانیهای زنده از WebSockets استفاده میکند، بنابراین پراکسی باید
|
||||
هدرهای `Upgrade`/`Connection` را عبور دهد (خروجی Nginx بالا این کار را انجام
|
||||
میدهد). Caddy ارتقاهای WebSocket را بهصورت خودکار مدیریت میکند.
|
||||
</Callout>
|
||||
|
||||
## Nginx + گواهی
|
||||
|
||||
با Nginx، گواهی را با `certbot` (یا `acme.sh`) دریافت کنید و در بلوک server به آن
|
||||
ارجاع دهید:
|
||||
|
||||
```bash title="certbot"
|
||||
certbot certonly --nginx -d panel.example.com
|
||||
```
|
||||
|
||||
پس از نصب گواهی، Nginx را بارگذاری مجدد کنید و تمدید خودکار را راهاندازی کنید
|
||||
(`certbot renew` بهصورت پیشفرض روی یک تایمر اجرا میشود).
|
||||
|
||||
## Caddy
|
||||
|
||||
Caddy گواهیها را برای شما دریافت و تمدید میکند — یک Caddyfile را به پنل اشاره
|
||||
دهید و همهچیز کار میکند:
|
||||
|
||||
```text title="Caddyfile"
|
||||
panel.example.com {
|
||||
reverse_proxy 127.0.0.1:2053
|
||||
}
|
||||
```
|
||||
|
||||
## نکتهها
|
||||
|
||||
- حتی پشت یک پراکسی هم **مسیر پایه وب** پنل را حفظ کنید؛ دفاع لایهبهلایه.
|
||||
- اگر TLS را در پراکسی مدیریت میکنید، ممکن است بخواهید `XUI_SKIP_HSTS=true` را روی
|
||||
پنل تنظیم کنید — به [مرجع متغیرهای محیطی](/docs/reference/env-vars) مراجعه کنید.
|
||||
- سرور [اشتراک](/docs/config/subscription) را هم پراکسی کنید تا محتوای آن نیز روی
|
||||
HTTPS ارائه شود.
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: امنیت
|
||||
description: سختسازی 3x-ui — احراز هویت پنل و 2FA، محدودیت IP با Fail2ban، قوانین فایروال، BBR و بهروز ماندن.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
یک پنل پروکسی هدفی پرارزش است. چند لایه سختسازی تأثیر زیادی دارد.
|
||||
|
||||
## سختسازی پنل
|
||||
|
||||
- اعتبارنامههای قوی و یکتا و **احراز هویت دومرحلهای** (TOTP).
|
||||
- یک پورت غیرپیشفرض برای پنل و یک مسیر پایه وب طولانی و تصادفی.
|
||||
- TLS روی پنل (مستقیماً یا از طریق یک [پروکسی معکوس](/docs/operations/reverse-proxy)).
|
||||
- **محدودکننده ورود** داخلی، یک IP/نام کاربری را پس از ۵ تلاش ناموفق در بازه ۵ دقیقه (به مدت ۱۵ دقیقه) مسدود میکند، و پنل میتواند ترافیک خروجی خود را از طریق یک outbound مسیریابی کند.
|
||||
|
||||
برای فهرست کامل به [نخستین ورود](/docs/guide/first-login) مراجعه کنید.
|
||||
|
||||
## Fail2ban و محدودیتهای IP
|
||||
|
||||
برای هر کلاینت یک **محدودیت IP** تنظیم کنید (به [کلاینتها](/docs/config/clients) مراجعه کنید) تا تعداد IPهای مبدأ همزمان محدود شود. اعمال این محدودیت توسط **Fail2ban** انجام میشود که 3x-ui آن را برای شما نصب و پیکربندی میکند (در نصبهای اسکریپتی بهطور پیشفرض فعال است و در Docker از طریق `XUI_ENABLE_FAIL2BAN=true`).
|
||||
|
||||
آن را از منوی `x-ui` مدیریت کنید (**۲۲ — IP Limit Management**): نصب/پیکربندی، تغییر مدت مسدودسازی (پیشفرض **۳۰ دقیقه**)، مسدودسازی/رفع مسدودی یک IP، مشاهده لاگهای مسدودسازی و بررسی وضعیت. در پشت صحنه:
|
||||
|
||||
- این jail با نام **`3x-ipl`** شناخته میشود؛ لاگهای مسدودسازی در `/var/log/x-ui/3xipl.log` و `/var/log/x-ui/3xipl-banned.log` قرار دارند (همچنین از طریق `x-ui banlog`).
|
||||
- مسدودسازیها همه TCP/UDP را پوشش میدهند **بهجز** پورتهای SSH و پنل شما، بنابراین یک مسدودسازی نمیتواند شما را از سرور یا پنل بیرون بیندازد.
|
||||
|
||||
<Callout type="warn">
|
||||
در Docker، Fail2ban با `iptables` مسدودسازی میکند که به قابلیت `NET_ADMIN` (و
|
||||
`NET_RAW`) نیاز دارد — `docker-compose.yml` آنها را اعطا میکند. با یک
|
||||
`docker run` ساده، `--cap-add=NET_ADMIN --cap-add=NET_RAW` را اضافه کنید وگرنه
|
||||
مسدودسازیها لاگ میشوند اما هرگز اعمال نمیشوند.
|
||||
</Callout>
|
||||
|
||||
## فایروال
|
||||
|
||||
تنها پورتهایی را باز کنید که واقعاً استفاده میکنید: SSH، پورت پنل، پورت اشتراک و پورتهای inbound خود. منوی `x-ui` (**۲۳ — Firewall Management**) ابزار `ufw` را در بر میگیرد، یا اینجا قوانین را تولید کنید:
|
||||
|
||||
<FirewallRulesGenerator />
|
||||
|
||||
<Callout type="warn">
|
||||
پیش از فعالسازی یک فایروال با سیاست رد پیشفرض، مطمئن شوید که SSH همچنان مجاز
|
||||
میماند، وگرنه ممکن است خودتان را بیرون بیندازید. با یک نشست دوم باز آن را آزمایش
|
||||
کنید.
|
||||
</Callout>
|
||||
|
||||
## تنظیم شبکه (BBR)
|
||||
|
||||
منوی `x-ui` (**۲۶ — Enable BBR**) کنترل ازدحام BBR گوگل را فعال/غیرفعال میکند
|
||||
(`net.ipv4.tcp_congestion_control = bbr`، `net.core.default_qdisc = fq`) که اغلب توان عملیاتی را روی لینکهای شلوغ بهبود میبخشد.
|
||||
|
||||
## بهروز ماندن
|
||||
|
||||
3x-ui و Xray-core را بهطور منظم بهروزرسانی کنید — اصلاحات امنیتی در نسخههای جدید منتشر میشوند. [صفحه انتشارها](https://github.com/MHSanaei/3x-ui/releases) را دنبال کنید و به [بهروزرسانی و حذف نصب](/docs/guide/update-uninstall) مراجعه کنید.
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: ربات Telegram
|
||||
description: یک ربات Telegram را به 3x-ui متصل کنید تا فرمانها، گزارشهای دورهای، هشدارهای رویداد (ورود، CPU، بالا/پایین شدن نود)، پشتیبانگیری و سلفسرویس کلاینتها را در اختیار داشته باشید.
|
||||
icon: Send
|
||||
---
|
||||
|
||||
3x-ui میتواند یک ربات Telegram را برای پایش، هشدار، پشتیبانگیری و مدیریت از راه دور
|
||||
به کار گیرد. ادمینها کنترل کامل دارند؛ کاربران عادی (که با Telegram ID پیوند خوردهاند)
|
||||
میتوانند مصرف و لینکهای خودشان را بررسی کنند.
|
||||
|
||||
<Callout type="info">
|
||||
دنبال اخبار و پشتیبانی انجمن هستید؟ به کانال رسمی Telegram یعنی
|
||||
[@XrayUI](https://t.me/XrayUI) بپیوندید. این از ربات زیر جداست، رباتی که خودتان
|
||||
آن را برای مدیریت پنل خودتان اجرا میکنید.
|
||||
</Callout>
|
||||
|
||||
## راهاندازی
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### ساختن یک ربات
|
||||
|
||||
به [@BotFather](https://t.me/BotFather) پیام بدهید، `/newbot` را ارسال کنید و **توکن
|
||||
ربات** را کپی نمایید.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پیدا کردن Telegram ID خودتان
|
||||
|
||||
شناسهی عددی کاربری Telegram خود را به دست آورید (پس از اتصال، فرمان `/id` خودِ ربات
|
||||
آن را گزارش میکند). این همان **شناسهی ادمین** شماست.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### پیکربندی پنل
|
||||
|
||||
در تنظیمات پنل، ربات Telegram را فعال کنید و **توکن** و **شناسه(های) چت ادمین** را
|
||||
(با کاما جداشده) تنظیم نمایید. ذخیره کنید، سپس به ربات خود پیام بدهید.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
پیش از چسباندن توکن، شناسههای ادمین و زمانبندی گزارش در پنل، آنها را اعتبارسنجی
|
||||
کنید:
|
||||
|
||||
<TelegramSetupHelper />
|
||||
|
||||
## فرمانها
|
||||
|
||||
اینها در منوی فرمان Telegram ظاهر میشوند: `/start`، `/help`، `/status`، `/id`.
|
||||
فرمانهای دیگر:
|
||||
|
||||
| فرمان | چه کسی | عملکرد |
|
||||
| ------------------ | ------ | ------------------------------------------------------------ |
|
||||
| `/start`، `/help` | همه | پیام خوشآمدگویی و منوی دکمههای درونخطی |
|
||||
| `/status` | همه | تأیید فعال بودن ربات |
|
||||
| `/id` | همه | نمایش شناسهی عددی Telegram شما |
|
||||
| `/usage <arg>` | هر دو | ادمینها کلاینتها را جستوجو میکنند؛ کاربران مصرف خود را میبینند |
|
||||
| `/inbound <remark>`| ادمین | نمایش جزئیات یک ورودی |
|
||||
| `/restart` | ادمین | راهاندازی مجدد Xray |
|
||||
|
||||
ادمینها همچنین جریانهای دکمهی درونخطی برای مصرف سرور، گزارشهای ترافیک مرتبشده،
|
||||
بازنشانی ترافیک، پشتیبانگیری از DB، گزارشهای مسدودسازی، فهرست کردن ورودیها/کلاینتها،
|
||||
کلاینتهای آنلاین، «بهزودی تمامشونده» و یک جادوگر کامل **افزودن کلاینت** را در اختیار دارند.
|
||||
کاربران عادی دکمههایی برای مصرف خودشان، لینکهای اشتراک، لینکهای منفرد و کدهای QR دارند.
|
||||
|
||||
## گزارشها و هشدارها
|
||||
|
||||
- **گزارش دورهای** — بر اساس زمانبندی `tgRunTime` (بهصورت پیشفرض `@daily`)، ربات
|
||||
مصرف سرور (هاست، نسخهها، آپتایم، بار، حافظه، کلاینتهای آنلاین، ترافیک)، فهرستی از
|
||||
کلاینتهای تمامشده/درحالانقضا و — اگر `tgBotBackup` فعال باشد — یک نسخهی پشتیبان از
|
||||
پایگاهداده و پیکربندی Xray را برای ادمینها میفرستد. کلاینتهایی که با Telegram ID
|
||||
پیوند خوردهاند، هشدارهای انقضا/سهمیهی خودشان را دریافت میکنند.
|
||||
- **هشدارهای رویداد** — با `tgEnabledEvents` انتخاب میشوند (بهصورت پیشفرض `login.attempt,cpu.high`):
|
||||
|
||||
| رویداد | چه زمانی |
|
||||
| --------------- | ------------------------------------------------------- |
|
||||
| `login.attempt` | ورود به پنل موفق یا ناموفق شود (همراه با IP و نام کاربری) |
|
||||
| `cpu.high` | CPU از `tgCpu` درصد فراتر برود (بهصورت پیشفرض ۸۰) |
|
||||
| `memory.high` | حافظه از `tgMemory` درصد فراتر برود (بهصورت پیشفرض ۸۰) |
|
||||
| `xray.crash` | Xray-core کرش کند |
|
||||
| `outbound.down` / `outbound.up` | یک خروجی از کار بیفتد / بازیابی شود |
|
||||
| `node.down` / `node.up` | یک نود آفلاین شود / بازگردد |
|
||||
|
||||
زمانهای پیشهشدار از `expireDiff` (روزهای پیش از انقضا) و `trafficDiff` (گیگابایتِ
|
||||
باقیمانده از سهمیه) میآیند؛ هر دو بهصورت پیشفرض `0` هستند (خاموش).
|
||||
|
||||
## تنظیمات
|
||||
|
||||
| تنظیم | پیشفرض | معنا |
|
||||
| -------------- | -------------------------- | ---------------------------------------------- |
|
||||
| `tgBotEnable` | `false` | روشن/خاموش اصلی. |
|
||||
| `tgBotToken` | _(محرمانه)_ | توکن API ربات. |
|
||||
| `tgBotChatId` | _(هیچکدام)_ | شناسههای Telegram **ادمین**، جداشده با کاما. |
|
||||
| `tgBotProxy` | _(هیچکدام)_ | پروکسی `socks5://`، `http://` یا `https://`. |
|
||||
| `tgBotAPIServer` | _(پیشفرض)_ | سرور سفارشی Telegram Bot API. |
|
||||
| `tgRunTime` | `@daily` | زمانبندی گزارش (cron / `@daily` / `@every …`). |
|
||||
| `tgBotBackup` | `false` | ضمیمه کردن یک نسخهی پشتیبان DB به گزارش دورهای. |
|
||||
| `tgCpu` / `tgMemory` | `80` / `80` | آستانههای هشدار CPU / حافظه (درصد). |
|
||||
| `tgLang` | `en-US` | زبان ربات. |
|
||||
| `tgEnabledEvents` | `login.attempt,cpu.high`| اینکه کدام رویدادها تحویل داده شوند. |
|
||||
|
||||
<Callout type="warn">
|
||||
توکن ربات کنترل ربات شما را در دست دارد — آن را محرمانه نگه دارید و فقط شناسههای چت
|
||||
ادمین **مورد اعتماد** را اضافه کنید. هشدارهای ورود هرگز شامل رمزهای عبور نمیشوند.
|
||||
</Callout>
|
||||
|
||||
<Callout type="info">
|
||||
اگر ترجیح میدهید هشدارها را از طریق ایمیل دریافت کنید، اعلانهای ایمیل (SMTP) همان
|
||||
رویدادها را بازتاب میدهند (`smtpEnabledEvents`) — SMTP را در تنظیمات پنل پیکربندی نمایید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: توکنهای API
|
||||
description: >-
|
||||
مدیریت توکنهای Bearer برای احراز هویت برنامهنویسیشده (رباتها، پنلهای مرکزی
|
||||
که از طرف این نود عمل میکنند، CI). هر توکن یک نام یکتا و یک پرچم فعالسازی دارد —
|
||||
برای لغو بدون حذف، آن را غیرفعال کنید و برای لغو دائمی، آن را حذف کنید. توکنها به
|
||||
صورت هش SHA-256 ذخیره میشوند و متن خام تنها یکبار، در پاسخ ایجاد، بازگردانده
|
||||
میشود — پس از آن قابل بازیابی نیست، بنابراین همان موقع آن را کپی کنید. برای هر
|
||||
درخواست /panel/api/* یکی را به صورت
|
||||
<code>Authorization: Bearer <token></code> ارسال کنید — این توکن یک اعتبارنامهٔ
|
||||
مدیر کامل است.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every API token, enabled or not. The token value is never returned
|
||||
— only metadata.
|
||||
url: >-
|
||||
#list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
|
||||
- depth: 2
|
||||
title: >-
|
||||
Mint a new API token. Name must be unique and 1-64 characters; the token
|
||||
string is server-generated and returned only in this response — it is
|
||||
stored hashed and cannot be retrieved later.
|
||||
url: >-
|
||||
#mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
|
||||
- depth: 2
|
||||
title: >-
|
||||
Permanently delete a token. Any caller using it stops authenticating
|
||||
immediately.
|
||||
url: >-
|
||||
#permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle a token enabled/disabled without deleting it. Disabled tokens are
|
||||
rejected by checkAPIAuth on the next request.
|
||||
url: >-
|
||||
#toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every API token, enabled or not. The token value is never
|
||||
returned — only metadata.
|
||||
id: >-
|
||||
list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
|
||||
- content: >-
|
||||
Mint a new API token. Name must be unique and 1-64 characters; the
|
||||
token string is server-generated and returned only in this response —
|
||||
it is stored hashed and cannot be retrieved later.
|
||||
id: >-
|
||||
mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
|
||||
- content: >-
|
||||
Permanently delete a token. Any caller using it stops authenticating
|
||||
immediately.
|
||||
id: >-
|
||||
permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
|
||||
- content: >-
|
||||
Toggle a token enabled/disabled without deleting it. Disabled tokens
|
||||
are rejected by checkAPIAuth on the next request.
|
||||
id: >-
|
||||
toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/apiTokens","method":"get"},{"path":"/panel/api/setting/apiTokens/create","method":"post"},{"path":"/panel/api/setting/apiTokens/delete/{id}","method":"post"},{"path":"/panel/api/setting/apiTokens/setEnabled/{id}","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: احراز هویت
|
||||
description: >-
|
||||
دو حالت احراز هویت پشتیبانی میشود. نشستهای UI از یک کوکی استفاده میکنند که
|
||||
توسط نقطهپایانی ورود تنظیم میشود. کلاینتهای برنامهنویسیشده (رباتها،
|
||||
اسکریپتها، پنلهای راه دور) با یک توکن Bearer که از مسیر Settings → Security →
|
||||
API Token گرفته میشود احراز هویت میکنند. هر دو روش برای همهٔ نقاطپایانی زیر
|
||||
/panel/api/* کار میکنند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
با نام کاربری + رمز عبور احراز هویت کنید و یک کوکی نشست دریافت کنید.
|
||||
پیش از هر فراخوانی API مبتنی بر کوکی الزامی است.
|
||||
url: >-
|
||||
#authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
|
||||
- depth: 2
|
||||
title: کوکی نشست را پاک میکند. برای نشستهای مرورگر به هدر CSRF نیاز دارد.
|
||||
url: '#clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions'
|
||||
- depth: 2
|
||||
title: >-
|
||||
یک توکن CSRF برای نشست جاری صادر میکند. SPA آن را در هدر X-CSRF-Token
|
||||
روی درخواستهای ناامن بازپخش میکند. فراخوانندگانی که از توکن Bearer
|
||||
استفاده میکنند میتوانند از این مرحله صرفنظر کنند — میانافزار برای
|
||||
درخواستهای API احراز هویتشده CSRF را دور میزند.
|
||||
url: >-
|
||||
#mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
|
||||
- depth: 2
|
||||
title: >-
|
||||
مشخص میکند که آیا 2FA روی پنل فعال است یا خیر — صفحهٔ ورود از آن برای
|
||||
تصمیمگیری دربارهٔ نمایش فیلد OTP استفاده میکند.
|
||||
url: >-
|
||||
#returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
با نام کاربری + رمز عبور احراز هویت کنید و یک کوکی نشست دریافت کنید.
|
||||
پیش از هر فراخوانی API مبتنی بر کوکی الزامی است.
|
||||
id: >-
|
||||
authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
|
||||
- content: >-
|
||||
کوکی نشست را پاک میکند. برای نشستهای مرورگر به هدر CSRF نیاز
|
||||
دارد.
|
||||
id: clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions
|
||||
- content: >-
|
||||
یک توکن CSRF برای نشست جاری صادر میکند. SPA آن را در هدر X-CSRF-Token
|
||||
روی درخواستهای ناامن بازپخش میکند. فراخوانندگانی که از توکن Bearer
|
||||
استفاده میکنند میتوانند از این مرحله صرفنظر کنند — میانافزار برای
|
||||
درخواستهای API احراز هویتشده CSRF را دور میزند.
|
||||
id: >-
|
||||
mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
|
||||
- content: >-
|
||||
مشخص میکند که آیا 2FA روی پنل فعال است یا خیر — صفحهٔ ورود از آن
|
||||
برای تصمیمگیری دربارهٔ نمایش فیلد OTP استفاده میکند.
|
||||
id: >-
|
||||
returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/login","method":"post"},{"path":"/logout","method":"post"},{"path":"/csrf-token","method":"get"},{"path":"/getTwoFactorEnable","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: پشتیبانگیری
|
||||
description: عملیاتهایی که با ربات Telegram پیکربندیشده تعامل دارند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Send a fresh DB backup to every Telegram chat configured as an admin
|
||||
recipient. No body, no params.
|
||||
url: >-
|
||||
#send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Send a fresh DB backup to every Telegram chat configured as an admin
|
||||
recipient. No body, no params.
|
||||
id: >-
|
||||
send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/backuptotgbot","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
---
|
||||
title: کلاینتها
|
||||
description: >-
|
||||
کلاینتها را بهعنوان موجودیتهای مستقل مدیریت کنید که میتوانند به یک یا چند
|
||||
inbound متصل شوند. هر رکورد کلاینت، ورودی settings.clients را در تمام
|
||||
inboundهایی که به آنها تعلق دارد هدایت میکند. این endpointها زیر مسیر
|
||||
/panel/api/clients قرار دارند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every client with its attached inbound IDs and traffic record. The
|
||||
reverse field, if set, is returned as a nested JSON object (legacy
|
||||
JSON-encoded-string form is still accepted on write).
|
||||
url: >-
|
||||
#list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Filter, sort, and paginate clients on the server. Each item is a slim
|
||||
row (no uuid/password/auth/flow/security/reverse/tgId) so the clients
|
||||
page can ship 25-ish rows in a few KB instead of the full table. The
|
||||
response also includes a summary computed across the full DB row set so
|
||||
dashboard counters stay stable as the user paginates or filters. Page
|
||||
size capped at 200; fetch /get/:email to obtain the full per-client
|
||||
payload for an edit/info modal.
|
||||
url: >-
|
||||
#filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch one client by email, including the inbound IDs and external config
|
||||
IDs it is attached to.
|
||||
url: >-
|
||||
#fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new client and attach it to one or more inbounds in a single
|
||||
call. Body is JSON. Per-protocol secrets (UUID for VLESS/VMess, password
|
||||
for Trojan/Shadowsocks, auth for Hysteria) are generated server-side
|
||||
when omitted, so callers can send only the universal fields.
|
||||
url: >-
|
||||
#create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
|
||||
- depth: 2
|
||||
title: >-
|
||||
Update an existing client by email. Changes propagate to every attached
|
||||
inbound. Body is the JSON client payload — supply the full set of fields
|
||||
you want to keep (the server replaces the row, it does not patch).
|
||||
url: >-
|
||||
#update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete a client by email. Removes it from every attached inbound and
|
||||
drops its traffic record unless keepTraffic=1 is passed.
|
||||
url: >-
|
||||
#delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Attach an existing client to one or more additional inbounds. Body is
|
||||
JSON.
|
||||
url: >-
|
||||
#attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
|
||||
- depth: 2
|
||||
title: Detach a client from one or more inbounds without deleting the client.
|
||||
url: '#detach-a-client-from-one-or-more-inbounds-without-deleting-the-client'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace a client's external links (per-client share links and remote
|
||||
subscription URLs surfaced in their subscription). Sends the full set;
|
||||
the server replaces all rows.
|
||||
url: >-
|
||||
#replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reset the up/down counters for every client globally. Quotas and expiry
|
||||
are not affected. Triggers an Xray restart if any counter actually
|
||||
moved.
|
||||
url: >-
|
||||
#reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete every client whose traffic quota is exhausted (used >= total,
|
||||
when reset is disabled) or whose expiry has passed. Returns the deleted
|
||||
count and triggers an Xray restart when any client was on a running
|
||||
inbound.
|
||||
url: >-
|
||||
#delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete every client that is not attached to any inbound, along with its
|
||||
traffic record, IP log, and external links. Useful for clearing clients
|
||||
left unattached after their inbounds were removed. Returns the deleted
|
||||
count. Cannot be undone.
|
||||
url: >-
|
||||
#delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return every client as a {client, inboundIds} array — the same shape
|
||||
/bulkCreate and /import accept — so the payload round-trips straight
|
||||
back through /import. Clients with no inbound attachment are included
|
||||
with an empty inboundIds list. The UI shows this in a CodeMirror viewer
|
||||
(copy / download); programmatic callers get the array in obj.
|
||||
url: >-
|
||||
#return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
|
||||
- depth: 2
|
||||
title: >-
|
||||
Import clients from a JSON body { "data": "<json>" }, where data is a
|
||||
string-encoded array produced by /export ([{client, inboundIds}]). Items
|
||||
with inboundIds are created and attached to those inbounds; items with
|
||||
an empty inboundIds list are restored as unattached client records.
|
||||
Existing emails are never overwritten — they are returned in skipped.
|
||||
Triggers a single Xray restart at the end if any target inbound was
|
||||
running.
|
||||
url: >-
|
||||
#import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Shift expiry and/or traffic quota for many clients in one call.
|
||||
addDays/addBytes may be negative. Clients with unlimited expiry
|
||||
(expiryTime=0) or unlimited traffic (totalGB=0) are skipped for the
|
||||
corresponding field — bulk extend never converts unlimited to limited.
|
||||
The optional flow directive sets the XTLS flow on every client: "none"
|
||||
clears it, "xtls-rprx-vision"/"xtls-rprx-vision-udp443" set it where the
|
||||
inbound supports it (omit or "" to leave it unchanged). Returns the
|
||||
adjusted count and per-email skip reasons.
|
||||
url: >-
|
||||
#shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Enable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to add each user. Note that enabling a
|
||||
client whose quota is exhausted or whose expiry has passed only flips
|
||||
the flag — the traffic loop will disable it again on the next tick.
|
||||
Returns the changed count and per-email skip reasons.
|
||||
url: >-
|
||||
#enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Disable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to remove each user. Returns the
|
||||
changed count and per-email skip reasons.
|
||||
url: >-
|
||||
#disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete many clients in one call. The server processes the list
|
||||
sequentially so each delete sees the committed state of the previous one
|
||||
— avoids the race the per-email fan-out had on the panel side. Pass
|
||||
keepTraffic=true to retain the xray_client_traffic rows after deletion.
|
||||
url: >-
|
||||
#delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create many clients in one call. Body is a JSON array of {client,
|
||||
inboundIds} payloads — the same shape /add accepts. Items are processed
|
||||
sequentially; per-email skip reasons are returned for items that fail
|
||||
(e.g., duplicate email). Triggers a single Xray restart at the end if
|
||||
any inbound was running.
|
||||
url: >-
|
||||
#create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Add many clients to a group in one call. Updates clients.group_name and
|
||||
patches the matching client entry inside every owning inbound's settings
|
||||
JSON in a single transaction. If the group name does not yet exist (in
|
||||
client_groups or as a derived label), it is auto-created as a persistent
|
||||
group. To clear the group label, use /groups/bulkRemove instead.
|
||||
url: >-
|
||||
#add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
|
||||
- depth: 2
|
||||
title: >-
|
||||
Clear the group label on many clients in one call. Inverse of
|
||||
/groups/bulkAdd. Clients themselves are kept — only the group label is
|
||||
cleared from clients.group_name and from each owning inbound's settings
|
||||
JSON. Groups become empty if all their members are removed.
|
||||
url: >-
|
||||
#clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Attach many existing clients to many inbounds in one call. Each client
|
||||
keeps its identity (email/UUID/password/subId) and a shared traffic row;
|
||||
all clients are added to a target inbound in a single AddInboundClient
|
||||
call. Clients already present on a target are reported under skipped.
|
||||
Returns per-email attached/skipped/errors lists and triggers a single
|
||||
Xray restart if any target inbound was running.
|
||||
url: >-
|
||||
#attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Mirror of bulkAttach: detach many existing clients from many inbounds in
|
||||
one call. For each email, intersects the client's current inbounds with
|
||||
the requested set and detaches from those only; (email, inbound) pairs
|
||||
where the client is not currently attached are silently no-ops. Emails
|
||||
not attached to any of the requested inbounds are reported under
|
||||
skipped. Client records are kept even if they become orphaned — use
|
||||
bulkDel for full removal. Returns per-email detached/skipped/errors
|
||||
lists and triggers a single Xray restart if any target inbound was
|
||||
running.
|
||||
url: >-
|
||||
#mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero up/down counters for many clients in one call. Loops the
|
||||
single-reset path so each client is re-enabled across its attached
|
||||
inbounds and pushed to Xray/remote nodes. Returns the count of
|
||||
successfully reset clients.
|
||||
url: >-
|
||||
#zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
|
||||
- depth: 2
|
||||
title: >-
|
||||
List all client groups with their member counts. Merges persisted groups
|
||||
(rows in client_groups, including empty placeholders) with the distinct
|
||||
group_name values currently set on clients. Sorted alphabetically
|
||||
(case-insensitive).
|
||||
url: >-
|
||||
#list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return just the email list of clients that currently belong to the given
|
||||
group. Useful for fanning a single bulk action over an entire group
|
||||
without round-tripping the full client list.
|
||||
url: >-
|
||||
#return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new empty (placeholder) group. The group becomes selectable in
|
||||
client forms and the filter drawer even before any client is added to
|
||||
it. Errors if a group with the same name already exists.
|
||||
url: >-
|
||||
#create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
|
||||
- depth: 2
|
||||
title: >-
|
||||
Rename a group. The new name is applied to the client_groups row AND
|
||||
propagated to every matching client (both clients.group_name and the
|
||||
client entry inside every owning inbound's settings JSON) in a single
|
||||
transaction. Returns the number of clients whose label was updated.
|
||||
url: >-
|
||||
#rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
|
||||
- depth: 2
|
||||
title: >-
|
||||
Remove a group. Deletes the client_groups row and clears the group label
|
||||
from every matching client (both clients.group_name and the inbound
|
||||
settings JSON). The clients themselves are NOT deleted — use /bulkDel
|
||||
after filtering by group for that. Returns the count of clients whose
|
||||
label was cleared.
|
||||
url: >-
|
||||
#remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero out a single client’s up/down counters. Re-enables the client
|
||||
across every attached inbound and pushes the change to Xray (or the
|
||||
remote node) so depleted users can connect again immediately.
|
||||
url: >-
|
||||
#zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
|
||||
- depth: 2
|
||||
title: >-
|
||||
Manually adjust a client’s upload + download counters. Useful for
|
||||
migrations from external accounting systems.
|
||||
url: >-
|
||||
#manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
|
||||
- depth: 2
|
||||
title: >-
|
||||
List source IPs that have connected with the given client’s credentials.
|
||||
Returns an array of "ip (timestamp)" strings.
|
||||
url: >-
|
||||
#list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
|
||||
- depth: 2
|
||||
title: Reset the recorded IP list for a client.
|
||||
url: '#reset-the-recorded-ip-list-for-a-client'
|
||||
- depth: 2
|
||||
title: >-
|
||||
List the emails of currently connected clients (last seen within the
|
||||
heartbeat window), deduped across every node.
|
||||
url: >-
|
||||
#list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Online client emails grouped by the panelGuid of the node that
|
||||
physically hosts each client. The local panel uses its own GUID; each
|
||||
node (at any depth in a chain) uses its GUID. Lets the inbounds page
|
||||
attribute online status to the real node instead of the intermediate one
|
||||
it syncs through.
|
||||
url: >-
|
||||
#online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
|
||||
- depth: 2
|
||||
title: >-
|
||||
Per-client source IPs grouped by the panelGuid of the node that observed
|
||||
them. Lets the central panel attribute and enforce per-client IP limits
|
||||
using the real visitor IPs each node sees, instead of the address of the
|
||||
intermediate panel it syncs through.
|
||||
url: >-
|
||||
#per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
|
||||
- depth: 2
|
||||
title: >-
|
||||
Inbound tags that carried traffic within the heartbeat window, grouped
|
||||
by the hosting node's panelGuid. Pairs with onlinesByGuid so the
|
||||
inbounds page only marks a multi-inbound client online on the inbounds
|
||||
it actually used. Nodes that do not report per-inbound activity are
|
||||
absent.
|
||||
url: >-
|
||||
#inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
|
||||
- depth: 2
|
||||
title: Map of client email → last-seen unix timestamp.
|
||||
url: '#map-of-client-email--last-seen-unix-timestamp'
|
||||
- depth: 2
|
||||
title: Traffic counters for a client identified by email.
|
||||
url: '#traffic-counters-for-a-client-identified-by-email'
|
||||
- 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
|
||||
- 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:
|
||||
vmess, vless, trojan, shadowsocks, hysteria. If
|
||||
streamSettings.externalProxy is set, returns one URL per external proxy.
|
||||
Protocols without a URL form (socks, http, mixed, wireguard, dokodemo,
|
||||
tunnel) contribute nothing.
|
||||
url: >-
|
||||
#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-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every client with its attached inbound IDs and traffic record.
|
||||
The reverse field, if set, is returned as a nested JSON object (legacy
|
||||
JSON-encoded-string form is still accepted on write).
|
||||
id: >-
|
||||
list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
|
||||
- content: >-
|
||||
Filter, sort, and paginate clients on the server. Each item is a slim
|
||||
row (no uuid/password/auth/flow/security/reverse/tgId) so the clients
|
||||
page can ship 25-ish rows in a few KB instead of the full table. The
|
||||
response also includes a summary computed across the full DB row set
|
||||
so dashboard counters stay stable as the user paginates or filters.
|
||||
Page size capped at 200; fetch /get/:email to obtain the full
|
||||
per-client payload for an edit/info modal.
|
||||
id: >-
|
||||
filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
|
||||
- content: >-
|
||||
Fetch one client by email, including the inbound IDs and external
|
||||
config IDs it is attached to.
|
||||
id: >-
|
||||
fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
|
||||
- content: >-
|
||||
Create a new client and attach it to one or more inbounds in a single
|
||||
call. Body is JSON. Per-protocol secrets (UUID for VLESS/VMess,
|
||||
password for Trojan/Shadowsocks, auth for Hysteria) are generated
|
||||
server-side when omitted, so callers can send only the universal
|
||||
fields.
|
||||
id: >-
|
||||
create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
|
||||
- content: >-
|
||||
Update an existing client by email. Changes propagate to every
|
||||
attached inbound. Body is the JSON client payload — supply the full
|
||||
set of fields you want to keep (the server replaces the row, it does
|
||||
not patch).
|
||||
id: >-
|
||||
update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
|
||||
- content: >-
|
||||
Delete a client by email. Removes it from every attached inbound and
|
||||
drops its traffic record unless keepTraffic=1 is passed.
|
||||
id: >-
|
||||
delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
|
||||
- content: >-
|
||||
Attach an existing client to one or more additional inbounds. Body is
|
||||
JSON.
|
||||
id: >-
|
||||
attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
|
||||
- content: Detach a client from one or more inbounds without deleting the client.
|
||||
id: detach-a-client-from-one-or-more-inbounds-without-deleting-the-client
|
||||
- content: >-
|
||||
Replace a client's external links (per-client share links and remote
|
||||
subscription URLs surfaced in their subscription). Sends the full set;
|
||||
the server replaces all rows.
|
||||
id: >-
|
||||
replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
|
||||
- content: >-
|
||||
Reset the up/down counters for every client globally. Quotas and
|
||||
expiry are not affected. Triggers an Xray restart if any counter
|
||||
actually moved.
|
||||
id: >-
|
||||
reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
|
||||
- content: >-
|
||||
Delete every client whose traffic quota is exhausted (used >= total,
|
||||
when reset is disabled) or whose expiry has passed. Returns the
|
||||
deleted count and triggers an Xray restart when any client was on a
|
||||
running inbound.
|
||||
id: >-
|
||||
delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
|
||||
- content: >-
|
||||
Delete every client that is not attached to any inbound, along with
|
||||
its traffic record, IP log, and external links. Useful for clearing
|
||||
clients left unattached after their inbounds were removed. Returns the
|
||||
deleted count. Cannot be undone.
|
||||
id: >-
|
||||
delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
|
||||
- content: >-
|
||||
Return every client as a {client, inboundIds} array — the same shape
|
||||
/bulkCreate and /import accept — so the payload round-trips straight
|
||||
back through /import. Clients with no inbound attachment are included
|
||||
with an empty inboundIds list. The UI shows this in a CodeMirror
|
||||
viewer (copy / download); programmatic callers get the array in obj.
|
||||
id: >-
|
||||
return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
|
||||
- content: >-
|
||||
Import clients from a JSON body { "data": "<json>" }, where data is a
|
||||
string-encoded array produced by /export ([{client, inboundIds}]).
|
||||
Items with inboundIds are created and attached to those inbounds;
|
||||
items with an empty inboundIds list are restored as unattached client
|
||||
records. Existing emails are never overwritten — they are returned in
|
||||
skipped. Triggers a single Xray restart at the end if any target
|
||||
inbound was running.
|
||||
id: >-
|
||||
import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Shift expiry and/or traffic quota for many clients in one call.
|
||||
addDays/addBytes may be negative. Clients with unlimited expiry
|
||||
(expiryTime=0) or unlimited traffic (totalGB=0) are skipped for the
|
||||
corresponding field — bulk extend never converts unlimited to limited.
|
||||
The optional flow directive sets the XTLS flow on every client: "none"
|
||||
clears it, "xtls-rprx-vision"/"xtls-rprx-vision-udp443" set it where
|
||||
the inbound supports it (omit or "" to leave it unchanged). Returns
|
||||
the adjusted count and per-email skip reasons.
|
||||
id: >-
|
||||
shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Enable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to add each user. Note that enabling
|
||||
a client whose quota is exhausted or whose expiry has passed only
|
||||
flips the flag — the traffic loop will disable it again on the next
|
||||
tick. Returns the changed count and per-email skip reasons.
|
||||
id: >-
|
||||
enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Disable many clients in one call. Emails are grouped by inbound and
|
||||
applied with a single read-modify-write per inbound; the running Xray
|
||||
(local or remote node) is updated to remove each user. Returns the
|
||||
changed count and per-email skip reasons.
|
||||
id: >-
|
||||
disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
|
||||
- content: >-
|
||||
Delete many clients in one call. The server processes the list
|
||||
sequentially so each delete sees the committed state of the previous
|
||||
one — avoids the race the per-email fan-out had on the panel side.
|
||||
Pass keepTraffic=true to retain the xray_client_traffic rows after
|
||||
deletion.
|
||||
id: >-
|
||||
delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
|
||||
- content: >-
|
||||
Create many clients in one call. Body is a JSON array of {client,
|
||||
inboundIds} payloads — the same shape /add accepts. Items are
|
||||
processed sequentially; per-email skip reasons are returned for items
|
||||
that fail (e.g., duplicate email). Triggers a single Xray restart at
|
||||
the end if any inbound was running.
|
||||
id: >-
|
||||
create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
|
||||
- content: >-
|
||||
Add many clients to a group in one call. Updates clients.group_name
|
||||
and patches the matching client entry inside every owning inbound's
|
||||
settings JSON in a single transaction. If the group name does not yet
|
||||
exist (in client_groups or as a derived label), it is auto-created as
|
||||
a persistent group. To clear the group label, use /groups/bulkRemove
|
||||
instead.
|
||||
id: >-
|
||||
add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
|
||||
- content: >-
|
||||
Clear the group label on many clients in one call. Inverse of
|
||||
/groups/bulkAdd. Clients themselves are kept — only the group label is
|
||||
cleared from clients.group_name and from each owning inbound's
|
||||
settings JSON. Groups become empty if all their members are removed.
|
||||
id: >-
|
||||
clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
|
||||
- content: >-
|
||||
Attach many existing clients to many inbounds in one call. Each client
|
||||
keeps its identity (email/UUID/password/subId) and a shared traffic
|
||||
row; all clients are added to a target inbound in a single
|
||||
AddInboundClient call. Clients already present on a target are
|
||||
reported under skipped. Returns per-email attached/skipped/errors
|
||||
lists and triggers a single Xray restart if any target inbound was
|
||||
running.
|
||||
id: >-
|
||||
attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Mirror of bulkAttach: detach many existing clients from many inbounds
|
||||
in one call. For each email, intersects the client's current inbounds
|
||||
with the requested set and detaches from those only; (email, inbound)
|
||||
pairs where the client is not currently attached are silently no-ops.
|
||||
Emails not attached to any of the requested inbounds are reported
|
||||
under skipped. Client records are kept even if they become orphaned —
|
||||
use bulkDel for full removal. Returns per-email
|
||||
detached/skipped/errors lists and triggers a single Xray restart if
|
||||
any target inbound was running.
|
||||
id: >-
|
||||
mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
|
||||
- content: >-
|
||||
Zero up/down counters for many clients in one call. Loops the
|
||||
single-reset path so each client is re-enabled across its attached
|
||||
inbounds and pushed to Xray/remote nodes. Returns the count of
|
||||
successfully reset clients.
|
||||
id: >-
|
||||
zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
|
||||
- content: >-
|
||||
List all client groups with their member counts. Merges persisted
|
||||
groups (rows in client_groups, including empty placeholders) with the
|
||||
distinct group_name values currently set on clients. Sorted
|
||||
alphabetically (case-insensitive).
|
||||
id: >-
|
||||
list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
|
||||
- content: >-
|
||||
Return just the email list of clients that currently belong to the
|
||||
given group. Useful for fanning a single bulk action over an entire
|
||||
group without round-tripping the full client list.
|
||||
id: >-
|
||||
return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
|
||||
- content: >-
|
||||
Create a new empty (placeholder) group. The group becomes selectable
|
||||
in client forms and the filter drawer even before any client is added
|
||||
to it. Errors if a group with the same name already exists.
|
||||
id: >-
|
||||
create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
|
||||
- content: >-
|
||||
Rename a group. The new name is applied to the client_groups row AND
|
||||
propagated to every matching client (both clients.group_name and the
|
||||
client entry inside every owning inbound's settings JSON) in a single
|
||||
transaction. Returns the number of clients whose label was updated.
|
||||
id: >-
|
||||
rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
|
||||
- content: >-
|
||||
Remove a group. Deletes the client_groups row and clears the group
|
||||
label from every matching client (both clients.group_name and the
|
||||
inbound settings JSON). The clients themselves are NOT deleted — use
|
||||
/bulkDel after filtering by group for that. Returns the count of
|
||||
clients whose label was cleared.
|
||||
id: >-
|
||||
remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
|
||||
- content: >-
|
||||
Zero out a single client’s up/down counters. Re-enables the client
|
||||
across every attached inbound and pushes the change to Xray (or the
|
||||
remote node) so depleted users can connect again immediately.
|
||||
id: >-
|
||||
zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
|
||||
- content: >-
|
||||
Manually adjust a client’s upload + download counters. Useful for
|
||||
migrations from external accounting systems.
|
||||
id: >-
|
||||
manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
|
||||
- content: >-
|
||||
List source IPs that have connected with the given client’s
|
||||
credentials. Returns an array of "ip (timestamp)" strings.
|
||||
id: >-
|
||||
list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
|
||||
- content: Reset the recorded IP list for a client.
|
||||
id: reset-the-recorded-ip-list-for-a-client
|
||||
- content: >-
|
||||
List the emails of currently connected clients (last seen within the
|
||||
heartbeat window), deduped across every node.
|
||||
id: >-
|
||||
list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
|
||||
- content: >-
|
||||
Online client emails grouped by the panelGuid of the node that
|
||||
physically hosts each client. The local panel uses its own GUID; each
|
||||
node (at any depth in a chain) uses its GUID. Lets the inbounds page
|
||||
attribute online status to the real node instead of the intermediate
|
||||
one it syncs through.
|
||||
id: >-
|
||||
online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
|
||||
- content: >-
|
||||
Per-client source IPs grouped by the panelGuid of the node that
|
||||
observed them. Lets the central panel attribute and enforce per-client
|
||||
IP limits using the real visitor IPs each node sees, instead of the
|
||||
address of the intermediate panel it syncs through.
|
||||
id: >-
|
||||
per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
|
||||
- content: >-
|
||||
Inbound tags that carried traffic within the heartbeat window, grouped
|
||||
by the hosting node's panelGuid. Pairs with onlinesByGuid so the
|
||||
inbounds page only marks a multi-inbound client online on the inbounds
|
||||
it actually used. Nodes that do not report per-inbound activity are
|
||||
absent.
|
||||
id: >-
|
||||
inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
|
||||
- content: Map of client email → last-seen unix timestamp.
|
||||
id: map-of-client-email--last-seen-unix-timestamp
|
||||
- content: Traffic counters for a client identified by email.
|
||||
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
|
||||
- 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
|
||||
streamSettings.externalProxy is set, returns one URL per external
|
||||
proxy. Protocols without a URL form (socks, http, mixed, wireguard,
|
||||
dokodemo, tunnel) contribute nothing.
|
||||
id: >-
|
||||
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-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<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 />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: هاستها
|
||||
description: >-
|
||||
نقاط پایانی بازنویسی به ازای هر inbound. هر host فعال یک لینک اشتراک/پراکسی
|
||||
اضافی با آدرس/پورت/TLS مخصوص خودش ارائه میدهد و جایگزین آرایهی قدیمی
|
||||
externalProxy میشود. همهی نقاط پایانی زیر /panel/api/hosts قرار دارند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every host across all inbounds, grouped by inbound then ordered by
|
||||
sort order.
|
||||
url: >-
|
||||
#list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
|
||||
- depth: 2
|
||||
title: Fetch a single host by ID.
|
||||
url: '#fetch-a-single-host-by-id'
|
||||
- depth: 2
|
||||
title: Fetch one inbound's hosts, ordered by sort order then id.
|
||||
url: '#fetch-one-inbounds-hosts-ordered-by-sort-order-then-id'
|
||||
- depth: 2
|
||||
title: Distinct, sorted set of tags used across all hosts.
|
||||
url: '#distinct-sorted-set-of-tags-used-across-all-hosts'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a host on an inbound. inboundId and remark are required; security
|
||||
defaults to "same" (inherit the inbound).
|
||||
url: >-
|
||||
#create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace a host’s content. The inbound and sort order are immutable here
|
||||
(use /reorder for ordering).
|
||||
url: >-
|
||||
#replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
|
||||
- depth: 2
|
||||
title: Delete a host.
|
||||
url: '#delete-a-host'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Enable or disable a single host (disabled hosts are skipped in
|
||||
subscriptions).
|
||||
url: >-
|
||||
#enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
|
||||
- depth: 2
|
||||
title: Set host sort order by the position of each id in the array.
|
||||
url: '#set-host-sort-order-by-the-position-of-each-id-in-the-array'
|
||||
- depth: 2
|
||||
title: Enable or disable many hosts in one call.
|
||||
url: '#enable-or-disable-many-hosts-in-one-call'
|
||||
- depth: 2
|
||||
title: Delete many hosts in one call.
|
||||
url: '#delete-many-hosts-in-one-call'
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every host across all inbounds, grouped by inbound then ordered
|
||||
by sort order.
|
||||
id: >-
|
||||
list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
|
||||
- content: Fetch a single host by ID.
|
||||
id: fetch-a-single-host-by-id
|
||||
- content: Fetch one inbound's hosts, ordered by sort order then id.
|
||||
id: fetch-one-inbounds-hosts-ordered-by-sort-order-then-id
|
||||
- content: Distinct, sorted set of tags used across all hosts.
|
||||
id: distinct-sorted-set-of-tags-used-across-all-hosts
|
||||
- content: >-
|
||||
Create a host on an inbound. inboundId and remark are required;
|
||||
security defaults to "same" (inherit the inbound).
|
||||
id: >-
|
||||
create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
|
||||
- content: >-
|
||||
Replace a host’s content. The inbound and sort order are immutable
|
||||
here (use /reorder for ordering).
|
||||
id: >-
|
||||
replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
|
||||
- content: Delete a host.
|
||||
id: delete-a-host
|
||||
- content: >-
|
||||
Enable or disable a single host (disabled hosts are skipped in
|
||||
subscriptions).
|
||||
id: >-
|
||||
enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
|
||||
- content: Set host sort order by the position of each id in the array.
|
||||
id: set-host-sort-order-by-the-position-of-each-id-in-the-array
|
||||
- content: Enable or disable many hosts in one call.
|
||||
id: enable-or-disable-many-hosts-in-one-call
|
||||
- content: Delete many hosts in one call.
|
||||
id: delete-many-hosts-in-one-call
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/hosts/list","method":"get"},{"path":"/panel/api/hosts/get/{id}","method":"get"},{"path":"/panel/api/hosts/byInbound/{inboundId}","method":"get"},{"path":"/panel/api/hosts/tags","method":"get"},{"path":"/panel/api/hosts/add","method":"post"},{"path":"/panel/api/hosts/update/{id}","method":"post"},{"path":"/panel/api/hosts/del/{id}","method":"post"},{"path":"/panel/api/hosts/setEnable/{id}","method":"post"},{"path":"/panel/api/hosts/reorder","method":"post"},{"path":"/panel/api/hosts/bulk/setEnable","method":"post"},{"path":"/panel/api/hosts/bulk/del","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
---
|
||||
title: ورودیها
|
||||
description: >-
|
||||
مدیریت پیکربندیهای ورودی و کلاینتهای آنها. همهٔ endpointها زیر
|
||||
/panel/api/inbounds قرار دارند و به یک نشست واردشده یا توکن Bearer نیاز دارند.
|
||||
endpointهای تولیدکنندهٔ لینک تنها زمانی به هدرهای forwarded اعتنا میکنند که
|
||||
درخواست از یک پراکسی مورد اعتماد پیکربندیشده برسد.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every inbound owned by the authenticated user, including each
|
||||
inbound’s clientStats traffic counters. settings, streamSettings, and
|
||||
sniffing are returned as nested JSON objects (no escaped strings);
|
||||
legacy callers that send them back as JSON-encoded strings are still
|
||||
accepted on write.
|
||||
url: >-
|
||||
#list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Same shape as /list but with settings.clients[] stripped down to {email,
|
||||
enable, comment} and ClientStats not enriched with UUID/SubId. Use this
|
||||
for list pages; fetch /get/:id when you need the full per-client payload
|
||||
(uuid, password, flow, ...).
|
||||
url: >-
|
||||
#same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
|
||||
- depth: 2
|
||||
title: >-
|
||||
Lightweight picker projection of the authenticated user’s inbounds.
|
||||
Returns id, remark, tag, protocol, port, a server-computed
|
||||
tlsFlowCapable flag (true for VLESS on TCP with tls or reality, or on
|
||||
XHTTP with VLESS encryption / vlessenc enabled), and ssMethod (the
|
||||
Shadowsocks cipher, empty for non-Shadowsocks inbounds — used by the
|
||||
client UI to generate a valid Shadowsocks 2022 PSK). Use this for
|
||||
dropdowns and attach pickers — it skips settings, streamSettings, and
|
||||
clientStats so the payload stays small even on panels with thousands of
|
||||
clients.
|
||||
url: >-
|
||||
#lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
|
||||
- depth: 2
|
||||
title: Fetch a single inbound by numeric ID.
|
||||
url: '#fetch-a-single-inbound-by-numeric-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create a new inbound. Send the full inbound payload (protocol, port,
|
||||
settings, streamSettings, sniffing, remark, expiryTime, total, enable).
|
||||
settings, streamSettings, and sniffing may be sent as nested JSON
|
||||
objects (preferred) or as JSON-encoded strings (legacy).
|
||||
url: >-
|
||||
#create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
|
||||
- depth: 2
|
||||
title: Delete an inbound by ID. Also removes its associated client stats rows.
|
||||
url: '#delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete many inbounds in one call. Processes the list sequentially;
|
||||
failures are reported per id and the rest still proceed. Restarts xray
|
||||
at most once.
|
||||
url: >-
|
||||
#delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
|
||||
inbounds with thousands of clients — prefer /setEnable for enable-only
|
||||
flips.
|
||||
url: >-
|
||||
#replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle only the enable flag without serialising the whole settings JSON.
|
||||
Recommended for UI switches on large inbounds.
|
||||
url: >-
|
||||
#toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Zero out upload + download counters for a single inbound. Does not touch
|
||||
per-client counters.
|
||||
url: >-
|
||||
#zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
|
||||
- depth: 2
|
||||
title: >-
|
||||
Remove every client attached to a single inbound while keeping the
|
||||
inbound itself. Collects emails from settings.clients[] and feeds them
|
||||
into the optimized bulk-delete path (runtime user removal + traffic-row
|
||||
cleanup + SyncInbound). Destructive and cannot be undone.
|
||||
url: >-
|
||||
#remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reset upload + download counters on every inbound. Destructive —
|
||||
accounting history is lost.
|
||||
url: >-
|
||||
#reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
|
||||
- depth: 2
|
||||
title: >-
|
||||
Bulk-import an inbound from a JSON blob (e.g. one exported via the UI).
|
||||
The body uses form encoding with a single "data" field.
|
||||
url: >-
|
||||
#bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
|
||||
- depth: 2
|
||||
title: >-
|
||||
Receive a master panel's aggregated per-client usage, keyed by the
|
||||
master's GUID. Stored in a side table used only for the UI display
|
||||
overlay and local quota enforcement — never folded into the local
|
||||
counters that masters poll, so delta accounting stays intact. Called
|
||||
panel-to-panel by the node traffic sync job.
|
||||
url: >-
|
||||
#receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
|
||||
- depth: 2
|
||||
title: >-
|
||||
List the fallback rules attached to a master VLESS/Trojan TCP-TLS
|
||||
inbound. Each rule links one child inbound (the dest) to optional
|
||||
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
|
||||
inbound's listen+port is used.
|
||||
url: >-
|
||||
#list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
|
||||
- depth: 2
|
||||
title: >-
|
||||
Replace the entire fallback list for a master inbound. Body is JSON.
|
||||
Triggers an Xray restart.
|
||||
url: >-
|
||||
#replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every inbound owned by the authenticated user, including each
|
||||
inbound’s clientStats traffic counters. settings, streamSettings, and
|
||||
sniffing are returned as nested JSON objects (no escaped strings);
|
||||
legacy callers that send them back as JSON-encoded strings are still
|
||||
accepted on write.
|
||||
id: >-
|
||||
list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
|
||||
- content: >-
|
||||
Same shape as /list but with settings.clients[] stripped down to
|
||||
{email, enable, comment} and ClientStats not enriched with UUID/SubId.
|
||||
Use this for list pages; fetch /get/:id when you need the full
|
||||
per-client payload (uuid, password, flow, ...).
|
||||
id: >-
|
||||
same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
|
||||
- content: >-
|
||||
Lightweight picker projection of the authenticated user’s inbounds.
|
||||
Returns id, remark, tag, protocol, port, a server-computed
|
||||
tlsFlowCapable flag (true for VLESS on TCP with tls or reality, or on
|
||||
XHTTP with VLESS encryption / vlessenc enabled), and ssMethod (the
|
||||
Shadowsocks cipher, empty for non-Shadowsocks inbounds — used by the
|
||||
client UI to generate a valid Shadowsocks 2022 PSK). Use this for
|
||||
dropdowns and attach pickers — it skips settings, streamSettings, and
|
||||
clientStats so the payload stays small even on panels with thousands
|
||||
of clients.
|
||||
id: >-
|
||||
lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
|
||||
- content: Fetch a single inbound by numeric ID.
|
||||
id: fetch-a-single-inbound-by-numeric-id
|
||||
- content: >-
|
||||
Create a new inbound. Send the full inbound payload (protocol, port,
|
||||
settings, streamSettings, sniffing, remark, expiryTime, total,
|
||||
enable). settings, streamSettings, and sniffing may be sent as nested
|
||||
JSON objects (preferred) or as JSON-encoded strings (legacy).
|
||||
id: >-
|
||||
create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
|
||||
- content: >-
|
||||
Delete an inbound by ID. Also removes its associated client stats
|
||||
rows.
|
||||
id: delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows
|
||||
- content: >-
|
||||
Delete many inbounds in one call. Processes the list sequentially;
|
||||
failures are reported per id and the rest still proceed. Restarts xray
|
||||
at most once.
|
||||
id: >-
|
||||
delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
|
||||
- content: >-
|
||||
Replace an inbound’s configuration. Body shape mirrors /add. Heavy on
|
||||
inbounds with thousands of clients — prefer /setEnable for enable-only
|
||||
flips.
|
||||
id: >-
|
||||
replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
|
||||
- content: >-
|
||||
Toggle only the enable flag without serialising the whole settings
|
||||
JSON. Recommended for UI switches on large inbounds.
|
||||
id: >-
|
||||
toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
|
||||
- content: >-
|
||||
Zero out upload + download counters for a single inbound. Does not
|
||||
touch per-client counters.
|
||||
id: >-
|
||||
zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
|
||||
- content: >-
|
||||
Remove every client attached to a single inbound while keeping the
|
||||
inbound itself. Collects emails from settings.clients[] and feeds them
|
||||
into the optimized bulk-delete path (runtime user removal +
|
||||
traffic-row cleanup + SyncInbound). Destructive and cannot be undone.
|
||||
id: >-
|
||||
remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
|
||||
- content: >-
|
||||
Reset upload + download counters on every inbound. Destructive —
|
||||
accounting history is lost.
|
||||
id: >-
|
||||
reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
|
||||
- content: >-
|
||||
Bulk-import an inbound from a JSON blob (e.g. one exported via the
|
||||
UI). The body uses form encoding with a single "data" field.
|
||||
id: >-
|
||||
bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
|
||||
- content: >-
|
||||
Receive a master panel's aggregated per-client usage, keyed by the
|
||||
master's GUID. Stored in a side table used only for the UI display
|
||||
overlay and local quota enforcement — never folded into the local
|
||||
counters that masters poll, so delta accounting stays intact. Called
|
||||
panel-to-panel by the node traffic sync job.
|
||||
id: >-
|
||||
receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
|
||||
- content: >-
|
||||
List the fallback rules attached to a master VLESS/Trojan TCP-TLS
|
||||
inbound. Each rule links one child inbound (the dest) to optional
|
||||
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
|
||||
inbound's listen+port is used.
|
||||
id: >-
|
||||
list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
|
||||
- content: >-
|
||||
Replace the entire fallback list for a master inbound. Body is JSON.
|
||||
Triggers an Xray restart.
|
||||
id: >-
|
||||
replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/inbounds/list","method":"get"},{"path":"/panel/api/inbounds/list/slim","method":"get"},{"path":"/panel/api/inbounds/options","method":"get"},{"path":"/panel/api/inbounds/get/{id}","method":"get"},{"path":"/panel/api/inbounds/add","method":"post"},{"path":"/panel/api/inbounds/del/{id}","method":"post"},{"path":"/panel/api/inbounds/bulkDel","method":"post"},{"path":"/panel/api/inbounds/update/{id}","method":"post"},{"path":"/panel/api/inbounds/setEnable/{id}","method":"post"},{"path":"/panel/api/inbounds/{id}/resetTraffic","method":"post"},{"path":"/panel/api/inbounds/{id}/delAllClients","method":"post"},{"path":"/panel/api/inbounds/resetAllTraffics","method":"post"},{"path":"/panel/api/inbounds/import","method":"post"},{"path":"/panel/api/inbounds/pushClientTraffics","method":"post"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"get"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: مرجع API
|
||||
description: REST API پنل 3x-ui — احراز هویت، inboundها، کلاینتها، آمار سرور و موارد دیگر، تولیدشده از مشخصات OpenAPI.
|
||||
icon: Webhook
|
||||
---
|
||||
|
||||
پنل 3x-ui یک REST API برای خودکارسازی در اختیار میگذارد. این صفحات از مشخصات
|
||||
OpenAPI پنل تولید شدهاند، بنابراین همواره با اسکیمای مستندشده هماهنگ هستند.
|
||||
|
||||
## احراز هویت
|
||||
|
||||
درخواستها یا با یک **کوکی نشست** (از `POST /login`) یا با یک
|
||||
**توکن Bearer** احراز هویت میشوند:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
توکنهای API را در پنل بسازید؛ این توکنها اعتبارنامههای ادمین کامل هستند، پس آنها را
|
||||
بهصورت ایمن نگهداری کنید. به [توکنهای API](/docs/reference/api/api-tokens) مراجعه کنید.
|
||||
|
||||
برای هر یک از endpointهای زیر یک درخواست احرازهویتشده بسازید:
|
||||
|
||||
<ApiRequestBuilder />
|
||||
|
||||
## مرور بر اساس حوزه
|
||||
|
||||
<Cards>
|
||||
<Card title="احراز هویت" href="/docs/reference/api/authentication" />
|
||||
<Card title="Inboundها" href="/docs/reference/api/inbounds" />
|
||||
<Card title="کلاینتها" href="/docs/reference/api/clients" />
|
||||
<Card title="سرور" href="/docs/reference/api/server" />
|
||||
<Card title="تنظیمات" href="/docs/reference/api/settings" />
|
||||
<Card title="تنظیمات Xray" href="/docs/reference/api/xray-settings" />
|
||||
</Cards>
|
||||
|
||||
<Callout type="info">
|
||||
این مرجع با اجرای `pnpm gen:api` از `public/openapi.json` بازتولید میشود.
|
||||
صفحات تگ تولیدشده را بهصورت دستی ویرایش نکنید.
|
||||
</Callout>
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "مرجع API",
|
||||
"icon": "Webhook",
|
||||
"pages": [
|
||||
"index",
|
||||
"authentication",
|
||||
"api-tokens",
|
||||
"inbounds",
|
||||
"clients",
|
||||
"server",
|
||||
"settings",
|
||||
"xray-settings",
|
||||
"subscription-server",
|
||||
"hosts",
|
||||
"nodes",
|
||||
"backup",
|
||||
"websocket"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
---
|
||||
title: نودها
|
||||
description: >-
|
||||
مدیریت پنلهای راهدور 3x-ui که بهعنوان نود برای یک پنل مرکزی عمل میکنند. همهٔ
|
||||
اندپوینتها زیر مسیر /panel/api/nodes.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
List every configured node with its connection details, health, and last
|
||||
heartbeat patch.
|
||||
url: >-
|
||||
#list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
|
||||
- depth: 2
|
||||
title: >-
|
||||
This panel's node-auth CA certificate (public, PEM) to paste into a
|
||||
node's mTLS trust setting. Lazily mints the CA and the master client
|
||||
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
|
||||
url: >-
|
||||
#this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Set the CA certificate this panel trusts for incoming node-API client
|
||||
certificates (this panel acting as a node). Paste the managing panel's
|
||||
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty value
|
||||
must be a PEM certificate. Applied on the next panel restart.
|
||||
url: >-
|
||||
#set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
|
||||
- depth: 2
|
||||
title: Fetch a single node by ID.
|
||||
url: '#fetch-a-single-node-by-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch a node's own web TLS certificate/key file paths (proxied to the
|
||||
node). Used by the inbound form's "Set Cert from Panel" so a
|
||||
node-assigned inbound gets paths that exist on the node, not the central
|
||||
panel.
|
||||
url: >-
|
||||
#fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
||||
- depth: 2
|
||||
title: >-
|
||||
Register a new remote node. Provide its URL, apiToken, and optional
|
||||
remark / allowPrivateAddress flag.
|
||||
url: >-
|
||||
#register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
|
||||
- depth: 2
|
||||
title: Replace a node’s connection details. Same body shape as /add.
|
||||
url: '#replace-a-nodes-connection-details-same-body-shape-as-add'
|
||||
- depth: 2
|
||||
title: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||
url: '#delete-a-node-inbounds-bound-to-it-are-not-auto-migrated'
|
||||
- depth: 2
|
||||
title: Pause or resume traffic sync with this node.
|
||||
url: '#pause-or-resume-traffic-sync-with-this-node'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Probe a node without saving it. Uses the body as connection details and
|
||||
returns the same heartbeat snapshot a registered node would have.
|
||||
url: >-
|
||||
#probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
|
||||
- depth: 2
|
||||
title: >-
|
||||
Connect to the node over HTTPS without verifying its certificate and
|
||||
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
|
||||
Node dialog to fetch and pin a self-signed certificate. Uses the same
|
||||
body as /test.
|
||||
url: >-
|
||||
#connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
|
||||
- depth: 2
|
||||
title: >-
|
||||
Use unsaved node connection details to list the remote inbounds
|
||||
available for selective import.
|
||||
url: >-
|
||||
#use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
|
||||
- depth: 2
|
||||
title: Probe an existing node, updating its cached health state.
|
||||
url: '#probe-an-existing-node-updating-its-cached-health-state'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Trigger the official panel self-updater on each given node (downloads
|
||||
the latest release and restarts). Only enabled, online nodes are
|
||||
updated; offline/disabled ones are reported as skipped. Set "dev": true
|
||||
to move the nodes to the rolling per-commit dev channel instead of the
|
||||
latest stable release. Returns a per-node result list.
|
||||
url: >-
|
||||
#trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
|
||||
- depth: 2
|
||||
title: >-
|
||||
Aggregated metric history for a node — same shape as /server/history,
|
||||
scoped to one node.
|
||||
url: >-
|
||||
#aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
List every configured node with its connection details, health, and
|
||||
last heartbeat patch.
|
||||
id: >-
|
||||
list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
|
||||
- content: >-
|
||||
This panel's node-auth CA certificate (public, PEM) to paste into a
|
||||
node's mTLS trust setting. Lazily mints the CA and the master client
|
||||
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
|
||||
id: >-
|
||||
this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
|
||||
- content: >-
|
||||
Set the CA certificate this panel trusts for incoming node-API client
|
||||
certificates (this panel acting as a node). Paste the managing panel's
|
||||
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty
|
||||
value must be a PEM certificate. Applied on the next panel restart.
|
||||
id: >-
|
||||
set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
|
||||
- content: Fetch a single node by ID.
|
||||
id: fetch-a-single-node-by-id
|
||||
- content: >-
|
||||
Fetch a node's own web TLS certificate/key file paths (proxied to the
|
||||
node). Used by the inbound form's "Set Cert from Panel" so a
|
||||
node-assigned inbound gets paths that exist on the node, not the
|
||||
central panel.
|
||||
id: >-
|
||||
fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
||||
- content: >-
|
||||
Register a new remote node. Provide its URL, apiToken, and optional
|
||||
remark / allowPrivateAddress flag.
|
||||
id: >-
|
||||
register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
|
||||
- content: Replace a node’s connection details. Same body shape as /add.
|
||||
id: replace-a-nodes-connection-details-same-body-shape-as-add
|
||||
- content: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||
id: delete-a-node-inbounds-bound-to-it-are-not-auto-migrated
|
||||
- content: Pause or resume traffic sync with this node.
|
||||
id: pause-or-resume-traffic-sync-with-this-node
|
||||
- content: >-
|
||||
Probe a node without saving it. Uses the body as connection details
|
||||
and returns the same heartbeat snapshot a registered node would have.
|
||||
id: >-
|
||||
probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
|
||||
- content: >-
|
||||
Connect to the node over HTTPS without verifying its certificate and
|
||||
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
|
||||
Node dialog to fetch and pin a self-signed certificate. Uses the same
|
||||
body as /test.
|
||||
id: >-
|
||||
connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
|
||||
- content: >-
|
||||
Use unsaved node connection details to list the remote inbounds
|
||||
available for selective import.
|
||||
id: >-
|
||||
use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
|
||||
- content: Probe an existing node, updating its cached health state.
|
||||
id: probe-an-existing-node-updating-its-cached-health-state
|
||||
- content: >-
|
||||
Trigger the official panel self-updater on each given node (downloads
|
||||
the latest release and restarts). Only enabled, online nodes are
|
||||
updated; offline/disabled ones are reported as skipped. Set "dev":
|
||||
true to move the nodes to the rolling per-commit dev channel instead
|
||||
of the latest stable release. Returns a per-node result list.
|
||||
id: >-
|
||||
trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
|
||||
- content: >-
|
||||
Aggregated metric history for a node — same shape as /server/history,
|
||||
scoped to one node.
|
||||
id: >-
|
||||
aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/nodes/list","method":"get"},{"path":"/panel/api/nodes/mtls/ca","method":"post"},{"path":"/panel/api/nodes/mtls/trustCA","method":"post"},{"path":"/panel/api/nodes/get/{id}","method":"get"},{"path":"/panel/api/nodes/webCert/{id}","method":"get"},{"path":"/panel/api/nodes/add","method":"post"},{"path":"/panel/api/nodes/update/{id}","method":"post"},{"path":"/panel/api/nodes/del/{id}","method":"post"},{"path":"/panel/api/nodes/setEnable/{id}","method":"post"},{"path":"/panel/api/nodes/test","method":"post"},{"path":"/panel/api/nodes/certFingerprint","method":"post"},{"path":"/panel/api/nodes/inbounds","method":"post"},{"path":"/panel/api/nodes/probe/{id}","method":"post"},{"path":"/panel/api/nodes/updatePanel","method":"post"},{"path":"/panel/api/nodes/history/{id}/{metric}/{bucket}","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
---
|
||||
title: سرور
|
||||
description: >-
|
||||
وضعیت سیستم، دریافت لاگ، تولیدکنندههای گواهی، مدیریت باینری Xray و
|
||||
پشتیبانگیری/بازیابی. همگی زیرمجموعهٔ /panel/api/server.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
|
||||
averages, open connections, Xray state. Cached and refreshed every 2
|
||||
seconds in the background.
|
||||
url: >-
|
||||
#real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reports whether per-client IP limits can be enforced on this host. The
|
||||
panel uses it to gate the "IP Limit" field, since enforcement depends on
|
||||
Fail2ban being installed.
|
||||
url: >-
|
||||
#reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead — same
|
||||
data with a uniform {t, v} shape.
|
||||
url: >-
|
||||
#legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
|
||||
- depth: 2
|
||||
title: >-
|
||||
Aggregated time-series for one metric. Returns an array of {t, v}
|
||||
samples covering the last ~6 hours.
|
||||
url: >-
|
||||
#aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
|
||||
- depth: 2
|
||||
title: >-
|
||||
Xray runtime metrics state — whether the xray config has a `metrics`
|
||||
block, which expvar keys are flowing, and the current snapshot values
|
||||
for each. Returns an empty state when metrics are not configured.
|
||||
url: >-
|
||||
#xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
|
||||
- depth: 2
|
||||
title: >-
|
||||
Time-series history for one Xray runtime metric over the last ~6 hours.
|
||||
Same {t, v} shape as /history/:metric/:bucket.
|
||||
url: >-
|
||||
#time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
|
||||
- depth: 2
|
||||
title: >-
|
||||
Latest snapshot from the Xray observatory — per-outbound latency, health
|
||||
status, and last-probe time. Only populated when the Xray config has an
|
||||
observatory configured.
|
||||
url: >-
|
||||
#latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
|
||||
- depth: 2
|
||||
title: >-
|
||||
Time-series of observatory probe results for one outbound tag. Same {t,
|
||||
v} shape as the other history endpoints.
|
||||
url: >-
|
||||
#time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
||||
- depth: 2
|
||||
title: List Xray binary versions available for install on this host.
|
||||
url: '#list-xray-binary-versions-available-for-install-on-this-host'
|
||||
- depth: 2
|
||||
title: Check whether a newer 3x-ui release is available on GitHub.
|
||||
url: '#check-whether-a-newer-3x-ui-release-is-available-on-github'
|
||||
- depth: 2
|
||||
title: Return the assembled Xray config that’s currently running on this host.
|
||||
url: '#return-the-assembled-xray-config-thats-currently-running-on-this-host'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Stream the SQLite database file as an attachment. Use as a manual
|
||||
backup.
|
||||
url: '#stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Stream a cross-engine migration file as an attachment: a .dump (SQL
|
||||
text) on SQLite, or a .db SQLite database built from the live data on
|
||||
PostgreSQL.
|
||||
url: >-
|
||||
#stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
|
||||
- depth: 2
|
||||
title: Generate a fresh UUID v4. Convenience helper for client IDs.
|
||||
url: '#generate-a-fresh-uuid-v4-convenience-helper-for-client-ids'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return this panel's own web TLS certificate and key file paths. The
|
||||
central panel calls it on a node (via the node API token) so "Set Cert
|
||||
from Panel" fills a node-assigned inbound with paths that exist on the
|
||||
node.
|
||||
url: >-
|
||||
#return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
|
||||
- depth: 2
|
||||
title: >-
|
||||
Read-only summaries (guid, parentGuid, name, address, status, versions)
|
||||
of the nodes this panel manages. A parent panel calls it on a node (via
|
||||
the node API token) to surface transitive sub-nodes in a chained
|
||||
topology. Counts are computed by the parent, not returned here.
|
||||
url: >-
|
||||
#read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
|
||||
- depth: 2
|
||||
title: Generate a new X25519 keypair for Reality.
|
||||
url: '#generate-a-new-x25519-keypair-for-reality'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
|
||||
{privateKey, publicKey, seed}.
|
||||
url: >-
|
||||
#generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
|
||||
{clientKey, serverKey}.
|
||||
url: >-
|
||||
#generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate VLESS encryption auth options. Returns an auths array each with
|
||||
id, label, encryption, and decryption fields.
|
||||
url: >-
|
||||
#generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
|
||||
- depth: 2
|
||||
title: Stop the Xray binary. All proxies go offline immediately.
|
||||
url: '#stop-the-xray-binary-all-proxies-go-offline-immediately'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reload Xray with the current config. Typically required after structural
|
||||
inbound or routing changes.
|
||||
url: >-
|
||||
#reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
|
||||
- depth: 2
|
||||
title: >-
|
||||
Download and install the specified Xray version. Pass "latest" for the
|
||||
newest release.
|
||||
url: >-
|
||||
#download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
|
||||
- depth: 2
|
||||
title: >-
|
||||
Self-update the panel to the latest version. The server restarts on
|
||||
success.
|
||||
url: >-
|
||||
#self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
|
||||
- depth: 2
|
||||
title: >-
|
||||
Toggle the panel update channel between stable and the rolling
|
||||
per-commit dev release. Only effective on dev builds.
|
||||
url: >-
|
||||
#toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Refresh the default GeoIP / GeoSite data files. Body can include a
|
||||
fileName, or use the /:fileName variant.
|
||||
url: >-
|
||||
#refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
|
||||
- depth: 2
|
||||
title: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
|
||||
url: '#refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat'
|
||||
- depth: 2
|
||||
title: Return the last N lines of the panel’s own log.
|
||||
url: '#return-the-last-n-lines-of-the-panels-own-log'
|
||||
- depth: 2
|
||||
title: Return the last N lines of the Xray process log.
|
||||
url: '#return-the-last-n-lines-of-the-xray-process-log'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Restore the panel DB from an uploaded SQLite file (multipart form, field
|
||||
name "db"). The panel restarts after restore. Destructive.
|
||||
url: >-
|
||||
#restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
|
||||
- depth: 2
|
||||
title: >-
|
||||
Generate a new ECH (Encrypted Client Hello) keypair and config list for
|
||||
the given SNI.
|
||||
url: >-
|
||||
#generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
|
||||
- depth: 2
|
||||
title: >-
|
||||
Compute the hex SHA-256 of a certificate (DER) for pinning
|
||||
(pinnedPeerCertSha256). Provide either a server file path or inline
|
||||
PEM/DER content.
|
||||
url: >-
|
||||
#compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
|
||||
- depth: 2
|
||||
title: >-
|
||||
Run `xray tls ping` against a remote server and return its live
|
||||
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
|
||||
url: >-
|
||||
#run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
|
||||
- depth: 2
|
||||
title: >-
|
||||
Fetch the fully aggregated inbound_client_ips database table. Used by
|
||||
nodes to sync recently active IPs across the cluster.
|
||||
url: >-
|
||||
#fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
|
||||
- depth: 2
|
||||
title: >-
|
||||
Submit a list of recently active IP timestamps. The panel merges them
|
||||
with the existing database to maintain a unified global IP-limit view.
|
||||
url: >-
|
||||
#submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
|
||||
averages, open connections, Xray state. Cached and refreshed every 2
|
||||
seconds in the background.
|
||||
id: >-
|
||||
real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
|
||||
- content: >-
|
||||
Reports whether per-client IP limits can be enforced on this host. The
|
||||
panel uses it to gate the "IP Limit" field, since enforcement depends
|
||||
on Fail2ban being installed.
|
||||
id: >-
|
||||
reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
|
||||
- content: >-
|
||||
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead —
|
||||
same data with a uniform {t, v} shape.
|
||||
id: >-
|
||||
legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
|
||||
- content: >-
|
||||
Aggregated time-series for one metric. Returns an array of {t, v}
|
||||
samples covering the last ~6 hours.
|
||||
id: >-
|
||||
aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
|
||||
- content: >-
|
||||
Xray runtime metrics state — whether the xray config has a `metrics`
|
||||
block, which expvar keys are flowing, and the current snapshot values
|
||||
for each. Returns an empty state when metrics are not configured.
|
||||
id: >-
|
||||
xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
|
||||
- content: >-
|
||||
Time-series history for one Xray runtime metric over the last ~6
|
||||
hours. Same {t, v} shape as /history/:metric/:bucket.
|
||||
id: >-
|
||||
time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
|
||||
- content: >-
|
||||
Latest snapshot from the Xray observatory — per-outbound latency,
|
||||
health status, and last-probe time. Only populated when the Xray
|
||||
config has an observatory configured.
|
||||
id: >-
|
||||
latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
|
||||
- content: >-
|
||||
Time-series of observatory probe results for one outbound tag. Same
|
||||
{t, v} shape as the other history endpoints.
|
||||
id: >-
|
||||
time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
||||
- content: List Xray binary versions available for install on this host.
|
||||
id: list-xray-binary-versions-available-for-install-on-this-host
|
||||
- content: Check whether a newer 3x-ui release is available on GitHub.
|
||||
id: check-whether-a-newer-3x-ui-release-is-available-on-github
|
||||
- content: >-
|
||||
Return the assembled Xray config that’s currently running on this
|
||||
host.
|
||||
id: return-the-assembled-xray-config-thats-currently-running-on-this-host
|
||||
- content: >-
|
||||
Stream the SQLite database file as an attachment. Use as a manual
|
||||
backup.
|
||||
id: >-
|
||||
stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup
|
||||
- content: >-
|
||||
Stream a cross-engine migration file as an attachment: a .dump (SQL
|
||||
text) on SQLite, or a .db SQLite database built from the live data on
|
||||
PostgreSQL.
|
||||
id: >-
|
||||
stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
|
||||
- content: Generate a fresh UUID v4. Convenience helper for client IDs.
|
||||
id: generate-a-fresh-uuid-v4-convenience-helper-for-client-ids
|
||||
- content: >-
|
||||
Return this panel's own web TLS certificate and key file paths. The
|
||||
central panel calls it on a node (via the node API token) so "Set Cert
|
||||
from Panel" fills a node-assigned inbound with paths that exist on the
|
||||
node.
|
||||
id: >-
|
||||
return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
|
||||
- content: >-
|
||||
Read-only summaries (guid, parentGuid, name, address, status,
|
||||
versions) of the nodes this panel manages. A parent panel calls it on
|
||||
a node (via the node API token) to surface transitive sub-nodes in a
|
||||
chained topology. Counts are computed by the parent, not returned
|
||||
here.
|
||||
id: >-
|
||||
read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
|
||||
- content: Generate a new X25519 keypair for Reality.
|
||||
id: generate-a-new-x25519-keypair-for-reality
|
||||
- content: >-
|
||||
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
|
||||
{privateKey, publicKey, seed}.
|
||||
id: >-
|
||||
generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
|
||||
- content: >-
|
||||
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
|
||||
{clientKey, serverKey}.
|
||||
id: >-
|
||||
generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
|
||||
- content: >-
|
||||
Generate VLESS encryption auth options. Returns an auths array each
|
||||
with id, label, encryption, and decryption fields.
|
||||
id: >-
|
||||
generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
|
||||
- content: Stop the Xray binary. All proxies go offline immediately.
|
||||
id: stop-the-xray-binary-all-proxies-go-offline-immediately
|
||||
- content: >-
|
||||
Reload Xray with the current config. Typically required after
|
||||
structural inbound or routing changes.
|
||||
id: >-
|
||||
reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
|
||||
- content: >-
|
||||
Download and install the specified Xray version. Pass "latest" for the
|
||||
newest release.
|
||||
id: >-
|
||||
download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
|
||||
- content: >-
|
||||
Self-update the panel to the latest version. The server restarts on
|
||||
success.
|
||||
id: >-
|
||||
self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
|
||||
- content: >-
|
||||
Toggle the panel update channel between stable and the rolling
|
||||
per-commit dev release. Only effective on dev builds.
|
||||
id: >-
|
||||
toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
|
||||
- content: >-
|
||||
Refresh the default GeoIP / GeoSite data files. Body can include a
|
||||
fileName, or use the /:fileName variant.
|
||||
id: >-
|
||||
refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
|
||||
- content: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
|
||||
id: refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat
|
||||
- content: Return the last N lines of the panel’s own log.
|
||||
id: return-the-last-n-lines-of-the-panels-own-log
|
||||
- content: Return the last N lines of the Xray process log.
|
||||
id: return-the-last-n-lines-of-the-xray-process-log
|
||||
- content: >-
|
||||
Restore the panel DB from an uploaded SQLite file (multipart form,
|
||||
field name "db"). The panel restarts after restore. Destructive.
|
||||
id: >-
|
||||
restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
|
||||
- content: >-
|
||||
Generate a new ECH (Encrypted Client Hello) keypair and config list
|
||||
for the given SNI.
|
||||
id: >-
|
||||
generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
|
||||
- content: >-
|
||||
Compute the hex SHA-256 of a certificate (DER) for pinning
|
||||
(pinnedPeerCertSha256). Provide either a server file path or inline
|
||||
PEM/DER content.
|
||||
id: >-
|
||||
compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
|
||||
- content: >-
|
||||
Run `xray tls ping` against a remote server and return its live
|
||||
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
|
||||
id: >-
|
||||
run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
|
||||
- content: >-
|
||||
Fetch the fully aggregated inbound_client_ips database table. Used by
|
||||
nodes to sync recently active IPs across the cluster.
|
||||
id: >-
|
||||
fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
|
||||
- content: >-
|
||||
Submit a list of recently active IP timestamps. The panel merges them
|
||||
with the existing database to maintain a unified global IP-limit view.
|
||||
id: >-
|
||||
submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/server/status","method":"get"},{"path":"/panel/api/server/fail2banStatus","method":"get"},{"path":"/panel/api/server/cpuHistory/{bucket}","method":"get"},{"path":"/panel/api/server/history/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayMetricsState","method":"get"},{"path":"/panel/api/server/xrayMetricsHistory/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayObservatory","method":"get"},{"path":"/panel/api/server/xrayObservatoryHistory/{tag}/{bucket}","method":"get"},{"path":"/panel/api/server/getXrayVersion","method":"get"},{"path":"/panel/api/server/getPanelUpdateInfo","method":"get"},{"path":"/panel/api/server/getConfigJson","method":"get"},{"path":"/panel/api/server/getDb","method":"get"},{"path":"/panel/api/server/getMigration","method":"get"},{"path":"/panel/api/server/getNewUUID","method":"get"},{"path":"/panel/api/server/getWebCertFiles","method":"get"},{"path":"/panel/api/server/descendants","method":"get"},{"path":"/panel/api/server/getNewX25519Cert","method":"get"},{"path":"/panel/api/server/getNewmldsa65","method":"get"},{"path":"/panel/api/server/getNewmlkem768","method":"get"},{"path":"/panel/api/server/getNewVlessEnc","method":"get"},{"path":"/panel/api/server/stopXrayService","method":"post"},{"path":"/panel/api/server/restartXrayService","method":"post"},{"path":"/panel/api/server/installXray/{version}","method":"post"},{"path":"/panel/api/server/updatePanel","method":"post"},{"path":"/panel/api/server/setUpdateChannel","method":"post"},{"path":"/panel/api/server/updateGeofile","method":"post"},{"path":"/panel/api/server/updateGeofile/{fileName}","method":"post"},{"path":"/panel/api/server/logs/{count}","method":"post"},{"path":"/panel/api/server/xraylogs/{count}","method":"post"},{"path":"/panel/api/server/importDB","method":"post"},{"path":"/panel/api/server/getNewEchCert","method":"post"},{"path":"/panel/api/server/getCertHash","method":"post"},{"path":"/panel/api/server/getRemoteCertHash","method":"post"},{"path":"/panel/api/server/clientIps","method":"get"},{"path":"/panel/api/server/clientIps","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: تنظیمات
|
||||
description: >-
|
||||
پیکربندی پنل و اطلاعات ورود کاربر. همهی نقاط پایانی زیر /panel/api/setting
|
||||
قرار دارند و به یک نشست واردشده یا توکن Bearer نیاز دارند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return every panel setting: web server, Telegram bot, subscription,
|
||||
security, LDAP. The full JSON blob that the Settings page edits.
|
||||
url: >-
|
||||
#return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the computed default settings based on the request host. Useful
|
||||
to preview what a fresh install would use.
|
||||
url: >-
|
||||
#return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
|
||||
- depth: 2
|
||||
title: >-
|
||||
Persist every setting at once. The body mirrors the shape returned by
|
||||
/all. Invalid values (bad ports, missing cert pairs, etc.) are rejected
|
||||
before write.
|
||||
url: >-
|
||||
#persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
|
||||
- depth: 2
|
||||
title: >-
|
||||
Change the panel admin username and password. Requires the current
|
||||
credentials for verification. The session is refreshed with the new
|
||||
values on success.
|
||||
url: >-
|
||||
#change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
||||
- depth: 2
|
||||
title: >-
|
||||
Restart the entire 3x-ui process after a 3-second grace period. The
|
||||
connection drops immediately; the panel comes back online ~5-10 seconds
|
||||
later.
|
||||
url: >-
|
||||
#restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test SMTP connection with stage-by-stage reporting (connect, auth,
|
||||
send). Returns structured result with stage and message.
|
||||
url: >-
|
||||
#test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test Telegram bot connection by sending a test message to the configured
|
||||
chat.
|
||||
url: >-
|
||||
#test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the built-in default Xray JSON config template that ships with
|
||||
this panel version.
|
||||
url: >-
|
||||
#return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Return every panel setting: web server, Telegram bot, subscription,
|
||||
security, LDAP. The full JSON blob that the Settings page edits.
|
||||
id: >-
|
||||
return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
|
||||
- content: >-
|
||||
Return the computed default settings based on the request host. Useful
|
||||
to preview what a fresh install would use.
|
||||
id: >-
|
||||
return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
|
||||
- content: >-
|
||||
Persist every setting at once. The body mirrors the shape returned by
|
||||
/all. Invalid values (bad ports, missing cert pairs, etc.) are
|
||||
rejected before write.
|
||||
id: >-
|
||||
persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
|
||||
- content: >-
|
||||
Change the panel admin username and password. Requires the current
|
||||
credentials for verification. The session is refreshed with the new
|
||||
values on success.
|
||||
id: >-
|
||||
change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
||||
- content: >-
|
||||
Restart the entire 3x-ui process after a 3-second grace period. The
|
||||
connection drops immediately; the panel comes back online ~5-10
|
||||
seconds later.
|
||||
id: >-
|
||||
restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
||||
- content: >-
|
||||
Test SMTP connection with stage-by-stage reporting (connect, auth,
|
||||
send). Returns structured result with stage and message.
|
||||
id: >-
|
||||
test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
||||
- content: >-
|
||||
Test Telegram bot connection by sending a test message to the
|
||||
configured chat.
|
||||
id: >-
|
||||
test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
|
||||
- content: >-
|
||||
Return the built-in default Xray JSON config template that ships with
|
||||
this panel version.
|
||||
id: >-
|
||||
return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/all","method":"post"},{"path":"/panel/api/setting/defaultSettings","method":"post"},{"path":"/panel/api/setting/update","method":"post"},{"path":"/panel/api/setting/updateUser","method":"post"},{"path":"/panel/api/setting/restartPanel","method":"post"},{"path":"/panel/api/setting/testSmtp","method":"post"},{"path":"/panel/api/setting/testTgBot","method":"post"},{"path":"/panel/api/setting/getDefaultJsonConfig","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: سرور اشتراک
|
||||
description: >-
|
||||
یک سرور HTTP/HTTPS جداگانه که لینکهای اشتراک پراکسی (استاندارد، JSON و Clash)
|
||||
را به کلاینتها ارائه میدهد. این سرور روی پورت اختصاصی خودش (بهصورت پیشفرض
|
||||
10882) گوش میدهد و در بخش Settings ← Subscription پیکربندی میشود. مسیرها قابل
|
||||
پیکربندی هستند؛ مقادیر پیشفرض در ادامه نشان داده شدهاند. همهی نقاط پایانی
|
||||
اشتراک، هدرهای پاسخ را برای خواندن اطلاعات ترافیک/انقضا توسط برنامههای کلاینت
|
||||
تنظیم میکنند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
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.
|
||||
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
|
||||
- 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
|
||||
- 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.
|
||||
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
|
||||
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.
|
||||
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
|
||||
- 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
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: WebSocket
|
||||
description: >-
|
||||
دریافت بهروزرسانیهای وضعیت در لحظه از طریق WebSocket. تنها یکبار به
|
||||
<code>ws://<panel>/ws</code> متصل شوید تا بدون نیاز به polling، جریانی از
|
||||
پیامهای JSON دریافت کنید. به یک کوکی نشست احرازهویتشده نیاز دارد (احرازهویت با
|
||||
توکن Bearer پشتیبانی نمیشود). هر پیام دارای یک فیلد <code>type</code> است که
|
||||
شکل دادهی آن را مشخص میکند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
|
||||
session cookie (Bearer token auth is not supported here). Returns 101
|
||||
Switching Protocols on success. The server then pushes JSON messages
|
||||
described below.
|
||||
url: >-
|
||||
#upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
|
||||
session cookie (Bearer token auth is not supported here). Returns 101
|
||||
Switching Protocols on success. The server then pushes JSON messages
|
||||
described below.
|
||||
id: >-
|
||||
upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/ws","method":"get"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
---
|
||||
title: تنظیمات Xray
|
||||
description: >-
|
||||
قالب پیکربندی Xray، مدیریت outboundها، یکپارچهسازی Warp/Nord و آزمایش
|
||||
پیکربندی. همهی نقاط پایانی زیر /panel/api/xray قرار دارند.
|
||||
full: true
|
||||
_openapi:
|
||||
preload:
|
||||
- ./public/openapi.json
|
||||
toc:
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the Xray config template (JSON string), available inbound tags,
|
||||
client reverse tags, and the configured outbound test URL in one
|
||||
response.
|
||||
url: >-
|
||||
#return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the built-in default Xray config shipped with the panel
|
||||
(identical to /panel/api/setting/getDefaultJsonConfig).
|
||||
url: >-
|
||||
#return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return traffic statistics for every outbound. Each outbound shows
|
||||
up/down/total counters.
|
||||
url: >-
|
||||
#return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
|
||||
- depth: 2
|
||||
title: >-
|
||||
Return the most recent Xray process stdout/stderr output. Useful to
|
||||
check for startup errors or runtime warnings.
|
||||
url: >-
|
||||
#return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
|
||||
- depth: 2
|
||||
title: >-
|
||||
Save the Xray JSON config template and optionally the outbound test URL.
|
||||
Both are sent as form fields.
|
||||
url: >-
|
||||
#save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
|
||||
- depth: 2
|
||||
title: >-
|
||||
Manage Cloudflare Warp integration. The action parameter selects the
|
||||
operation.
|
||||
url: >-
|
||||
#manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
|
||||
- depth: 2
|
||||
title: Manage NordVPN integration. The action parameter selects the operation.
|
||||
url: '#manage-nordvpn-integration-the-action-parameter-selects-the-operation'
|
||||
- depth: 2
|
||||
title: Reset traffic counters for a specific outbound by tag.
|
||||
url: '#reset-traffic-counters-for-a-specific-outbound-by-tag'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test an outbound configuration. Sends the outbound JSON (required),
|
||||
optionally all outbounds (to resolve sockopt.dialerProxy dependencies),
|
||||
and a mode flag.
|
||||
url: >-
|
||||
#test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
|
||||
- depth: 2
|
||||
title: >-
|
||||
Test a batch of outbounds (max 50) through one shared temp xray
|
||||
instance. Returns an array of results in input order, each with the
|
||||
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
|
||||
breakdown.
|
||||
url: >-
|
||||
#test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
|
||||
- depth: 2
|
||||
title: >-
|
||||
Live state of routing balancers in the running core
|
||||
(RoutingService.GetBalancerInfo): current override and the targets the
|
||||
strategy prefers. Returns a map keyed by balancer tag.
|
||||
url: >-
|
||||
#live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
|
||||
- depth: 2
|
||||
title: >-
|
||||
Force a balancer in the running core to always pick one outbound
|
||||
(RoutingService.OverrideBalancerTarget). Applied live without a restart;
|
||||
cleared automatically when Xray restarts.
|
||||
url: >-
|
||||
#force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
|
||||
- depth: 2
|
||||
title: >-
|
||||
Ask the running core which outbound its router would pick for a
|
||||
synthetic connection (RoutingService.TestRoute). No traffic is sent.
|
||||
url: >-
|
||||
#ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
|
||||
- depth: 2
|
||||
title: >-
|
||||
List all outbound subscriptions (remote URLs that supply additional
|
||||
outbounds), newest first.
|
||||
url: >-
|
||||
#list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
|
||||
- depth: 2
|
||||
title: >-
|
||||
Create an outbound subscription. The URL is fetched, parsed into
|
||||
outbounds with stable tags, and merged additively into the running Xray
|
||||
config.
|
||||
url: >-
|
||||
#create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
|
||||
- depth: 2
|
||||
title: >-
|
||||
Update an existing outbound subscription by id. Accepts the same form
|
||||
fields as create.
|
||||
url: >-
|
||||
#update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
|
||||
- depth: 2
|
||||
title: Delete an outbound subscription by id.
|
||||
url: '#delete-an-outbound-subscription-by-id'
|
||||
- depth: 2
|
||||
title: >-
|
||||
Delete an outbound subscription by id (POST alias of DELETE for
|
||||
axios-friendly clients).
|
||||
url: >-
|
||||
#delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
|
||||
- depth: 2
|
||||
title: >-
|
||||
Force an immediate re-fetch of the subscription and return the parsed
|
||||
outbounds. Signals Xray to reload.
|
||||
url: >-
|
||||
#force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
|
||||
- depth: 2
|
||||
title: >-
|
||||
Reorder a subscription one step up or down in priority (controls its
|
||||
position in the merged outbounds).
|
||||
url: >-
|
||||
#reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
|
||||
- depth: 2
|
||||
title: >-
|
||||
Preview a subscription URL: fetch and parse it into outbounds without
|
||||
persisting anything.
|
||||
url: >-
|
||||
#preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
|
||||
structuredData:
|
||||
headings:
|
||||
- content: >-
|
||||
Return the Xray config template (JSON string), available inbound tags,
|
||||
client reverse tags, and the configured outbound test URL in one
|
||||
response.
|
||||
id: >-
|
||||
return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
|
||||
- content: >-
|
||||
Return the built-in default Xray config shipped with the panel
|
||||
(identical to /panel/api/setting/getDefaultJsonConfig).
|
||||
id: >-
|
||||
return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
|
||||
- content: >-
|
||||
Return traffic statistics for every outbound. Each outbound shows
|
||||
up/down/total counters.
|
||||
id: >-
|
||||
return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
|
||||
- content: >-
|
||||
Return the most recent Xray process stdout/stderr output. Useful to
|
||||
check for startup errors or runtime warnings.
|
||||
id: >-
|
||||
return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
|
||||
- content: >-
|
||||
Save the Xray JSON config template and optionally the outbound test
|
||||
URL. Both are sent as form fields.
|
||||
id: >-
|
||||
save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
|
||||
- content: >-
|
||||
Manage Cloudflare Warp integration. The action parameter selects the
|
||||
operation.
|
||||
id: >-
|
||||
manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
|
||||
- content: >-
|
||||
Manage NordVPN integration. The action parameter selects the
|
||||
operation.
|
||||
id: manage-nordvpn-integration-the-action-parameter-selects-the-operation
|
||||
- content: Reset traffic counters for a specific outbound by tag.
|
||||
id: reset-traffic-counters-for-a-specific-outbound-by-tag
|
||||
- content: >-
|
||||
Test an outbound configuration. Sends the outbound JSON (required),
|
||||
optionally all outbounds (to resolve sockopt.dialerProxy
|
||||
dependencies), and a mode flag.
|
||||
id: >-
|
||||
test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
|
||||
- content: >-
|
||||
Test a batch of outbounds (max 50) through one shared temp xray
|
||||
instance. Returns an array of results in input order, each with the
|
||||
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
|
||||
breakdown.
|
||||
id: >-
|
||||
test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
|
||||
- content: >-
|
||||
Live state of routing balancers in the running core
|
||||
(RoutingService.GetBalancerInfo): current override and the targets the
|
||||
strategy prefers. Returns a map keyed by balancer tag.
|
||||
id: >-
|
||||
live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
|
||||
- content: >-
|
||||
Force a balancer in the running core to always pick one outbound
|
||||
(RoutingService.OverrideBalancerTarget). Applied live without a
|
||||
restart; cleared automatically when Xray restarts.
|
||||
id: >-
|
||||
force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
|
||||
- content: >-
|
||||
Ask the running core which outbound its router would pick for a
|
||||
synthetic connection (RoutingService.TestRoute). No traffic is sent.
|
||||
id: >-
|
||||
ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
|
||||
- content: >-
|
||||
List all outbound subscriptions (remote URLs that supply additional
|
||||
outbounds), newest first.
|
||||
id: >-
|
||||
list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
|
||||
- content: >-
|
||||
Create an outbound subscription. The URL is fetched, parsed into
|
||||
outbounds with stable tags, and merged additively into the running
|
||||
Xray config.
|
||||
id: >-
|
||||
create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
|
||||
- content: >-
|
||||
Update an existing outbound subscription by id. Accepts the same form
|
||||
fields as create.
|
||||
id: >-
|
||||
update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
|
||||
- content: Delete an outbound subscription by id.
|
||||
id: delete-an-outbound-subscription-by-id
|
||||
- content: >-
|
||||
Delete an outbound subscription by id (POST alias of DELETE for
|
||||
axios-friendly clients).
|
||||
id: >-
|
||||
delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
|
||||
- content: >-
|
||||
Force an immediate re-fetch of the subscription and return the parsed
|
||||
outbounds. Signals Xray to reload.
|
||||
id: >-
|
||||
force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
|
||||
- content: >-
|
||||
Reorder a subscription one step up or down in priority (controls its
|
||||
position in the merged outbounds).
|
||||
id: >-
|
||||
reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
|
||||
- content: >-
|
||||
Preview a subscription URL: fetch and parse it into outbounds without
|
||||
persisting anything.
|
||||
id: >-
|
||||
preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
|
||||
contents: []
|
||||
---
|
||||
|
||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
||||
|
||||
export default function Layout(props) {
|
||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
||||
const Comp = OpenAPIPage ?? APIPage;
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/xray/","method":"post"},{"path":"/panel/api/xray/getDefaultJsonConfig","method":"get"},{"path":"/panel/api/xray/getOutboundsTraffic","method":"get"},{"path":"/panel/api/xray/getXrayResult","method":"get"},{"path":"/panel/api/xray/update","method":"post"},{"path":"/panel/api/xray/warp/{action}","method":"post"},{"path":"/panel/api/xray/nord/{action}","method":"post"},{"path":"/panel/api/xray/resetOutboundsTraffic","method":"post"},{"path":"/panel/api/xray/testOutbound","method":"post"},{"path":"/panel/api/xray/testOutbounds","method":"post"},{"path":"/panel/api/xray/balancerStatus","method":"post"},{"path":"/panel/api/xray/balancerOverride","method":"post"},{"path":"/panel/api/xray/routeTest","method":"post"},{"path":"/panel/api/xray/outbound-subs","method":"get"},{"path":"/panel/api/xray/outbound-subs","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"delete"},{"path":"/panel/api/xray/outbound-subs/{id}/del","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/refresh","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/move","method":"post"},{"path":"/panel/api/xray/outbound-subs/parse","method":"post"}]} showTitle />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: پایگاه داده
|
||||
description: بکاندهای ذخیرهسازی 3x-ui — SQLite (پیشفرض) و PostgreSQL — مسیر پایگاه داده، استخر اتصال و مهاجرت از SQLite به PostgreSQL.
|
||||
icon: Database
|
||||
---
|
||||
|
||||
3x-ui همه چیز را — inboundها، کلاینتها و تنظیمات — در یک پایگاه داده ذخیره میکند.
|
||||
بکاند را هنگام نصب انتخاب میکنید؛ هر دو کاملاً پشتیبانی میشوند.
|
||||
|
||||
## SQLite (پیشفرض)
|
||||
|
||||
یک فایل واحد در مسیر `/etc/x-ui/x-ui.db`. بدون نیاز به هیچ راهاندازی، ایدهآل برای
|
||||
استقرارهای کوچک و متوسط. این پوشه با
|
||||
[`XUI_DB_FOLDER`](/docs/reference/env-vars#database) قابل تنظیم است (در ویندوز بهطور
|
||||
پیشفرض کنار فایل اجرایی قرار میگیرد).
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
برای تعداد بالای کلاینتها یا راهاندازیهای چندنودی توصیه میشود. نصبکننده میتواند
|
||||
PostgreSQL را بهصورت محلی برای شما نصب کند، یا یک DSN به سروری موجود را بپذیرد. در زمان
|
||||
اجرا بکاند از طریق متغیرهای محیطی انتخاب میشود که نصبکننده آنها را در
|
||||
`/etc/default/x-ui` مینویسد:
|
||||
|
||||
```bash title="/etc/default/x-ui"
|
||||
XUI_DB_TYPE=postgres
|
||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||
```
|
||||
|
||||
استخر اتصال را با `XUI_DB_MAX_OPEN_CONNS` و
|
||||
`XUI_DB_MAX_IDLE_CONNS` تنظیم کنید.
|
||||
|
||||
### Docker
|
||||
|
||||
دستور `docker compose up -d` همچنان از SQLite استفاده میکند. برای اجرا با سرویس
|
||||
PostgreSQL همراه، دو خط `XUI_DB_*` را در `docker-compose.yml` از حالت کامنت خارج کنید و
|
||||
با این پروفایل اجرا کنید:
|
||||
|
||||
```bash
|
||||
docker compose --profile postgres up -d
|
||||
```
|
||||
|
||||
## مهاجرت از SQLite به PostgreSQL
|
||||
|
||||
یک نصب موجود SQLite را با دستور داخلی به PostgreSQL منتقل کنید:
|
||||
|
||||
```bash
|
||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||
```
|
||||
|
||||
سپس `XUI_DB_TYPE` و `XUI_DB_DSN` را در `/etc/default/x-ui` تنظیم کرده و سرویس را مجدداً
|
||||
راهاندازی کنید:
|
||||
|
||||
```bash
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
فایل مبدأ SQLite دستنخورده باقی میماند — آن را تنها پس از اینکه از کارکرد صحیح
|
||||
بکاند جدید مطمئن شدید، بهصورت دستی حذف کنید.
|
||||
</Callout>
|
||||
|
||||
## پشتیبانگیری
|
||||
|
||||
از هر بکاندی که استفاده میکنید، بهطور منظم از آن پشتیبان بگیرید — به
|
||||
[پشتیبانگیری و بازیابی](/docs/operations/backup-restore) مراجعه کنید.
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: متغیرهای محیطی
|
||||
description: مرجع کامل متغیرهای محیطی `XUI_*` در 3x-ui — پایگاهداده، پنل، لاگگیری، حافظه و پایشگر سلامت تونل.
|
||||
icon: Variable
|
||||
---
|
||||
|
||||
3x-ui پیکربندی زماناجرای خود را از متغیرهای محیطی `XUI_*` میخواند. در نصب
|
||||
اسکریپتی، نصبکننده آنها را در فایل محیطی سرویس مینویسد
|
||||
(`/etc/default/x-ui`، یا بسته به توزیع `/etc/conf.d/x-ui` / `/etc/sysconfig/x-ui`)؛
|
||||
برای Docker آنها را در `docker-compose.yml` یا `docker run -e` تنظیم میکنید.
|
||||
مقادیر پیشفرض منطقی هستند — فقط آنچه را که نیاز به تغییر دارید تنظیم کنید، سپس
|
||||
ریاستارت کنید: `systemctl restart x-ui`.
|
||||
|
||||
## پایگاهداده
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ----------- | -------------------------------------------------------------------- |
|
||||
| `XUI_DB_TYPE` | `sqlite` | بکاند: `sqlite`، یا `postgres` (همچنین `postgresql` / `pg` را میپذیرد). |
|
||||
| `XUI_DB_FOLDER` | `/etc/x-ui` | پوشهی فایل پایگاهدادهی SQLite (`x-ui.db`). |
|
||||
| `XUI_DB_DSN` | — | رشتهی اتصال PostgreSQL (وقتی `XUI_DB_TYPE=postgres` باشد استفاده میشود). |
|
||||
| `XUI_DB_MAX_OPEN_CONNS` | — | حداکثر اتصالات باز در استخر PostgreSQL. |
|
||||
| `XUI_DB_MAX_IDLE_CONNS` | — | حداکثر اتصالات بیکار در استخر PostgreSQL. |
|
||||
|
||||
مسیر پیشفرض پایگاهدادهی SQLite برابر `/etc/x-ui/x-ui.db` است. برای جزئیات
|
||||
SQLite ↔ PostgreSQL به [پایگاهداده](/docs/reference/database) مراجعه کنید.
|
||||
|
||||
## پنل
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ------- | ------------------------------------------------------------------------ |
|
||||
| `XUI_PORT` | — | بازنویسی پورت پنل (۱ تا ۶۵۵۳۵). بر تنظیم ذخیرهشده اولویت دارد. |
|
||||
| `XUI_INIT_WEB_BASE_PATH` | `/` | مسیر پایهی وب اولیه در **نخستین** اجرا (مثلاً `/panel`). |
|
||||
| `XUI_ENABLE_FAIL2BAN` | `true` | فعالسازی اعمالِ محدودیت IP مبتنی بر Fail2ban. |
|
||||
| `XUI_SKIP_HSTS` | `false` | رد کردن هدر HSTS — وقتی TLS توسط یک پروکسی معکوس خاتمه مییابد، `true` تنظیم کنید. |
|
||||
|
||||
## لاگگیری و باینریها
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ---------------- | ---------------- | ----------------------------------------------------------- |
|
||||
| `XUI_LOG_LEVEL` | `info` | `debug`، `info`، `notice`، `warning`، یا `error`. |
|
||||
| `XUI_DEBUG` | `false` | حالت دیباگ (سطح لاگ را به `debug` وادار میکند). |
|
||||
| `XUI_LOG_FOLDER` | `/var/log/x-ui` | پوشهی خروجی لاگ. |
|
||||
| `XUI_BIN_FOLDER` | `bin` | پوشهی باینری Xray-core و فایلهای geosite/geoip. |
|
||||
|
||||
## حافظه و پروفایلینگ
|
||||
|
||||
پنل با استفاده از `GOGC` و آزادسازیهای دورهای، مصرف حافظه را پایین نگه میدارد.
|
||||
اینها تنظیمات پیشرفتهای هستند — مگر اینکه در حال تنظیم دقیق یک میزبان با منابع
|
||||
محدود باشید، آنها را تنظیمنشده رها کنید.
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ----------------------------- | ------- | ----------------------------------------------------------------- |
|
||||
| `XUI_GOGC` | — | درصد هدف GC در Go؛ کمتر = RAM کمتر، CPU اندکی بیشتر. |
|
||||
| `XUI_MEMORY_RELEASE_INTERVAL` | — | فاصلهی زمانی فراخوانیهای `FreeOSMemory` بر حسب دقیقه؛ مقدار `0` آن را غیرفعال میکند. |
|
||||
| `XUI_MEMORY_LIMIT` | — | محدودیت نرم حافظهی Go بر حسب **MiB**. |
|
||||
| `GOMEMLIMIT` | — | محدودیت نرم با نحو Go (مثلاً `400MiB`)؛ بر مورد بالا اولویت دارد.|
|
||||
| `XUI_PPROF` | `false` | در دسترس قرار دادن پروفایلینگ pprof روی `127.0.0.1:6060`. |
|
||||
|
||||
## Xray
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ------- | --------------------- |
|
||||
| `XRAY_VMESS_AEAD_FORCED` | `false` | الزامیکردن VMess AEAD. |
|
||||
|
||||
## پایشگر سلامت تونل
|
||||
|
||||
نگهبان اختیاری: یک URL را پروب میکند (بهصورت اختیاری **از طریق** یک ورودی محلی
|
||||
Xray) و پس از خرابیهای مکرر، Xray را ریاستارت میکند. هر ریاستارت همهی
|
||||
کلاینتهای متصل را قطع میکند، پس آن را آگاهانه فعال کنید.
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ----------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `XUI_TUNNEL_HEALTH_MONITOR` | `false` | فعالسازی پایشگر. |
|
||||
| `XUI_TUNNEL_HEALTH_PROXY` | — | پروکسیای که پروب از طریق آن ارسال میشود، مثلاً `socks5://127.0.0.1:1080`. خالی = فقط اتصال میزبان را بررسی میکند. |
|
||||
| `XUI_TUNNEL_HEALTH_URL` | `https://www.cloudflare.com/cdn-cgi/trace` | URLی که پروب میشود. |
|
||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | `30s` | فاصلهی زمانی بین پروبها. |
|
||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | `10s` | مهلت زمانی هر پروب. |
|
||||
| `XUI_TUNNEL_HEALTH_FAILURES` | `3` | تعداد خرابیهای متوالی پیش از یک ریاستارت. |
|
||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | `5m` | حداقل تأخیر بین ریاستارتها. |
|
||||
|
||||
## نصب بدون نظارت
|
||||
|
||||
| Variable | Description |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `XUI_NONINTERACTIVE` | روی `1` تنظیم کنید (یا بدون TTY اجرا کنید) تا نصب بدون هیچ پرسشی انجام شود؛ اطلاعات احراز هویتِ تولیدشده در `/etc/x-ui/install-result.env` نوشته میشوند. نگاه کنید به [نصب](/docs/guide/installation#unattended--cloud-init). |
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "مرجع",
|
||||
"icon": "BookMarked",
|
||||
"pages": ["env-vars", "database", "ports-firewall", "api"]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: پورتها و فایروال
|
||||
description: پورتهایی که 3x-ui بهصورت پیشفرض استفاده میکند و قواعد آماده ufw / nftables برای باز کردن آنها.
|
||||
icon: Network
|
||||
---
|
||||
|
||||
فقط پورتهایی را باز کنید که واقعاً استفاده میکنید. در ادامه پورتهای رایج و یک
|
||||
سازنده برای قواعد `ufw` و `nftables` آمده است.
|
||||
|
||||
## پورتهای رایج
|
||||
|
||||
| Port (default) | Purpose |
|
||||
| -------------- | ----------------------------------------- |
|
||||
| `22` | SSH (این را باز نگه دارید!). |
|
||||
| `2053` | پنل (قابل پیکربندی). |
|
||||
| `2096` | سرور اشتراک (اگر جداگانه باشد). |
|
||||
| `443` | یک پورت ورودی رایج (TLS / REALITY). |
|
||||
| `80` / `443` | پراکسی معکوس (اگر از آن استفاده کنید). |
|
||||
|
||||
پورتهای ورودی واقعی شما به inboundهایی بستگی دارد که میسازید.
|
||||
|
||||
## ساخت قواعد فایروال
|
||||
|
||||
<FirewallRulesGenerator />
|
||||
|
||||
<Callout type="warn">
|
||||
همیشه پیش از فعالسازی سیاست رد پیشفرض (default-deny)، اجازه SSH را باز نگه
|
||||
دارید و از یک نشست دوم آزمایش کنید تا خودتان را پشت در نگذارید.
|
||||
</Callout>
|
||||
|
||||
## مرتبط
|
||||
|
||||
<Cards>
|
||||
<Card title="امنیت" href="/docs/operations/security" description="Fail2ban، محدودیتهای IP و سختسازی." />
|
||||
<Card title="متغیرهای محیطی" href="/docs/reference/env-vars" description="XUI_PORT و موارد مشابه." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Клиенты
|
||||
description: Управление клиентами 3x-ui — учётные данные, лимиты трафика и срока действия, ограничения по IP, группы, массовые операции, внешние ссылки и статус онлайн.
|
||||
icon: Users
|
||||
---
|
||||
|
||||
**Клиент** — это отдельный пользователь, идентифицируемый по уникальному
|
||||
**email**. В текущей версии панели клиенты являются полноценными записями,
|
||||
которые можно одновременно привязать к **нескольким входящим подключениям**
|
||||
(inbounds), с учётом трафика по каждому клиенту.
|
||||
|
||||
## Поля клиента
|
||||
|
||||
| Поле | Применяется к | Значение |
|
||||
| -------------- | --------------------- | ------------------------------------------------------------------ |
|
||||
| **Email** | все | Уникальный идентификатор для учёта трафика и поиска. |
|
||||
| **ID (UUID)** | VLESS, VMess | Учётные данные клиента. |
|
||||
| **Password** | Trojan, Shadowsocks | Учётные данные клиента. |
|
||||
| **Auth** | Hysteria2 | Учётные данные клиента. |
|
||||
| **Flow** | VLESS | Поток XTLS, например `xtls-rprx-vision`. |
|
||||
| **Limit IP** | все | Максимум одновременных IP-адресов источника (контролируется через Fail2ban). |
|
||||
| **Total (GB)** | все | Квота трафика; при исчерпании клиент отключается. |
|
||||
| **Expiry** | все | Дата, после которой клиент перестаёт работать. |
|
||||
| **Reset** | все | Период автопродления в **днях** (обнуляет квоту). |
|
||||
| **Telegram ID**| все | Привязывает клиента к пользователю Telegram для самообслуживания/уведомлений.|
|
||||
| **Sub ID** | все | Идентификатор подписки, группирующий ссылки этого клиента. |
|
||||
| **Group** | все | Необязательная группа клиента для организации и массовой фильтрации.|
|
||||
| **Comment** | все | Произвольная текстовая заметка. |
|
||||
|
||||
<Callout type="info">
|
||||
Достижение лимита **трафика** или **срока действия** отключает клиента; при
|
||||
автоматическом отключении клиентов панель может автоматически перезапускать
|
||||
Xray (`restartXrayOnClientDisable`, включено по умолчанию).
|
||||
</Callout>
|
||||
|
||||
## Лимиты и контроль IP
|
||||
|
||||
- Ограничения по **трафику / сроку действия** отключают клиента при достижении;
|
||||
период **Reset** автоматически обновляет квоту.
|
||||
- **Limit IP** ограничивает количество одновременных IP-адресов источника.
|
||||
Контроль осуществляется с помощью Fail2ban — см.
|
||||
[Безопасность](/docs/operations/security). Вы можете просмотреть недавние
|
||||
IP-адреса клиента и очистить их из действий клиента.
|
||||
- **Статус онлайн** и время **последнего входа** отслеживаются по каждому
|
||||
клиенту (и по каждому узлу в конфигурациях с несколькими узлами).
|
||||
|
||||
## Ссылки для общего доступа и внешние ссылки
|
||||
|
||||
У каждого клиента есть ссылки для общего доступа и QR-код для его входящих
|
||||
подключений, а также объединённая [подписка](/docs/config/subscription). К
|
||||
клиенту также можно привязать **внешние ссылки** — дополнительные ссылки
|
||||
`vless://`, `vmess://`, `trojan://`, `ss://`, `hysteria2://` или
|
||||
`wireguard://`, либо удалённый URL подписки, — чтобы они отображались рядом со
|
||||
сгенерированными панелью в подписке клиента.
|
||||
|
||||
Чтобы точно узнать, что содержит ссылка, вставьте её в
|
||||
[инспектор ссылок для общего доступа](/docs/config/share-links).
|
||||
|
||||
## Массовые операции
|
||||
|
||||
Для управления множеством клиентов одновременно панель поддерживает массовые
|
||||
операции **создания, включения, отключения, удаления, привязки/отвязки** (к
|
||||
входящим подключениям), **сброса трафика** и **корректировки** (добавить дни /
|
||||
добавить байты / задать flow). Операции обслуживания также позволяют удалять
|
||||
**исчерпанных** клиентов (исчерпана квота/срок действия) и **осиротевших**
|
||||
клиентов (не привязанных ни к одному входящему подключению).
|
||||
|
||||
<Callout type="warn">
|
||||
Ссылка клиента для общего доступа содержит его учётные данные. Относитесь к
|
||||
ссылкам и QR-кодам как к паролям и меняйте учётные данные, если что-то из
|
||||
этого утекло.
|
||||
</Callout>
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Входящие подключения и протоколы
|
||||
description: Создание входящих подключений в 3x-ui — протоколы, транспорты, сброс трафика и срок действия, а также fallback-правила, обслуживающие несколько протоколов на одном порту.
|
||||
icon: ArrowDownToLine
|
||||
---
|
||||
|
||||
**Входящее подключение** (inbound) — это слушатель, который принимает клиентские
|
||||
соединения на порту, используя определённый протокол и транспорт. Большая часть
|
||||
повседневной работы состоит в создании и управлении входящими подключениями и
|
||||
клиентами внутри них.
|
||||
|
||||
## Создание входящего подключения
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Добавьте входящее подключение
|
||||
|
||||
Откройте **Inbounds → Add**, задайте примечание, выберите **протокол**, а также
|
||||
**порт** и адрес прослушивания.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Выберите транспорт и безопасность
|
||||
|
||||
Выберите транспорт (TCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, …) и уровень
|
||||
безопасности (без шифрования, TLS или REALITY). См. [Транспорты](/docs/config/transports) и
|
||||
[REALITY](/docs/config/reality).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Добавьте клиентов
|
||||
|
||||
Добавьте одного или нескольких клиентов, у каждого со своими учётными данными,
|
||||
ограничениями и ссылкой для подключения. См. [Клиенты](/docs/config/clients).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Задайте лимит трафика, срок действия и сброс
|
||||
|
||||
При необходимости ограничьте общий объём трафика и установите дату истечения для
|
||||
входящего подключения, а также выберите расписание периодического **сброса трафика**:
|
||||
`never` (по умолчанию), `hourly`, `daily`, `weekly` или `monthly`.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Поддерживаемые протоколы
|
||||
|
||||
Редактор входящих подключений принимает следующие протоколы:
|
||||
|
||||
| Протокол | Примечания |
|
||||
| ---------------------- | ------------------------------------------------------------------------ |
|
||||
| **VLESS** | Лёгкий; основа для REALITY + XTLS-Vision. Рекомендуется. |
|
||||
| **VMess** | Более старый, но очень широко поддерживается клиентами. |
|
||||
| **Trojan** | На основе TLS; поддерживает XTLS и fallback-правила. |
|
||||
| **Shadowsocks** | Включает шифры Shadowsocks-2022 (`2022-blake3-*`). |
|
||||
| **WireGuard** | Современный туннель. |
|
||||
| **Hysteria2** | Выбирается как `hysteria`; панель создаёт ссылки `hysteria2://`. |
|
||||
| **HTTP** | HTTP-прокси. |
|
||||
| **Mixed (SOCKS/HTTP)** | Совмещённый слушатель SOCKS + HTTP. |
|
||||
| **Dokodemo-door / Tunnel** | Перенаправление портов / перенаправление трафика. |
|
||||
| **MTProto** | Прокси Telegram MTProto, обслуживаемый встроенным процессом `mtg` (не Xray). |
|
||||
|
||||
<Callout type="info">
|
||||
Hysteria2 внутренне не является отдельным протоколом — это протокол `hysteria`
|
||||
с версией транспорта, установленной в 2, и панель генерирует для него ссылки
|
||||
`hysteria2://` для подключения.
|
||||
</Callout>
|
||||
|
||||
## Fallback-правила — несколько протоколов на одном порту
|
||||
|
||||
Fallback-правила позволяют одному TLS-порту (например, `443`) обслуживать более
|
||||
одного протокола — например, VLESS **и** Trojan — направляя несовпавшие
|
||||
рукопожатия на дочернее входящее подключение. В 3x-ui fallback-правила
|
||||
управляются в панели (список **Fallbacks** у главного входящего подключения), а
|
||||
не прописываются вручную в JSON.
|
||||
|
||||
Fallback-правила доступны только тогда, когда главное входящее подключение:
|
||||
|
||||
- использует **VLESS** или **Trojan**,
|
||||
- работает на «сыром» транспорте **TCP**,
|
||||
- с безопасностью **TLS** или **REALITY**.
|
||||
|
||||
Каждое fallback-правило указывает на дочернее входящее подключение и может
|
||||
сопоставляться по `path`, `alpn` и `dest`. Клиентские ссылки для дочернего
|
||||
fallback-подключения автоматически переписываются так, чтобы указывать адрес,
|
||||
порт и TLS главного подключения.
|
||||
|
||||
## Не уверены, что выбрать?
|
||||
|
||||
Воспользуйтесь мастером, чтобы получить рекомендацию исходя из ваших целей и клиентов:
|
||||
|
||||
<ProtocolWizard />
|
||||
|
||||
<Callout type="info">
|
||||
Для устойчивости к цензуре с современными клиентами **VLESS + REALITY +
|
||||
XTLS-Vision** обычно является лучшим выбором — перейдите к
|
||||
[REALITY](/docs/config/reality).
|
||||
</Callout>
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "Конфигурация",
|
||||
"icon": "Settings",
|
||||
"pages": [
|
||||
"panel",
|
||||
"ssl-certificates",
|
||||
"inbounds",
|
||||
"reality",
|
||||
"transports",
|
||||
"clients",
|
||||
"subscription",
|
||||
"share-links"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Настройки панели
|
||||
description: Все настройки панели 3x-ui — веб-сервер, TLS, отображение, безопасность и уведомления — со значениями по умолчанию из исходного кода.
|
||||
icon: SlidersHorizontal
|
||||
---
|
||||
|
||||
**Настройки панели** определяют, как сама панель обслуживается и защищается
|
||||
(отдельно от ваших входящих подключений и клиентов). Настройки хранятся в виде
|
||||
пар ключ/значение; приведённые ниже значения по умолчанию взяты напрямую из
|
||||
исходного кода панели. Секреты (токены, пароли) отображаются только как индикатор
|
||||
«задано / не задано» и никогда не передаются в браузер целиком.
|
||||
|
||||
## Веб-сервер
|
||||
|
||||
| Настройка | По умолчанию | Значение |
|
||||
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
||||
| `webPort` | `2053` | Порт панели (1–65535). Переменная окружения `XUI_PORT` переопределяет его во время выполнения. |
|
||||
| `webListen` | _(все интерфейсы)_ | Привязка панели к конкретному IP. |
|
||||
| `webBasePath` | `/` | URL-путь, по которому обслуживается панель (всегда нормализуется к `/…/`). |
|
||||
| `webCertFile` / `webKeyFile` | _(нет)_ | Сертификат TLS + ключ. Когда заданы оба, панель обслуживается по **HTTPS**. |
|
||||
| `sessionMaxAge` | `360` | Время жизни сессии в **минутах** (по умолчанию 6 часов). |
|
||||
| `trustedProxyCIDRs` | `127.0.0.1/32,::1/128` | IP-адреса/CIDR, чьим переадресованным заголовкам (реальный IP клиента) можно доверять. |
|
||||
| `panelOutbound` | _(нет)_ | Маршрутизация собственного исходящего трафика панели (проверка обновлений, Telegram, запросы geo/подписок) через именованный исходящий канал Xray. |
|
||||
|
||||
После изменения порта или базового пути URL панели становится
|
||||
`http(s)://<server>:<port><web-base-path>`. Вы можете заранее задать базовый путь
|
||||
при первом запуске с помощью [`XUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars).
|
||||
|
||||
### TLS
|
||||
|
||||
Обслуживание панели по HTTPS защищает ваши учётные данные при передаче. Либо
|
||||
задайте `webCertFile` + `webKeyFile` — [меню SSL в `x-ui`](/docs/config/ssl-certificates)
|
||||
может получить для вас сертификат Let's Encrypt — либо завершайте TLS на
|
||||
[обратном прокси](/docs/operations/reverse-proxy).
|
||||
|
||||
<Callout type="warn">
|
||||
Никогда не выставляйте панель по обычному HTTP в публичный интернет. Используйте
|
||||
TLS, нестандартный порт и длинный случайный базовый путь.
|
||||
</Callout>
|
||||
|
||||
## Отображение
|
||||
|
||||
| Настройка | По умолчанию | Значение |
|
||||
| ---------------- | ------------------------------------------------ | ------------------------------------------------------------- |
|
||||
| `pageSize` | `25` | Строк на странице в списках (`0` отключает разбивку на страницы). |
|
||||
| `expireDiff` | `0` | За сколько дней до истечения срока начинать предупреждать. |
|
||||
| `trafficDiff` | `0` | Процент оставшейся квоты, при котором начинать предупреждать. |
|
||||
| `remarkTemplate` | `{{INBOUND}}-{{EMAIL}}\|📊{{TRAFFIC_LEFT}}\|⏳{{DAYS_LEFT}}D` | Шаблон примечания клиента по умолчанию (см. [Ссылки для обмена](/docs/config/share-links#remark-template-variables)). |
|
||||
| `timeLocation` | `Local` | Часовой пояс для статистики и сроков истечения. |
|
||||
| `datepicker` | `gregorian` | Календарь для ввода дат (григорианский или джалали/персидский). |
|
||||
|
||||
## Безопасность и аутентификация
|
||||
|
||||
Учётные данные, двухфакторная аутентификация, ограничитель перебора паролей,
|
||||
сессии и LDAP описаны в разделах [Первый вход](/docs/guide/first-login) и
|
||||
[Безопасность](/docs/operations/security). Вкратце:
|
||||
|
||||
- Пароли хранятся в виде хешей **bcrypt**; их изменение завершает все сессии.
|
||||
- При входе может требоваться **2FA (TOTP)**.
|
||||
- Резервный механизм **LDAP** может аутентифицировать пользователей, когда локальная проверка пароля не проходит.
|
||||
- Доступ к API использует **токены API**, управляемые в разделе «Настройки панели» (см.
|
||||
[справочник по API](/docs/reference/api/api-tokens)).
|
||||
|
||||
## Уведомления и подписка
|
||||
|
||||
У них есть собственные группы настроек и страницы:
|
||||
|
||||
<Cards>
|
||||
<Card title="Бот Telegram" href="/docs/operations/telegram-bot" description="Токен, идентификаторы чатов, оповещения и отчёты." />
|
||||
<Card title="Подписка" href="/docs/config/subscription" description="Сервер подписок, форматы и пути." />
|
||||
<Card title="Безопасность" href="/docs/operations/security" description="2FA, ограничения по IP и усиление защиты." />
|
||||
</Cards>
|
||||
|
||||
<Callout type="info">
|
||||
Уведомления по электронной почте (SMTP) также настраиваются (хост, порт,
|
||||
шифрование, получатели) с теми же типами событий, что и у бота Telegram.
|
||||
</Callout>
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: REALITY
|
||||
description: Настройка входящего подключения VLESS + REALITY с XTLS-Vision в 3x-ui — ключи, short ID, SNI, отпечатки и типичные ошибки.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
**REALITY** — это механизм безопасности транспорта Xray, маскирующий ваш прокси
|
||||
под обычный трафик к реальному популярному сайту. В отличие от классического TLS,
|
||||
вашему серверу **не нужен собственный сертификат** — он заимствует TLS-рукопожатие
|
||||
целевого сайта (`dest`). В сочетании с потоком **XTLS-Vision** это работает быстро
|
||||
и устойчиво к глубокому анализу пакетов.
|
||||
|
||||
REALITY используется с **VLESS** (а также Trojan). Рекомендуемый поток —
|
||||
`xtls-rprx-vision`.
|
||||
|
||||
## Ключевые настройки
|
||||
|
||||
Когда вы выбираете **REALITY** в качестве режима безопасности для входящего
|
||||
подключения VLESS, 3x-ui отображает следующие поля:
|
||||
|
||||
| Поле | Что это такое |
|
||||
| ------------------------ | ------------------------------------------------------------------ |
|
||||
| **Dest (цель)** | Реальный TLS-сайт для имитации, например `www.microsoft.com:443`. |
|
||||
| **SNI / Server Names** | Имя(имена) хоста, которые отправляют клиенты; должны совпадать с сертификатом цели. |
|
||||
| **Public / Private key** | Пара ключей **x25519**. Приватный ключ остаётся на сервере. |
|
||||
| **Short IDs** | Шестнадцатеричные строки для аутентификации клиентов (их может быть несколько). |
|
||||
| **Flow** | Установите в `xtls-rprx-vision`. |
|
||||
| **Fingerprint (uTLS)** | TLS-отпечаток клиента для имитации, например `chrome`. |
|
||||
|
||||
Приватный ключ генерируется утилитой `x25519` из состава Xray (панель может
|
||||
сгенерировать пару за вас):
|
||||
|
||||
```bash title="generate an x25519 keypair"
|
||||
xray x25519
|
||||
```
|
||||
|
||||
## Настройка в панели
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Создайте входящее подключение VLESS
|
||||
|
||||
Добавьте новое входящее подключение, выберите протокол **VLESS** и установите
|
||||
**Security** в **reality**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Выберите цель (dest) и SNI
|
||||
|
||||
Выберите авторитетный сайт, поддерживающий TLS 1.3 и HTTP/2 и доступный как с
|
||||
вашего сервера, так и с устройств клиентов (например `www.microsoft.com:443`).
|
||||
Задайте server names / SNI так, чтобы они совпадали с сертификатом этого сайта.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Сгенерируйте ключи и short ID
|
||||
|
||||
Сгенерируйте пару ключей x25519 и один или несколько short ID. Держите
|
||||
**приватный ключ** в секрете; клиенты получают только **публичный ключ**.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Задайте поток и отпечаток
|
||||
|
||||
Используйте поток `xtls-rprx-vision` и распространённый отпечаток uTLS, например
|
||||
`chrome`.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Добавьте клиента и поделитесь ссылкой
|
||||
|
||||
Создайте клиента, затем используйте его ссылку для подключения или QR-код в
|
||||
совместимом приложении (v2rayNG, Hiddify, Mihomo и других).
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Как выглядит конфигурация
|
||||
|
||||
На сервере секция `streamSettings` входящего подключения REALITY выглядит
|
||||
примерно так:
|
||||
|
||||
```json title="server inbound (excerpt)"
|
||||
{
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "www.microsoft.com:443",
|
||||
"serverNames": ["www.microsoft.com"],
|
||||
"privateKey": "<x25519 private key>",
|
||||
"shortIds": ["<hex short id>"],
|
||||
"fingerprint": "chrome"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Соответствующая клиентская ссылка для подключения содержит **публичные**
|
||||
параметры:
|
||||
|
||||
```text title="vless:// (excerpt)"
|
||||
vless://<uuid>@<server>:443?security=reality&pbk=<public-key>&sid=<short-id>&sni=www.microsoft.com&fp=chrome&spx=%2F&flow=xtls-rprx-vision#my-reality
|
||||
```
|
||||
|
||||
- `pbk` — **публичный** ключ REALITY
|
||||
- `sid` — short ID (совпадает с одним из заданных на сервере)
|
||||
- `sni` — server name (совпадает с сертификатом цели)
|
||||
- `fp` — отпечаток клиента
|
||||
- `spx` — путь spiderX
|
||||
- `flow` — `xtls-rprx-vision`
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
<Callout type="warn">
|
||||
|
||||
- **Неподходящая цель.** Значение `dest` должно указывать на реальный сайт,
|
||||
который поддерживает **TLS 1.3** и **HTTP/2**, доступен и не заблокирован в
|
||||
вашем регионе. Выбирайте сайт, который вам не принадлежит и на который идёт
|
||||
большой трафик.
|
||||
- **Несовпадение SNI.** Значения SNI / server names должны совпадать с реальным
|
||||
сертификатом цели, иначе рукопожатие выдаст маскировку.
|
||||
- **Утечка приватного ключа.** Клиентам всегда передавайте только **публичный**
|
||||
ключ.
|
||||
- **Неправильный поток.** Для REALITY + XTLS-Vision нужен `flow = xtls-rprx-vision`
|
||||
как в записи клиента входящего подключения, так и в ссылке для подключения.
|
||||
|
||||
</Callout>
|
||||
|
||||
## Сгенерируйте конфигурацию
|
||||
|
||||
Используйте генератор ниже, чтобы создать новую пару ключей X25519, UUID и short
|
||||
ID, а затем скопируйте JSON входящего подключения сервера и клиентскую ссылку для
|
||||
подключения. Все вычисления выполняются **в вашем браузере** — никакие ключи и
|
||||
ссылки никуда не отправляются.
|
||||
|
||||
<RealityConfigGenerator />
|
||||
|
||||
<Callout type="info">
|
||||
**Приватный ключ** должен оставаться только на вашем сервере. Делитесь с
|
||||
клиентами сгенерированной ссылкой `vless://` (которая содержит **публичный**
|
||||
ключ).
|
||||
</Callout>
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Ссылки для обмена
|
||||
description: Форматы ссылок для обмена в 3x-ui (vless, vmess, trojan, ss, hysteria2, mtproto), переменные шаблона примечания и инспектор ссылок в браузере.
|
||||
icon: Link
|
||||
---
|
||||
|
||||
3x-ui генерирует **ссылку для обмена** (и QR-код) для каждого клиента. Клиентские приложения,
|
||||
такие как v2rayNG, Hiddify и Mihomo, импортируют эти ссылки для собственной настройки.
|
||||
|
||||
## Форматы ссылок
|
||||
|
||||
| Схема | Структура |
|
||||
| -------------- | --------------------------------------------------------------- |
|
||||
| `vless://` | `vless://<uuid>@<host>:<port>?<params>#<remark>` |
|
||||
| `vmess://` | `vmess://<base64-json>` (JSON-объект в кодировке base64) |
|
||||
| `trojan://` | `trojan://<password>@<host>:<port>?<params>#<remark>` |
|
||||
| `ss://` | `ss://<userinfo>@<host>:<port>?<params>#<remark>` (SIP002; Shadowsocks-2022 использует userinfo с процентным кодированием) |
|
||||
| `hysteria2://` | `hysteria2://<auth>@<host>:<port>?<params>#<remark>` |
|
||||
| `tg://proxy` | `tg://proxy?server=…&port=…&secret=…` (MTProto) |
|
||||
|
||||
Параметры запроса несут настройки транспорта и безопасности — `security`,
|
||||
`sni`, `fp`, `pbk`, `sid`, `spx`, `flow`, `type`, `path`, `host`, `alpn` и
|
||||
другие.
|
||||
|
||||
## Разбор ссылки
|
||||
|
||||
Вставьте любую ссылку для обмена, чтобы декодировать каждое поле. Разбор происходит **целиком в вашем
|
||||
браузере** — ссылка никогда не отправляется по сети.
|
||||
|
||||
<ShareLinkInspector />
|
||||
|
||||
<Callout type="warn">
|
||||
Ссылки для обмена содержат всё необходимое для подключения в качестве клиента, включая
|
||||
учётные данные клиента. Относитесь к ним как к паролям.
|
||||
</Callout>
|
||||
|
||||
## Переменные шаблона примечания
|
||||
|
||||
Текст после `#` в каждой ссылке (**примечание**) генерируется из шаблона,
|
||||
которым вы управляете в настройках панели (`remarkTemplate`). По умолчанию используется:
|
||||
|
||||
```text
|
||||
{{INBOUND}}-{{EMAIL}}|📊{{TRAFFIC_LEFT}}|⏳{{DAYS_LEFT}}D
|
||||
```
|
||||
|
||||
Токены используют синтаксис `{{UPPER_CASE}}`. Шаблон разбивается на сегменты по `|`;
|
||||
сегмент, единственным значением которого является маркер безлимита `∞` (для `TRAFFIC_LEFT`,
|
||||
`TRAFFIC_TOTAL`, `DAYS_LEFT` или `TIME_LEFT`), отбрасывается, чтобы у клиентов с безлимитом
|
||||
не отображались пустые украшения.
|
||||
|
||||
### Доступные токены
|
||||
|
||||
| Токен | Значение |
|
||||
| ----- | ----- |
|
||||
| `{{EMAIL}}` / `{{USERNAME}}` | Email клиента (идентификатор) |
|
||||
| `{{INBOUND}}` | Примечание входящего соединения |
|
||||
| `{{HOST}}` | Примечание строки хоста (управляемые хосты) |
|
||||
| `{{ID}}` / `{{SHORT_ID}}` | UUID клиента / его первые 8 символов |
|
||||
| `{{TELEGRAM_ID}}` · `{{SUB_ID}}` · `{{COMMENT}}` | Telegram ID, ID подписки, комментарий |
|
||||
| `{{STATUS}}` / `{{STATUS_EMOJI}}` | `active`/`expired`/`depleted`/`disabled` (или ✅⏳🚫) |
|
||||
| `{{DAYS_LEFT}}` / `{{TIME_LEFT}}` | Осталось дней или `Xd Xh Xm` (`∞`, если безлимит) |
|
||||
| `{{EXPIRE_DATE}}` / `{{JALALI_EXPIRE_DATE}}` / `{{EXPIRE_UNIX}}` | Срок действия в григорианской / джалали дате / секундах Unix |
|
||||
| `{{CREATED_UNIX}}` | Время создания (секунды Unix) |
|
||||
| `{{TRAFFIC_USED}}` / `{{TRAFFIC_LEFT}}` / `{{TRAFFIC_TOTAL}}` | Использование в читаемом виде (`∞`, если безлимит) |
|
||||
| `{{TRAFFIC_USED_BYTES}}` / `{{TRAFFIC_LEFT_BYTES}}` / `{{TRAFFIC_TOTAL_BYTES}}` | То же, в байтах |
|
||||
| `{{UP}}` / `{{DOWN}}` | Отправлено / получено (в читаемом виде) |
|
||||
| `{{RESET_DAYS}}` · `{{USAGE_PERCENTAGE}}` | Период сброса (дни) · использованный процент |
|
||||
| `{{PROTOCOL}}` / `{{TRANSPORT}}` / `{{SECURITY}}` | например `VLESS` / `ws` / `REALITY` |
|
||||
|
||||
<Callout type="info">
|
||||
Токены использования (трафик, дни, статус) появляются в **теле** подписки, но
|
||||
удаляются из отображения/QR-вида, поэтому общий QR-код не раскрывает оставшуюся
|
||||
квоту клиента. Токены дат следуют настройке `datepicker` (григорианский или
|
||||
джалали календарь).
|
||||
</Callout>
|
||||
|
||||
## Связанные материалы
|
||||
|
||||
<Cards>
|
||||
<Card title="REALITY" href="/docs/config/reality" description="Сгенерируйте конфигурацию и ссылку VLESS + REALITY." />
|
||||
<Card title="Подписка" href="/docs/config/subscription" description="Отдавайте все ссылки клиента с одного URL." />
|
||||
</Cards>
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
title: SSL-сертификаты
|
||||
description: Получение и продление TLS-сертификатов для панели и входящих подключений 3x-ui — через меню ACME в x-ui (домен или голый IP), wildcard через Cloudflare DNS-01 или вручную с помощью Certbot.
|
||||
icon: ShieldCheck
|
||||
---
|
||||
|
||||
TLS-сертификат позволяет обслуживать **панель** по HTTPS (чтобы трафик входа и API
|
||||
был зашифрован) и терминировать TLS на **входящих подключениях** (VLESS-TLS, Trojan,
|
||||
Shadowsocks-TLS и им подобных). Получить его можно тремя способами:
|
||||
|
||||
- **Меню `x-ui`** — встроенный [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment)-клиент.
|
||||
Проще всего для одного домена или голого IP.
|
||||
- **Cloudflare DNS-01** — тоже из меню; нужен для **wildcard**-сертификатов или
|
||||
когда порт 80 заблокирован / сервер находится за прокси Cloudflare.
|
||||
- **Вручную через Certbot** — если вы предпочитаете управлять `acme.sh`/Certbot самостоятельно.
|
||||
|
||||
<Callout type="info">
|
||||
Если вы размещаете панель за Nginx или Caddy, доверьте управление
|
||||
сертификатом прокси-серверу — см. [Обратный прокси](/docs/operations/reverse-proxy).
|
||||
Входящим подключениям [REALITY](/docs/config/reality) сертификат **не нужен вовсе**; они
|
||||
заимствуют TLS реального сайта. Эта страница — про панель и про классические TLS-входящие
|
||||
подключения.
|
||||
</Callout>
|
||||
|
||||
## Меню SSL в `x-ui` (Let's Encrypt)
|
||||
|
||||
Запустите `x-ui` и выберите **`20` — SSL Certificate Management**. Оно управляет
|
||||
[acme.sh](https://github.com/acmesh-official/acme.sh) и предлагает:
|
||||
|
||||
| Опция | Что делает |
|
||||
| ------------------------------ | ------------------------------------------------------------------- |
|
||||
| Get SSL (Domain) | Выпустить сертификат для домена через HTTP-проверку. |
|
||||
| Get SSL for IP Address | Выпустить короткоживущий (6-дневный, автопродление) сертификат для **голого IP**. |
|
||||
| Revoke | Отозвать существующий сертификат. |
|
||||
| Force Renew | Продлить сейчас, до истечения срока. |
|
||||
| Show Existing Domains | Перечислить сертификаты, уже имеющиеся на сервере. |
|
||||
| Set Cert paths for the panel | Указать панели путь к выпущенному сертификату (заполняет поля за вас). |
|
||||
|
||||
### Выпуск сертификата для домена
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Направьте домен на сервер
|
||||
|
||||
Создайте запись `A` (и/или `AAAA`) для вашего домена, которая указывает на
|
||||
публичный IP этого сервера. Проверка не пройдёт, пока DNS не распространится.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Освободите порт 80
|
||||
|
||||
HTTP-проверке нужен **порт 80**, доступный из интернета и ещё не занятый. На время
|
||||
проверки остановите всё, что к нему привязано, и откройте его в
|
||||
[файрволе](/docs/reference/ports-firewall).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Запустите выпуск
|
||||
|
||||
`x-ui` → `20` → **Get SSL (Domain)**, затем введите домен. acme.sh запрашивает
|
||||
сертификат и сохраняет его в каталоге `/root/cert/<domain>/` как `fullchain.pem`
|
||||
(цепочка сертификатов) и `privkey.pem` (приватный ключ).
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Подключите его к панели
|
||||
|
||||
Выберите **Set Cert paths for the panel**, чтобы заполнить `webCertFile` и
|
||||
`webKeyFile` и перезапустить панель, либо задайте их сами в разделе
|
||||
[Настройки панели](/docs/config/panel#tls). Панель начинает обслуживать HTTPS, как только
|
||||
заданы оба значения.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
### Выпуск сертификата для голого IP
|
||||
|
||||
Нет домена? Выберите **Get SSL for IP Address**, чтобы получить короткоживущий
|
||||
сертификат (действует ~6 дней, продлевается автоматически), привязанный к IP сервера.
|
||||
Полезно для доступа к панели по HTTPS до того, как вы настроите домен.
|
||||
|
||||
## Cloudflare (wildcard через DNS-01)
|
||||
|
||||
DNS-проверка подтверждает, что вы управляете доменом, путём создания TXT-записи вместо
|
||||
ответа на порту 80 — поэтому она работает **за прокси Cloudflare**, на серверах,
|
||||
где порт 80 заблокирован, и для **wildcard**-сертификатов (`*.example.com`).
|
||||
|
||||
DNS вашего домена должен управляться Cloudflare, и вам понадобится одно из:
|
||||
|
||||
- **ограниченный по области API-токен** с правом `Zone:DNS:Edit` (рекомендуется), либо
|
||||
- **email вашей учётной записи + Global API Key**.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>
|
||||
### Создайте ограниченный API-токен
|
||||
|
||||
В панели Cloudflare перейдите в **My Profile → API Tokens →
|
||||
[Create Token](https://dash.cloudflare.com/profile/api-tokens)**, выберите шаблон
|
||||
**Edit zone DNS**, ограничьте его областью той зоны, для которой выпускаете сертификат, и создайте
|
||||
токен. Скопируйте его — он показывается только один раз.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Запустите выпуск через Cloudflare
|
||||
|
||||
`x-ui` → **`21` — Cloudflare SSL Certificate**. На запрос выберите **`t`** для
|
||||
API-токена (по умолчанию) или **`g`** для Global API Key, затем введите свой
|
||||
домен (а для Global API Key — ещё email учётной записи и ключ). acme.sh создаёт
|
||||
TXT-запись, проходит проверку и убирает её.
|
||||
</Step>
|
||||
|
||||
<Step>
|
||||
### Направьте на него панель
|
||||
|
||||
Как и в случае с доменом, используйте **Set Cert paths for the panel** (меню `20`) или задайте
|
||||
`webCertFile` / `webKeyFile` в разделе [Настройки панели](/docs/config/panel#tls).
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
<Callout type="info">
|
||||
Предпочитайте ограниченный токен Global API Key — он даёт право только на изменение
|
||||
DNS в выбранной вами зоне, поэтому его утечка не затронет остальную часть вашей учётной записи Cloudflare.
|
||||
</Callout>
|
||||
|
||||
## Вручную (Certbot)
|
||||
|
||||
Если вы предпочитаете не пользоваться меню, выпустите сертификат с помощью standalone-плагина
|
||||
Certbot (это, опять же, требует свободного порта 80 и домена, указывающего на сервер):
|
||||
|
||||
```bash
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
Certbot записывает сертификат в `/etc/letsencrypt/live/yourdomain.com/`
|
||||
(`fullchain.pem` и `privkey.pem`). Укажите панели путь к этим двум файлам в разделе
|
||||
[Настройки панели](/docs/config/panel#tls) и настройте продление — `certbot renew`
|
||||
по умолчанию запускается через таймер systemd.
|
||||
|
||||
## Использование сертификата
|
||||
|
||||
- **Панель** — задайте `webCertFile` (полная цепочка) и `webKeyFile` (приватный
|
||||
ключ) в разделе [Настройки панели](/docs/config/panel#tls). Чтобы панель переключилась
|
||||
на HTTPS, должны быть заданы оба. Пункт меню **`11` — View Current Settings** выводит
|
||||
пути, используемые в данный момент.
|
||||
- **Входящие подключения** — когда вы включаете TLS на входящем подключении, укажите те же
|
||||
файлы сертификата и ключа (или вставьте их содержимое) в настройках TLS этого подключения.
|
||||
См. [Входящие подключения](/docs/config/inbounds) и
|
||||
[Транспорты](/docs/config/transports).
|
||||
|
||||
<Callout type="warn">
|
||||
Сертификаты истекают (Let's Encrypt: 90 дней; IP-сертификаты: ~6 дней). И меню, и
|
||||
Certbot продлевают их автоматически, но панель продолжает читать **файлы** по их
|
||||
фиксированным путям — поэтому продлевайте **на месте**, а не перемещайте файлы, и
|
||||
панель подхватит новый сертификат при следующем перезапуске. **Force Renew** (меню `20`)
|
||||
запускает продление по требованию.
|
||||
</Callout>
|
||||
|
||||
## Дальнейшие шаги
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
title="Настройки панели"
|
||||
href="/docs/config/panel#tls"
|
||||
description="webCertFile / webKeyFile и остальные настройки веб-сервера."
|
||||
/>
|
||||
<Card
|
||||
title="Обратный прокси"
|
||||
href="/docs/operations/reverse-proxy"
|
||||
description="Доверьте терминирование TLS Nginx или Caddy."
|
||||
/>
|
||||
<Card
|
||||
title="REALITY"
|
||||
href="/docs/config/reality"
|
||||
description="Скрытный TLS для входящих подключений — сертификат не требуется."
|
||||
/>
|
||||
</Cards>
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Подписка
|
||||
description: Запуск сервера подписок 3x-ui — форматы base64/JSON/Clash, порты и пути, TLS, заголовки ответа и пользовательские шаблоны.
|
||||
icon: Rss
|
||||
---
|
||||
|
||||
**Подписка** — это единый URL, который возвращает все конфигурации клиента.
|
||||
Клиентские приложения периодически обновляют его, поэтому при изменении
|
||||
входящего соединения клиенты подхватывают изменения автоматически. Сервер
|
||||
подписок работает как **отдельный** сервер от панели.
|
||||
|
||||
## Включение и настройка
|
||||
|
||||
Сервер подписок **включён по умолчанию** (`subEnable`). Настройте его в
|
||||
параметрах подписки панели:
|
||||
|
||||
| Параметр | По умолчанию | Назначение |
|
||||
| ------------- | ------- | --------------------------------------------------------------- |
|
||||
| `subPort` | `2096` | Порт прослушивания (отдельный от панели). |
|
||||
| `subListen` | _(все)_ | Адрес привязки. |
|
||||
| `subPath` | `/sub/` | Базовый путь для необработанных URL подписок. |
|
||||
| `subDomain` | _(нет)_ | Публичный хост; если задан, сервер отвечает только для этого Host. |
|
||||
| `subCertFile` / `subKeyFile` | _(нет)_ | Сертификат + ключ TLS — когда заданы, сервер работает по **HTTPS**. |
|
||||
| `subEncrypt` | `true` | Кодировать тело необработанной подписки в base64. |
|
||||
| `subUpdates` | `12` | Рекомендуемый интервал обновления (часы), отправляемый клиентам. |
|
||||
|
||||
URL подписки выглядит так:
|
||||
|
||||
```text
|
||||
https://<sub-host>:<sub-port>/sub/<sub-id>
|
||||
```
|
||||
|
||||
где `<sub-id>` — это **Sub ID** клиента.
|
||||
|
||||
Один и тот же Sub ID отдаётся в нескольких форматах по разным путям — список
|
||||
**Base64** по `subPath` и конфигурация **JSON** (Xray-json) по пути JSON.
|
||||
Соберите URL и предпросмотрите оба тела здесь:
|
||||
|
||||
<SubscriptionBuilder />
|
||||
|
||||
## Форматы вывода
|
||||
|
||||
**Формат выбирается по пути**, у каждого свой переключатель включения:
|
||||
|
||||
| Формат | Путь | Включается | Вывод |
|
||||
| --------------------- | --------- | ---------------- | --------------------------------------------------- |
|
||||
| **Необработанные ссылки** | `/sub/` | всегда (если включён) | Список ссылок `vless://`, `vmess://`, … (закодированных в base64, когда включён `subEncrypt`). |
|
||||
| **JSON** | `/json/` | `subJsonEnable` | Полные клиентские конфигурации Xray. |
|
||||
| **Clash / Mihomo** | `/clash/` | `subClashEnable` | YAML-профиль. |
|
||||
|
||||
В подписке появляются только включённые входящие соединения, использующие
|
||||
**VLESS, VMess, Trojan, Shadowsocks или Hysteria2**, упорядоченные по их индексу
|
||||
сортировки подписки. Запрос `/sub/` с заголовком `Accept: text/html` (или
|
||||
`?html=1`) возвращает удобочитаемую информационную страницу вместо
|
||||
необработанного тела.
|
||||
|
||||
### Base64 vs JSON
|
||||
|
||||
Тело **Base64** — это просто ссылки для обмена, объединённые через перевод
|
||||
строки и закодированные в стандартный base64 (переключается через `subEncrypt`).
|
||||
Тело **JSON** оборачивает каждого клиента в полную клиентскую конфигурацию
|
||||
Xray — фиксированный каркас (локальные входящие mixed/HTTP, DNS, маршрутизация,
|
||||
policy) плюс исходящее соединение `proxy`, указывающее на входящее. 3x-ui
|
||||
выдаёт **единый объект конфигурации для одного клиента и массив для
|
||||
нескольких**, использует плоскую форму `settings` исходящего соединения
|
||||
(`address`/`port`/`id`, `level: 8`) и удаляет `sockopt` из `streamSettings`.
|
||||
|
||||
## Заголовки ответа
|
||||
|
||||
Подписки возвращают стандартные заголовки, которые читают совместимые
|
||||
приложения:
|
||||
|
||||
- **`Subscription-Userinfo`** — `upload`, `download`, `total` (байты; `total=0`
|
||||
означает без ограничений) и `expire` (Unix-секунды).
|
||||
- **`Profile-Update-Interval`** — интервал обновления в часах (`subUpdates`).
|
||||
- **`Profile-Title`**, **`Support-Url`**, **`Profile-Web-Page-Url`**,
|
||||
**`Announce`** — необязательный брендинг, отображаемый некоторыми клиентами.
|
||||
|
||||
## Пользовательские шаблоны страниц
|
||||
|
||||
Укажите в `subThemeDir` папку с пользовательским шаблоном информационной
|
||||
страницы, чтобы оформить HTML-страницу подписки в фирменном стиле. Примечание
|
||||
для каждого клиента на каждой ссылке полностью шаблонизируется — см.
|
||||
[Ссылки для обмена → переменные примечаний](/docs/config/share-links#remark-template-variables).
|
||||
|
||||
<Callout type="info">
|
||||
Разместите сервер подписок за TLS (задайте `subCertFile`/`subKeyFile` или
|
||||
[обратный прокси](/docs/operations/reverse-proxy)), чтобы содержимое подписки
|
||||
не передавалось в открытом виде.
|
||||
</Callout>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user