github MHSanaei/3x-ui v3.9.0

3 hours ago

๐Ÿš€ Native TUIC, Tunnels on Nodes, Xray-core v26.9.30 & Reliable Client Resets

  • ๐Ÿš€ Native TUIC v5 server โ€” TUIC now runs inside the panel in Go, with no external binary to download, BBR congestion control and crash-safe traffic accounting.
  • ๐ŸŒ AmneziaWG, TUIC & MTProto on nodes โ€” these inbounds can now be created and cloned from the master straight onto a node.
  • โš™๏ธ Xray-core v26.9.30 โ€” stored XDNS masks and WireGuard outbound settings are migrated to the new core's shape automatically.
  • ๐Ÿ” Client lifecycle you can trust โ€” resets, renewals and quota cuts now reach every counter on every node, and saving an inbound or editing a client no longer reverts changes made in the meantime.
  • ๐Ÿค– Telegram bot access levels โ€” unknown accounts are locked out, customers link themselves with an invite link, and admins can broadcast to every client.
  • ๐Ÿ—“๏ธ Weekly calendar renewal โ€” clients can renew on a fixed weekday, with a preview of the upcoming schedule.
  • ๐Ÿ“ฆ Subscription controls โ€” hide an inbound from subscriptions without disabling it, carry traffic through export/import, and set the User-Agent used for external subscriptions.
  • ๐Ÿ” Security hardening โ€” API token rotation, database restore, certificate fetching and the bot's command surface are all tightened.

โš ๏ธ Before you upgrade

Action required

  • /panel/api/inbounds/update and the inbound JSON editor no longer change which clients an inbound holds, their enable/expiry/quota/renewal fields, or the inbound's own enable flag โ€” do this: move any script that edits clients through an inbound update to the client endpoints, and use /panel/api/inbounds/setEnable/:id to switch an inbound on or off.
  • The Telegram bot now answers only /start and /id for accounts that are not linked to a client or listed as an admin โ€” do this: link customers who used /usage or /status by setting their Telegram ID on the client, or send them the new invite link from the client card.
  • XDNS finalmask changed its wire format in Xray-core v26.9.30 โ€” do this: update clients that use an XDNS mask to a core of v26.9.30 or newer, or they will not connect.
  • Weekly renewal is ignored by older binaries, and an older panel's depleted-client cleanup can delete a weekly-only client โ€” do this: upgrade every node before enabling weekly mode, and convert weekly clients to another mode before any downgrade.
  • Deploying an AmneziaWG, TUIC or MTProto inbound to a node is refused when the node is older than the release that introduced the protocol (MTProto v3.5.0, AmneziaWG v3.7.0, TUIC v3.8.0) โ€” do this: upgrade the node first.
  • WireGuard and AmneziaWG allowedIPs that overlap another client's range are now rejected; existing overlapping clients keep working but cannot be saved until fixed โ€” do this: narrow such ranges (for example 10.10.2.9/24 โ†’ 10.10.2.9/32) when editing them.
  • Self-built Docker images: the frontend stage now uses Node 26 โ€” do this: rebuild from the updated Dockerfile; an older copy fails at npm ci.

Automatic โ€” no action needed

  • One-time startup migrations rewrite stored XDNS finalmasks (inbounds, hosts, Xray template, JSON-subscription mask, cached outbound subscriptions) into the new object shape, and move a WireGuard outbound's domainStrategy to sockopt.domainStrategy / targetStrategy (remoteDNS: "local" becomes targetStrategy). They also add the excludeFromSub and weekly-renewal columns and the node_pending_resets and tuic_traffic_receipts tables. A migration failure stops the panel from starting.
  • The install and update scripts remove the old tuic-server binary, its bin/tuic configs and any leftover processes; TUIC inbounds come back up on the built-in server.
  • x-ui setting -getApiToken -tokenName <name> now keeps the regenerated token's scope and expiry instead of turning it into a non-expiring admin token; an already expired token is refused rather than rotated.
  • The panel fetches the sponsor list from sponsors.sanaei.dev at most once an hour and proxies sponsor logos itself, so admin browsers never contact a third party.

Requirements

Go 1.27.1 ยท Xray-core v26.9.30 ยท Node 26 (only for building the frontend from source)


๐Ÿ” Security

  • Regenerating a named API token from the CLI no longer silently turns a scoped or expiring token into a permanent full-admin one (#6700) @rokokol
  • Fetching a remote certificate for pinning now refuses private and loopback addresses unless the admin confirms, matching the REALITY target scan (ede275e4)
  • Restoring a SQL dump can no longer open or create any database file other than the panel's own (d31465e3)
  • The Telegram bot no longer lets unlinked accounts run client commands or press client buttons; invite-link claims are rate-limited and cannot be used to probe for valid subscription IDs (#6518) @pcxzs
  • Saving an inbound no longer restores a client that was deleted while the edit dialog was open, which brought revoked credentials back to life (823db059)
  • Subscriptions can tell supported client apps to require authentication on their local SOCKS/HTTP proxy, so other apps on the device can no longer use it to bypass per-app routing or learn the server address (#6628) @rudenko-ks

๐Ÿ†• New

  • TUIC v5 is now served by a native in-process Go server with BBR/New Reno congestion control, native and QUIC UDP relay, full Xray routing and a durable traffic journal โ€” no external binary (#6577) @poise52
  • AmneziaWG, TUIC and MTProto inbounds can be created and cloned onto nodes from the master (ed31ee43)
  • Calendar weekly renewal, plus a preview of upcoming renewal dates in the individual and bulk client forms (#6524) @JacktheRanger
  • Telegram bot invite links: the client card offers a link that binds the first account to open it (#6518) @pcxzs
  • Telegram bot /broadcast sends any admin message โ€” text, media or a whole album โ€” to every linked client, with progress and cancel (#6510) @DIMFLIX
  • Per-inbound "exclude from subscription" hides an inbound's links while it keeps serving and counting traffic (#6463) @mrchatam
  • Portable client export/import now carries traffic counters, without inflating group totals (#6469) @mrchatam
  • Visual routing-profile editor for client apps, with optional ad blocking and a LAN-bypass preset (#6545) @NgaiYeanCoi
  • App-management subscription headers for a second client app: per-app split tunnelling, fragmentation, UDP noise, DoH pre-resolution, banners and more (#6650) @DIMFLIX
  • Configurable User-Agent for fetching external subscriptions (#6613) @mrchatam
  • x-ui setting -getApiToken -tokenScope <scope> chooses the scope of the issued token (#6700) @rokokol
  • Finalmask noise items accept the new tag-expression type, and TUN exposes the new gateway-DNS and leak-block options (62423cac)
  • Sponsor slots on the overview, sidebar and login page plus a Sponsors page, with scheduled start dates; each slot can be hidden for 24 hours (fd7b3559, 09617f04, dcaadd48)

โšก Improved

  • Xray-core updated to v26.9.30 (62423cac)
  • Go, frontend and docs dependencies refreshed; the frontend baseline is now Node 26 / npm 11 (86302d2f, 99bc68fa)
  • TUIC throughput through Xray rises from about 2.4 to 3.4 Gbit/s on loopback with BBR (#6577) @poise52
  • The client-app settings page is folded from seven tabs into four (8f47b538)
  • The test suite runs several times faster and isolates each package on PostgreSQL (12d51d71, #6594) @n0ctal
  • README screenshots refreshed for the current UI (17d7dd46)

๐Ÿž Fixed

Clients & traffic

  • Saving an inbound no longer reverts client renewals, expiry, quotas, clients added meanwhile, the inbound's enable switch or traffic counted while the dialog was open (1110caaa, 823db059)
  • Adding, editing or deleting a client no longer undoes a renewal of another client that committed at the same moment (63ffc083)
  • A client traffic reset now reaches every node hosting the client and the MTProto quota, so a reset client is no longer switched off again on the next tick (4210a50c)
  • A client that ran out of quota or time is now dropped from every inbound it belongs to, not only the last one it was attached to (7c84ca96)
  • Resetting an inbound's traffic on a node now hits that inbound instead of an unrelated one (#6717) @ChesterFishmansWork

Subscriptions

  • JSON subscriptions for REALITY inbounds with a Host SNI no longer ship a config the client core refuses to start (#6691) @FZ1010
  • WireGuard, AmneziaWG and TUIC configs now advertise the inbound's Hosts on every surface, not the panel address (aee45ca3)
  • A client on several WireGuard/AmneziaWG inbounds now gets each inbound's own keys and address in its subscription (#6653) @mvanhorn

Protocols

  • Hysteria client changes are applied live instead of restarting the inbound and stalling every connected client (#6606) @iblchv
  • A WireGuard allowedIPs written as 10.10.2.9/24 can no longer claim other clients' traffic (c8a182b6)
All 45 fixes in this release

Clients & traffic

  • Saving an inbound no longer reverts client renewals, expiry, quotas, clients added meanwhile, the inbound's enable switch or traffic counted while the dialog was open (1110caaa, 823db059)
  • Adding, editing or deleting a client no longer undoes a renewal of another client that committed at the same moment (63ffc083)
  • A traffic reset no longer leaves a quota-disabled client looking enabled while it is dropped from the core (feb8451b)
  • A client traffic reset now reaches every node hosting the client and the MTProto quota, so a reset client is no longer switched off again on the next tick (4210a50c)
  • Resetting inbound traffic no longer hands every MTProto client a fresh quota, and a per-inbound client reset no longer touches other inbounds (fb7418f7)
  • A client that ran out of quota or time is now dropped from every inbound it belongs to, not only the last one it was attached to (7c84ca96)
  • Resetting an inbound's traffic on a node now hits that inbound instead of an unrelated one (#6717) @ChesterFishmansWork
  • Inbounds exported from v2.x panels import again (15d82a5e)
  • A WireGuard allowedIPs written as 10.10.2.9/24 can no longer claim other clients' traffic (c8a182b6)
  • Client search and group filter match names with non-ASCII capitals (#6685) @freeb5d
  • Changing a client's device limit can no longer be overwritten by a concurrent traffic cycle (#6591) @n0ctal
  • IP-limit bans reach fail2ban only after the scan is saved, so a failed save can no longer ban addresses the panel never recorded (#6590) @n0ctal
  • On PostgreSQL, concurrent IP-limit updates no longer drop node-reported IPs (#6612) @mrchatam

Subscriptions & links

  • JSON subscriptions for REALITY inbounds with a Host SNI no longer ship a config the client core refuses to start (#6691) @FZ1010
  • Spider settings in a REALITY spiderX query are kept in share links and JSON subscriptions (#6694) @FZ1010
  • VLESS REALITY share links carry the ML-KEM key-exchange hint (#6712) @libmur-dev
  • Fragment settings export in a form older client cores understand, and inbounds with UDP-only masks no longer break the QR, info and export views (#6702) @artemk1337
  • WireGuard, AmneziaWG and TUIC configs now advertise the inbound's Hosts on every surface, not the panel address (aee45ca3)
  • A client on several WireGuard/AmneziaWG inbounds now gets each inbound's own keys and address in its subscription (#6653) @mvanhorn
  • Clash subscriptions include the Hysteria2 certificate pin, so self-signed certificates are accepted (#6651) @libmur-dev
  • Clash subscriptions keep the encryption of external VLESS links (#6576) @SakikoTogawa0214
  • The server description in external link remarks is no longer mangled (#6580) @sdhfsl
  • Outbound subscription fetches send the same device ID as external links, so device-limited providers count the panel once (#6579) @sdhfsl
  • Behind a proxy that sends only X-Real-IP, links no longer advertise the subscriber's own IP as the server (#6608) @mrchatam
  • The JSON-subscription template no longer triggers a deprecation warning for its direct outbound (#6609) @mrchatam
  • Downloads on phones keep their file name, so peer.conf is no longer saved as peer.conf.txt (99047c0a)

Protocols & core

  • Hysteria client changes are applied live instead of restarting the inbound and stalling every connected client (#6606) @iblchv
  • An IPv4 inbound can share a port with an IPv6-only wildcard inbound (#6603) @lin-finegold
  • config.json is written after a hot apply, so config backups no longer upload stale rules (#6686) @freeb5d
  • AmneziaWG no longer redirects connections to a sniffed domain, and its IPv6 egress no longer breaks IPv4 traffic (#6654) @rudenko-ks
  • AmneziaWG padding and header ranges are validated the way the engine enforces them, accepting real configs that were refused and rejecting ones that would fail to start (#6642) @rudenko-ks
  • AmneziaWG tunnels without IPv6 stop resolving AAAA records, and the outbound form exposes I2โ€“I5 (#6611) @mrchatam
  • AmneziaWG inbounds and outbounds work on Windows builds (044e2926, 75f3702d)
  • The node-token key file loads on Windows (3fc3992a)

Bots

  • The Telegram bot picks up Panel Outbound when Xray starts after it, instead of staying unreachable on filtered hosts (bb18734c)
  • The bot's individual-links and QR actions work when the subscription host does not resolve from the server (4df570b3)
  • The bot's add-client wizard offers WireGuard and AmneziaWG inbounds and no longer shows an empty picker (#6621) @romus204
  • Two admins in one group chat no longer share one add-client wizard (#6604) @sdhfsl

Panel & system

  • Panel navigation recovers after an update leaves the browser with stale page chunks (#6679) @mvanhorn
  • The Syslog view no longer hangs on a slow journal (#6689) @freeb5d
  • On EL7, firewalld pulled in by fail2ban no longer blocks the panel's ports (#6688) @freeb5d
  • The x-ui menu opens instantly on hosts with large journals (092cbd55)
  • A legacy inbound-tag cleanup no longer fails every startup migration when its target tag already exists (#6592) @n0ctal
  • The Docker image builds again (9b957b96)
  • The REALITY "Min Client Ver" hint states which cores accept every client when the field is empty (3308c816)

Reports

Total Download

New Contributors

Full Changelog: v3.8.5...v3.9.0

Don't miss a new 3x-ui release

NewReleases is sending notifications on new releases.