MHSanaei/3x-ui v3.7.0
一句话概括:本次版本加入原生 AmneziaWG 支持与按日历月续费、可限定范围的 API Token,并对多节点同步、事务一致性和订阅输出做了大规模加固与修复。
新增能力
- 原生 AmneziaWG 3.1:AmneziaWG inbound 以内嵌用户态设备 + reconcile 管理器在进程内运行,抗 DPI peer 不再需要内核模块、Docker 或第二个面板。
- 出站与路由扩展:新增通过登录添加 PIA WireGuard outbounds;支持 remote routing URL;用户规则中加入客户端选择器;可直接从路由规则浏览 geosite/geoip 分类;新增
DisableFlow(让某个 inbound 退出自动 XTLS Vision)。
- 客户端生命周期(可对账计费):续费按整日历月递进;每个客户端独立流量重置周期;自动续费次数上限;可删除单个 HWID 设备;每客户端订阅 HWID 限制;每客户端外部链接开关;IP 限制可豁免可信地址。
- 凭证可限定范围与吊销:API Token 支持 scope 和可选过期时间;节点 API Token 可选静态加密;替换 TOTP secret 必须提供 2FA 验证码;CLI 不再悄悄累积等效管理员 Token。
- 订阅输出:JSON 订阅支持客户端侧 balancer;订阅元数据支持模板变量;暴露最后拉取时间;浏览器打开订阅 URL 时返回中性的 copy-only 页面;salamander 配置无法到达客户端时给出警告;新增订阅排序的窄接口。
- 多节点/前端/供应链:多节点克隆初版;导入数据库时保留本机设置;侧边栏可固定;network-only PWA 可安装;日志级别、访问事件、日历标签完成本地化;构建工具链升至 Go 1.27、TypeScript 7 + oxc(oxlint/oxfmt);发布镜像附带 provenance 与 SBOM attestation;release 二进制标记源码 revision。
重要修复
- 节点同步:不再删除本不打算删的客户端;过期的到期同步不再覆盖客户端的续期;匹配到已部署的 inbound 时改为复用而非重建;保留快照无法上报的禁用 inbound;未采纳任何 inbound 时不再写入
InboundsAdoptedAt;mTLS 信任包中每个证书都做校验;主 mTLS 证书轮换无需重启面板;主 mTLS 凭证原子持久化并停止静默重签。
- 事务正确性:批量客户端推送、流量维护副作用、分组移动都改为 commit 落库后才触发;半途失败的启动迁移不再静默提交。
- 其他关键修复:Hysteria2 超限客户端强制断连、离线客户端 IP 过期清理、LDAP 空目录不再触发自动删除全部客户端、inbound 端口 check-and-claim 竞态、拒绝空 client auth 的 Hysteria inbound 更新、REALITY 目标检查在私网可用、WARP Plus license key 在换 IP 时保留、从标准 obfs 参数正确导入 Hysteria2 salamander、单一被污染的 DNS 响应不再阻塞出站测试、jalali 到期清除按钮真正生效、表格虚拟化相关问题与响应式高度、安装更新时保留自定义
bin/ 文件、面板代理转发给 update.sh 下载。
Breaking changes / 升级注意
- 首次启动会执行自动 schema 迁移(客户端 reset-cycle 与 last-fetch 列、节点同步 orphan 列、小写 client-email 索引、API token scope/expiry、外链规范化),升级前务必备份数据库。
- 导入数据库默认保留本机的 listen 地址、端口、base path、证书路径和节点身份;取消勾选新复选框可恢复旧的整文件克隆行为。
- 浏览器打开订阅 URL 默认返回 copy-only 页面,需追加
html=1 或 view=html 才显示订阅信息页。
x-ui setting -getApiToken 现在轮换单个 cli-fallback token,而不是新签发,因此此前打印出的 CLI fallback token 将失效。
- 日历续费是逐客户端 opt-in,仍为 day 0 的客户端保持旧的滚动间隔。
- 从源码构建现在需要 Go 1.27 工具链。
▸ Release Notes 英文原文(18578 字符)
## 🚀 Native AmneziaWG, Calendar-Day Renewals, Scoped API Tokens & Node-Sync Hardening
- 🛡️ **Native AmneziaWG 3.1** — AmneziaWG inbounds run in-process on an embedded userspace device with a reconcile manager, so DPI-resistant peers need no kernel module, no Docker and no second panel.
- 🌐 **More outbound and routing reach** — PIA WireGuard outbounds added by login, remote routing URLs, a client picker inside user rules, and geosite/geoip categories browsable straight from a routing rule.
- 📅 **Client lifecycle you can actually bill against** — renewals that step whole calendar months, a per-client traffic reset cycle, a cap on auto-renewals, single-device HWID removal, per-client subscription HWID limits and per-client external-link controls.
- 🔑 **Credentials that can be scoped and revoked** — API tokens now carry scopes and an optional expiry, node API tokens can be encrypted at rest, replacing the TOTP secret requires a 2FA code, and the CLI stopped quietly accumulating admin-equivalent tokens.
- 🔗 **Subscription output** — client-side balancers in the JSON format, template variables in subscription metadata, an exposed last-fetch time, and a neutral copy-only page when a subscription URL is opened in a browser.
- 🕸️ **Multi-node hardening** — the sync adopts a matching deployed inbound instead of recreating it, keeps disabled inbounds a snapshot cannot report, stops undoing client extensions, validates every certificate in the mTLS trust bundle, and applies a rotated master certificate without a panel restart.
- 🧱 **Transactional correctness** — bulk client pushes, traffic maintenance side effects and group moves now fire only after the commit lands, and a half-applied startup migration can no longer commit silently.
- 🧰 **Toolchain and supply chain** — Go 1.27, TypeScript 7 on the oxc toolchain, provenance plus SBOM attestations on published images, and release binaries stamped with their source revision.
- 🖥️ **Panel polish** — a pinnable sidebar, network-only PWA installability, virtualized tables, real loading spinners, and localized log levels, access events and calendar labels.
> ℹ️ **Heads-up:** First start runs **automatic schema migrations** (client reset-cycle and last-fetch columns, node sync orphan columns, a lowercase client-email index, API token scope/expiry, external-link normalization) — **take a database backup before upgrading**. Two defaults changed for existing setups: **importing a database now keeps this machine's own listen addresses, ports, base path, certificate paths and node identity** (clear the new checkbox to restore the old whole-file clone), and **opening a subscription URL in a browser returns a copy-only page** unless you append `html=1` or `view=html`. `x-ui setting -getApiToken` now **rotates a single `cli-fallback` token** instead of minting a new one, so previously printed CLI fallback tokens stop working; calendar renewal is opt-in per client, so clients left on day 0 keep the old rolling interval. Building from source now requires the **Go 1.27 toolchain**.
<h3>🆕 New</h3>
- [feat(amneziawg): add native AmneziaWG protocol support](https://github.com/MHSanaei/3x-ui/commit/effcccce) (#6105) @Kuzz007
- [feat(pia): add PIA login-and-add WireGuard outbounds](https://github.com/MHSanaei/3x-ui/commit/bd6a6aba) (#6272) @Masterain98
- [feat(inbound): DisableFlow — opt an inbound out of auto XTLS Vision](https://github.com/MHSanaei/3x-ui/commit/930a0ed5) (#5698) @FZ1010
- [feat(routing): add client picker to user rules](https://github.com/MHSanaei/3x-ui/commit/02002dc1) (#6271) @ZaneL1u
- [feat(xray): browse geosite/geoip categories from routing rules](https://github.com/MHSanaei/3x-ui/commit/d7698ec7) (#6165) @STRENCH0
- [feat(routing): add remote routing URL support](https://github.com/MHSanaei/3x-ui/commit/380aff4d) (#6168) @yelloduxx
- [feat(clients): renew on a calendar day instead of a rolling interval](https://github.com/MHSanaei/3x-ui/commit/b8903fad) (#6239) @n0ctal
- [feat(clients): give each client its own traffic reset cycle](https://github.com/MHSanaei/3x-ui/commit/5c7ca5b5) (#6240) @n0ctal
- [feat(clients): cap how many times a client may auto-renew](https://github.com/MHSanaei/3x-ui/commit/e940f30b) (#6238) @n0ctal
- [feat(clients): allow removing a single HWID device](https://github.com/MHSanaei/3x-ui/commit/1250fbb7) (#6265) @Kuzz007
- [feat(sub): add per-client subscription HWID limits](https://github.com/MHSanaei/3x-ui/commit/694ad6de) (#5802) @rqzbeh
- [feat(clients): add per-client external link controls](https://github.com/MHSanaei/3x-ui/commit/abd32099) (#5650) @fastnas2023
- [feat(limitip): let operators exempt trusted addresses from the IP limit](https://github.com/MHSanaei/3x-ui/commit/d6472740) (#6230) @n0ctal
- [feat(sub): client-side balancers for the JSON subscription](https://github.com/MHSanaei/3x-ui/commit/da01b763) (#6243) @DIMFLIX
- [feat(sub): add template variables to subscription metadata](https://github.com/MHSanaei/3x-ui/commit/2d669fa4) (#6163) @isultanov99
- [feat(sub): expose last subscription fetch time](https://github.com/MHSanaei/3x-ui/commit/2217213e) (#6217) @hunmar
- [feat(sub): warn when salamander settings cannot reach the client](https://github.com/MHSanaei/3x-ui/commit/dafd3c0e) (#6177) @n0ctal
- [feat(inbounds): add a narrow endpoint for subscription sort order](https://github.com/MHSanaei/3x-ui/commit/b4e44786) (#6179) @n0ctal
- [feat(api): scoped, optionally expiring API tokens](https://github.com/MHSanaei/3x-ui/commit/1230559e) (#6201) @n0ctal
- [feat(nodes): opt-in encryption at rest for the outbound node API token](https://github.com/MHSanaei/3x-ui/commit/1793a9b8) (#6186) @n0ctal
- [feat(frontend): multi-node cloning initial implementation](https://github.com/MHSanaei/3x-ui/commit/8c8556ab) (#6216) @rlex
- [feat(inbounds): improve multi-node online attribution](https://github.com/MHSanaei/3x-ui/commit/be70535b) (#6164) @isultanov99
- [feat(server): keep this machine's own settings when importing a database](https://github.com/MHSanaei/3x-ui/commit/6e80a468) (#6227) @n0ctal
- [feat(ui): let users pin the sidebar](https://github.com/MHSanaei/3x-ui/commit/5373786f) (#6161) @PathGao
- [feat(web): add network-only PWA installability](https://github.com/MHSanaei/3x-ui/commit/3a2f9b48) (#6190) @korsun009
- [feat(i18n): translate the log levels, access events and calendar labels](https://github.com/MHSanaei/3x-ui/commit/5c9268c4) (#6226) @n0ctal
<h3>⚡ Update & improvement</h3>
- [chore(build): bump Go toolchain to 1.27.0](https://github.com/MHSanaei/3x-ui/commit/81fcacab)
- [Move to TypeScript 7 and the oxc toolchain (oxlint + oxfmt)](https://github.com/MHSanaei/3x-ui/commit/92fb94d8) (#6262)
- [chore(lint): adapt to staticcheck v0.8.0 under golangci-lint v2.13.1](https://github.com/MHSanaei/3x-ui/commit/e4798a02)
- [chore: bump dependencies and clear deprecated frontend APIs](https://github.com/MHSanaei/3x-ui/commit/fcf60eb2)
- [chore(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0](https://github.com/MHSanaei/3x-ui/commit/138e1bd8) (#6162)
- [chore(deps): bump github.com/klauspost/compress from 1.19.1 to 1.19.2](https://github.com/MHSanaei/3x-ui/commit/e2f75aca) (#6212)
- [chore(deps): bump dompurify](https://github.com/MHSanaei/3x-ui/commit/75032fd4) (#6193)
- [chore(deps-dev): bump postcss](https://github.com/MHSanaei/3x-ui/commit/d1423073) (#6173)
- [chore(frontend): resolve the high-severity brace-expansion advisory](https://github.com/MHSanaei/3x-ui/commit/7eacce6a) (#6180) @n0ctal
- [perf(clients): write client_inbounds deltas and check identity from the clients table](https://github.com/MHSanaei/3x-ui/commit/f7db247b)
- [perf(frontend): replace blank Suspense fallbacks with Spin, switch to matchMedia hook, add virtual table scrolling](https://github.com/MHSanaei/3x-ui/commit/8e7fb144) (#6187) @PathGao
- [refactor(tgbot): share numeric keypad transitions](https://github.com/MHSanaei/3x-ui/commit/238e4bb3) (#6211) @n0ctal
- [test(tgbot): detect open-coded keypad transitions](https://github.com/MHSanaei/3x-ui/commit/aecbad3a) (#6214) @n0ctal
- [ci: attach provenance and SBOM attestations to the published images](https://github.com/MHSanaei/3x-ui/commit/7c8a9a69) (#6130) @kobihikri
- [ci(release): stamp released binaries with their source revision](https://github.com/MHSanaei/3x-ui/commit/dc1979a1) (#6223) @n0ctal
- [ci: actually run the PostgreSQL schema and migration tests](https://github.com/MHSanaei/3x-ui/commit/2b1fe1fd) (#6224) @n0ctal
- [refactor(ci): replace the in-house review lanes with the official code-review skill](https://github.com/MHSanaei/3x-ui/commit/58669f61)
- [docs(api): document WireGuard and mtproto secret generation on clients/add](https://github.com/MHSanaei/3x-ui/commit/af3e6c11) (#6282) @rokokol
- [chore(i18n): update tr-TR translations](https://github.com/MHSanaei/3x-ui/commit/f204997c) (#6288) @tarihcituranx
- [fix(i18n): localize Chinese Xray labels](https://github.com/MHSanaei/3x-ui/commit/69a82375) (#6202) @nrps9909
<h3>🐞 Bug fixed</h3>
- [fix(node): stop the node sync from deleting clients it never meant to](https://github.com/MHSanaei/3x-ui/commit/5bc81dfd)
- [fix(node): stop stale expiry sync from undoing client extensions](https://github.com/MHSanaei/3x-ui/commit/6f7a3052) (#6231) @mrchatam
- [fix(node): adopt a matching deployed inbound instead of recreating it](https://github.com/MHSanaei/3x-ui/commit/bb29b6af) (#6197) @n0ctal
- [fix(node): keep disabled inbounds the node snapshot cannot report](https://github.com/MHSanaei/3x-ui/commit/6a674c7f) (#6221) @n0ctal
- [fix(node): don't stamp InboundsAdoptedAt when the sync adopted nothing](https://github.com/MHSanaei/3x-ui/commit/a255ab7c) (#6284) @yzxcj797
- [fix(nodes): log the inbound the node snapshot removes centrally](https://github.com/MHSanaei/3x-ui/commit/4b0e9f9b) (#6219) @n0ctal
- [fix(nodes): validate every certificate in the node mTLS trust bundle](https://github.com/MHSanaei/3x-ui/commit/bab39393) (#6188) @n0ctal
- [fix(nodes): apply a rotated master mTLS certificate without restarting the panel](https://github.com/MHSanaei/3x-ui/commit/7ecd88b9) (#6194) @n0ctal
- [fix(nodes): persist the master mTLS credential atomically and stop silent reissue](https://github.com/MHSanaei/3x-ui/commit/60453bf5) (#6195) @n0ctal
- [fix(nodes): report probe heartbeat persistence failures](https://github.com/MHSanaei/3x-ui/commit/4a5f6771) (#6207) @n0ctal
- [fix(clients): push bulk client changes to nodes only after the commit lands](https://github.com/MHSanaei/3x-ui/commit/c5dec64d) (#6181) @n0ctal
- [fix(clients): stop a stale IP row from blocking a client edit](https://github.com/MHSanaei/3x-ui/commit/2a8c3bc0)
- [fix(clients): stop recomputing the summary badges from the client_stats snapshot](https://github.com/MHSanaei/3x-ui/commit/ecadfd0e) (#6169) @mrnickson-hue
- [fix(traffic): clear cross-panel rows only for clients actually renewed](https://github.com/MHSanaei/3x-ui/commit/326009e9) (#6263) @n0ctal
- [fix(traffic): apply maintenance side effects only after the commit lands](https://github.com/MHSanaei/3x-ui/commit/13960050) (#6200) @n0ctal
- [fix(job): expire stored client IPs of offline clients](https://github.com/MHSanaei/3x-ui/commit/103b0dfe)
- [fix(job): force-disconnect over-limit Hysteria2 clients](https://github.com/MHSanaei/3x-ui/commit/d175050f)
- [fix(database): keep IP limits when the fail2ban probe is inconclusive](https://github.com/MHSanaei/3x-ui/commit/17fea2f6) (#6176) @n0ctal
- [fix(ldap): stop auto-delete from wiping every client on an empty directory](https://github.com/MHSanaei/3x-ui/commit/f4b7b08e)
- [fix(inbounds): close the port check-and-claim race on the serial writer](https://github.com/MHSanaei/3x-ui/commit/81cfd857) (#6225) @n0ctal
- [fix(inbounds): reject Hysteria inbound updates with empty client auth](https://github.com/MHSanaei/3x-ui/commit/585f4ecd) (#6268) @mvanhorn
- [fix(inbounds): surface form validation errors](https://github.com/MHSanaei/3x-ui/commit/3fa88adb) (#6084) @narcotics0507
- [fix(reality): make the REALITY target check usable on a private network](https://github.com/MHSanaei/3x-ui/commit/708a69ac) (#6242) @shustovTE
- [fix(groups): report changed bulk moves without restarting xray](https://github.com/MHSanaei/3x-ui/commit/0496c23a) (#6199) @n0ctal
- [fix(panel): stop one poisoned DNS answer from blocking outbound tests](https://github.com/MHSanaei/3x-ui/commit/2d30ab3a)
- [fix(outbounds): propagate allocation query failures](https://github.com/MHSanaei/3x-ui/commit/b70c5abc) (#6208) @n0ctal
- [fix(outbound): import Hysteria2 salamander properly from standard obfs params](https://github.com/MHSanaei/3x-ui/commit/d05e44e4) (#6166) @xMasterX
- [fix(warp): preserve WARP Plus license key when changing IP](https://github.com/MHSanaei/3x-ui/commit/5d6d98d1) (#6218) @rqzbeh
- [fix(warp): surface update-clock persistence failures](https://github.com/MHSanaei/3x-ui/commit/64f4f074) (#6209) @n0ctal
- [fix(netsafe): classify IPv6 transition and CGNAT ranges as internal](https://github.com/MHSanaei/3x-ui/commit/b51f0976)
- [fix(sub): keep Hysteria2 mport on external-proxy links](https://github.com/MHSanaei/3x-ui/commit/7a595cb4)
- [fix(sub): forward tlsSettings.cipherSuites into the JSON subscription](https://github.com/MHSanaei/3x-ui/commit/d9b599b9)
- [fix(sub): serve a copy-only page when a subscription URL is opened in a browser](https://github.com/MHSanaei/3x-ui/commit/43bc9153) (#6183) @n0ctal
- [fix(sub): restore the subscription info page for browser visits](https://github.com/MHSanaei/3x-ui/commit/f22df49a)
- [fix(sub): keep copy page within mobile viewport](https://github.com/MHSanaei/3x-ui/commit/338822ab)
- [fix(sub): render the full remark once per subscription, not once per credential](https://github.com/MHSanaei/3x-ui/commit/3b190915) (#6198) @n0ctal
- [fix(sub): use a fullwidth percent in USAGE_PERCENTAGE](https://github.com/MHSanaei/3x-ui/commit/ad32144c) (#6174) @n0ctal
- [fix(migration): stop a half-applied startup migration from committing silently](https://github.com/MHSanaei/3x-ui/commit/b56b0872) (#6182) @n0ctal
- [fix(db): harden unrestricted freedom outbounds](https://github.com/MHSanaei/3x-ui/commit/3bb87e80) (#6184) @n0ctal
- [fix(security): require a 2FA code to replace the stored TOTP secret](https://github.com/MHSanaei/3x-ui/commit/c8a3a2d7)
- [fix(cli): stop -getApiToken accumulating admin tokens](https://github.com/MHSanaei/3x-ui/commit/34c248bb) (#6175) @n0ctal
- [fix(web): fallback to default secret when database setting is empty](https://github.com/MHSanaei/3x-ui/commit/0f14ce75) (#6189) @CaMeDoZa
- [fix(web): report unexpected HTTP serve failures](https://github.com/MHSanaei/3x-ui/commit/20b3f84f) (#6210) @n0ctal
- [fix(frontend): make the jalali expiry clear button actually clear](https://github.com/MHSanaei/3x-ui/commit/b53a5515)
- [fix(frontend): refresh subscription settings after save](https://github.com/MHSanaei/3x-ui/commit/b73ceae0) (#6287) @dawNotPoi
- [fix(frontend): restore responsive table height](https://github.com/MHSanaei/3x-ui/commit/acbf09e7)
- [fix(frontend): disable table virtualization](https://github.com/MHSanaei/3x-ui/commit/03950b12)
- [fix(frontend): isolate swagger deps from main vendor chunk](https://github.com/MHSanaei/3x-ui/commit/8a8da885)
- [fix(frontend): restore the two rolldown bindings npm dropped from the lockfile](https://github.com/MHSanaei/3x-ui/commit/ce63bf3e)
- [fix(frontend): keep the MSW worker in step with the lockfile](https://github.com/MHSanaei/3x-ui/commit/f75ea08a) (#6222) @n0ctal
- [fix(install): preserve custom bin/ files (e.g. hand-added geoip) across updates](https://github.com/MHSanaei/3x-ui/commit/9165ab67) (#6152) @Kuzz007
- [fix(panel): forward the panel's proxy to update.sh's own downloads](https://github.com/MHSanaei/3x-ui/commit/94084249) (#6259) @Kuzz007
- [fix(tgbot): split long messages at line boundaries](https://github.com/MHSanaei/3x-ui/commit/f13baa9a) (#6293) @sanmaxdev
- [fix: dead code, typo, and minor bugs in main.go, process.go and index.go](https://github.com/MHSanaei/3x-ui/commit/31c1eed5) (#6167) @isuru709
- [fix: follow-ups from the post-merge reviews of #6221, #6227, #6230 and #6239](https://github.com/MHSanaei/3x-ui/commit/3f1dd4bf) (#6250) @n0ctal
<h3> Reports </h3>

## New Contributors
* @fastnas2023 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/5650
* @FZ1010 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/5698
* @narcotics0507 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6084
* @kobihikri made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6130
* @Kuzz007 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6152
* @xMasterX made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6166
* @isuru709 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6167
* @yelloduxx made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6168
* @CaMeDoZa made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6189
* @korsun009 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6190
* @nrps9909 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6202
* @rlex made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6216
* @hunmar made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6217
* @mrchatam made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6231
* @shustovTE made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6242
* @DIMFLIX made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6243
* @ZaneL1u made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6271
* @Masterain98 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6272
* @rokokol made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6282
* @yzxcj797 made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6284
* @dawNotPoi made their first contribution in https://github.com/MHSanaei/3x-ui/pull/6287
**Full Changelog**: https://github.com/MHSanaei/3x-ui/compare/v3.6.0...v3.7.0