mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-16 01:55:01 +03:00
9b91f0f42e
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.
158 lines
6.5 KiB
Plaintext
158 lines
6.5 KiB
Plaintext
---
|
|
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>
|