Files
3x-ui/docs/content/docs/en/config/tuic.mdx
T
Egor 207c705300 fix(tuic): preserve client identity for Xray user routing (#6875)
TUIC traffic reached Xray through a loopback SOCKS relay that took no login,
so Xray never learned which client a connection belonged to and user routing
rules never matched TUIC (#6874). The relay now carries one account per client
email, so per-user rules match on TCP and both UDP modes; admission stays with
the native TUIC server.

Adding, removing or renaming a TUIC client swaps only that inbound's relay
instead of restarting Xray: new sessions wait behind a bounded gate while live
streams and UDP associations continue, accounts are verified after the swap and
rolled back on failure, one failing relay no longer strands the others or blocks
unrelated live changes, and emails over SOCKS5's 255-byte limit are excluded
with a warning.
2026-10-24 06:20:39 +02:00

113 lines
7.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: TUIC
description: Set up a TUIC inbound in 3x-ui — QUIC congestion control, 0-RTT handshakes, and multi-user authentication.
icon: Zap
---
**TUIC** (v5) is a proxy protocol built directly on top of the **QUIC** (HTTP/3) transport
layer. It uses 0-RTT handshakes, connection multiplexing without head-of-line blocking,
and custom congestion control algorithms to maintain stable connections over lossy or
unstable networks.
<Callout type="info">
TUIC runs as an **in-process native Go server** inside 3x-ui. Decrypted traffic is bridged into Xray-core via a loopback SOCKS5 tunnel, enabling full Xray routing rules, cascading outbounds (e.g. TUIC → VLESS / WARP), per-client traffic quotas (`totalGB`), and in-memory client management.
</Callout>
## Key settings
### Server, QUIC & client-profile parameters
| Field | Description |
| --- | --- |
| **Port** | UDP port for incoming client QUIC connections. |
| **Certificate & Key** | Full TLS certificate chain and private key. QUIC mandates TLS encryption; self-signed certificates or valid Let's Encrypt / ACME certs are supported. |
| **SNI** | Client-profile Server Name Indication. Set it to the domain covered by the server certificate; this field does not configure the listener certificate. |
| **Congestion Control** | QUIC congestion control algorithm used in the server setting and exported client profile: `bbr`, `cubic`, or `new_reno`. The server runs BBR or New Reno; when CUBIC is selected, the client profile keeps CUBIC while this server currently falls back to New Reno. |
| **ALPN** | Application-Layer Protocol Negotiation tokens (default: `h3`). |
| **UDP Relay Mode** | Client-profile packet mode: `native` (QUIC datagrams) or `quic` (unidirectional streams). The server accepts both modes regardless of this exported preference. |
| **Zero-RTT Handshake** | Enables 0-RTT connection resumption to eliminate initial handshake round-trips for returning clients. |
| **Authentication Timeout** | Maximum time (seconds) allowed for client authentication before disconnecting (default: `3s`). |
| **Max Idle Time** | Inactivity timeout (seconds) before closing idle QUIC connections (default: `15s`). |
| **Max Packet Size** | Maximum UDP relay packet size in bytes (default: `1500`). |
## Set it up in the panel
<Steps>
<Step>
### Add an inbound
Create a new inbound and choose protocol **TUIC**. Assign a UDP port (e.g. `8443` or `443`).
</Step>
<Step>
### Select TLS certificate
Provide the certificate file path and private key file path (or paste their contents). Make sure the configured SNI matches the certificate domain.
</Step>
<Step>
### Configure QUIC options
The panel fills recommended defaults (`bbr`, `h3`, `native` UDP relay). Adjust timeouts or enable **Zero-RTT Handshake** if desired.
</Step>
<Step>
### Add clients
Each client requires an **Email** identifier, a **UUID** (token), and a **Password**. TUIC email identifiers must contain 1–255 UTF-8 bytes. Existing clients with invalid identifiers are excluded from TUIC service with a warning; shorten their identifiers to restore access. The panel automatically generates secure random credentials when creating clients.
</Step>
<Step>
### Export and connect
Copy the client's share link (`tuic://…`) or open the **QR modal** to download a ready-to-use **Clash / Mihomo YAML** configuration.
</Step>
</Steps>
## Client support & configuration
TUIC v5 is supported by modern proxy clients including **Clash Verge Rev**, **Mihomo**, **Flclash**, **sing-box**, and **v2rayN**.
### Clash / Mihomo configuration
The panel provides automatic YAML export for Clash/Mihomo in the client QR modal:
```yaml title="clash-tuic.yaml"
proxies:
- name: "3x-ui-tuic"
type: tuic
server: vpn.example.com
port: 8443
uuid: 8a47f2b1-5e8c-4a3d-9b1e-7f6c5d4a3b2a
password: secure-random-password
alpn:
- h3
sni: vpn.example.com
congestion-controller: bbr
udp-relay-mode: native
reduce-rtt: false
skip-cert-verify: false
```
### Share link format
TUIC share links use standard URI formatting:
```text
tuic://<uuid>:<password>@<host>:<port>?congestion_control=bbr&alpn=h3&sni=vpn.example.com&udp_relay_mode=native&allow_insecure=0#Remark
```
## Architecture & Features
<Callout type="info">
- **Native in-process Go engine**: TUIC v5 runs 100% natively in Go within the 3x-ui process. No external binaries or sidecars to download or maintain.
- **Full Xray routing & cascading**: Decrypted traffic passes directly through Xray's routing engine. The client **Email** is preserved for `user` rules on TCP and both UDP modes. Inbound tags (`in-<port>-udp`), domain/IP rules, and cascading to any outbound proxy (VLESS, Shadowsocks, WARP, etc.) are supported. Put specific `inboundTag` + `user` rules before broader `user` rules; Xray uses the first matching rule.
- **Per-client traffic limits & expiration**: Individual traffic quotas (`totalGB`) and expiration timestamps (`expiryTime`) are tracked and enforced for each client.
- **Live speed & traffic totals**: Native TUIC client counters are sampled every 10 seconds and sent to the panel for per-client live speed. Xray meters inbound totals through the loopback relay. A separate relay policy disables Xray's per-user traffic and loopback online-IP counters; native TUIC remains the source for client accounting, speed, and activity.
- **UDP resource bounds**: Each QUIC connection can hold up to 256 active UDP associations. Idle associations are closed after five minutes. This is a per-connection limit, not a node-wide association cap. TUIC uses a reserved loopback SOCKS relay port in `64001–65000`; 3x-ui checks it against managed inbound and relay ports.
- **Client updates**: Native TUIC enforces client enable/disable, quotas, and expiration; resetting a quota restores access without restarting Xray. Adding, removing, or renaming clients replaces only that inbound's internal SOCKS relay. Accounts are validated before replacement and checked again against the running relay afterward. A failed update restores the previous relay and schedules a retry. Failures are isolated to related relays: healthy TUIC inbounds and independent Xray updates continue to apply. Routing changes that depend on a failed tag change wait for that relay to recover. Related client and inbound changes also wait; new TUIC sessions are admitted only after their routing policy is applied. New relay connections wait up to 10 seconds while replacement or rollback is in progress; existing TCP streams and UDP associations continue running. New UDP associations use a bounded packet queue so they do not block existing flows on the same QUIC connection. Waiting is canceled on disconnect. Queue overflow or an unavailable relay can still reject a new request; other protocols keep running. TUIC password-only changes and client-profile edits do not change relay accounts.
- **Deployment**: A TUIC inbound can be created on, or cloned to, a sub-node. The node's own panel runs the TUIC server, so the node must run panel v3.8.0 or newer; the master refuses an older node.
</Callout>