π 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=1orview=html.x-ui setting -getApiTokennow rotates a singlecli-fallbacktoken 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.
π New
- feat(amneziawg): add native AmneziaWG protocol support (#6105) @Kuzz007
- feat(pia): add PIA login-and-add WireGuard outbounds (#6272) @Masterain98
- feat(inbound): DisableFlow β opt an inbound out of auto XTLS Vision (#5698) @FZ1010
- feat(routing): add client picker to user rules (#6271) @ZaneL1u
- feat(xray): browse geosite/geoip categories from routing rules (#6165) @STRENCH0
- feat(routing): add remote routing URL support (#6168) @yelloduxx
- feat(clients): renew on a calendar day instead of a rolling interval (#6239) @n0ctal
- feat(clients): give each client its own traffic reset cycle (#6240) @n0ctal
- feat(clients): cap how many times a client may auto-renew (#6238) @n0ctal
- feat(clients): allow removing a single HWID device (#6265) @Kuzz007
- feat(sub): add per-client subscription HWID limits (#5802) @rqzbeh
- feat(clients): add per-client external link controls (#5650) @fastnas2023
- feat(limitip): let operators exempt trusted addresses from the IP limit (#6230) @n0ctal
- feat(sub): client-side balancers for the JSON subscription (#6243) @DIMFLIX
- feat(sub): add template variables to subscription metadata (#6163) @isultanov99
- feat(sub): expose last subscription fetch time (#6217) @hunmar
- feat(sub): warn when salamander settings cannot reach the client (#6177) @n0ctal
- feat(inbounds): add a narrow endpoint for subscription sort order (#6179) @n0ctal
- feat(api): scoped, optionally expiring API tokens (#6201) @n0ctal
- feat(nodes): opt-in encryption at rest for the outbound node API token (#6186) @n0ctal
- feat(frontend): multi-node cloning initial implementation (#6216) @rlex
- feat(inbounds): improve multi-node online attribution (#6164) @isultanov99
- feat(server): keep this machine's own settings when importing a database (#6227) @n0ctal
- feat(ui): let users pin the sidebar (#6161) @PathGao
- feat(web): add network-only PWA installability (#6190) @korsun009
- feat(i18n): translate the log levels, access events and calendar labels (#6226) @n0ctal
β‘ Update & improvement
- chore(build): bump Go toolchain to 1.27.0
- Move to TypeScript 7 and the oxc toolchain (oxlint + oxfmt) (#6262)
- chore(lint): adapt to staticcheck v0.8.0 under golangci-lint v2.13.1
- chore: bump dependencies and clear deprecated frontend APIs
- chore(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0 (#6162)
- chore(deps): bump github.com/klauspost/compress from 1.19.1 to 1.19.2 (#6212)
- chore(deps): bump dompurify (#6193)
- chore(deps-dev): bump postcss (#6173)
- chore(frontend): resolve the high-severity brace-expansion advisory (#6180) @n0ctal
- perf(clients): write client_inbounds deltas and check identity from the clients table
- perf(frontend): replace blank Suspense fallbacks with Spin, switch to matchMedia hook, add virtual table scrolling (#6187) @PathGao
- refactor(tgbot): share numeric keypad transitions (#6211) @n0ctal
- test(tgbot): detect open-coded keypad transitions (#6214) @n0ctal
- ci: attach provenance and SBOM attestations to the published images (#6130) @kobihikri
- ci(release): stamp released binaries with their source revision (#6223) @n0ctal
- ci: actually run the PostgreSQL schema and migration tests (#6224) @n0ctal
- refactor(ci): replace the in-house review lanes with the official code-review skill
- docs(api): document WireGuard and mtproto secret generation on clients/add (#6282) @rokokol
- chore(i18n): update tr-TR translations (#6288) @tarihcituranx
- fix(i18n): localize Chinese Xray labels (#6202) @nrps9909
π Bug fixed
- fix(node): stop the node sync from deleting clients it never meant to
- fix(node): stop stale expiry sync from undoing client extensions (#6231) @mrchatam
- fix(node): adopt a matching deployed inbound instead of recreating it (#6197) @n0ctal
- fix(node): keep disabled inbounds the node snapshot cannot report (#6221) @n0ctal
- fix(node): don't stamp InboundsAdoptedAt when the sync adopted nothing (#6284) @yzxcj797
- fix(nodes): log the inbound the node snapshot removes centrally (#6219) @n0ctal
- fix(nodes): validate every certificate in the node mTLS trust bundle (#6188) @n0ctal
- fix(nodes): apply a rotated master mTLS certificate without restarting the panel (#6194) @n0ctal
- fix(nodes): persist the master mTLS credential atomically and stop silent reissue (#6195) @n0ctal
- fix(nodes): report probe heartbeat persistence failures (#6207) @n0ctal
- fix(clients): push bulk client changes to nodes only after the commit lands (#6181) @n0ctal
- fix(clients): stop a stale IP row from blocking a client edit
- fix(clients): stop recomputing the summary badges from the client_stats snapshot (#6169) @mrnickson-hue
- fix(traffic): clear cross-panel rows only for clients actually renewed (#6263) @n0ctal
- fix(traffic): apply maintenance side effects only after the commit lands (#6200) @n0ctal
- fix(job): expire stored client IPs of offline clients
- fix(job): force-disconnect over-limit Hysteria2 clients
- fix(database): keep IP limits when the fail2ban probe is inconclusive (#6176) @n0ctal
- fix(ldap): stop auto-delete from wiping every client on an empty directory
- fix(inbounds): close the port check-and-claim race on the serial writer (#6225) @n0ctal
- fix(inbounds): reject Hysteria inbound updates with empty client auth (#6268) @mvanhorn
- fix(inbounds): surface form validation errors (#6084) @narcotics0507
- fix(reality): make the REALITY target check usable on a private network (#6242) @shustovTE
- fix(groups): report changed bulk moves without restarting xray (#6199) @n0ctal
- fix(panel): stop one poisoned DNS answer from blocking outbound tests
- fix(outbounds): propagate allocation query failures (#6208) @n0ctal
- fix(outbound): import Hysteria2 salamander properly from standard obfs params (#6166) @xMasterX
- fix(warp): preserve WARP Plus license key when changing IP (#6218) @rqzbeh
- fix(warp): surface update-clock persistence failures (#6209) @n0ctal
- fix(netsafe): classify IPv6 transition and CGNAT ranges as internal
- fix(sub): keep Hysteria2 mport on external-proxy links
- fix(sub): forward tlsSettings.cipherSuites into the JSON subscription
- fix(sub): serve a copy-only page when a subscription URL is opened in a browser (#6183) @n0ctal
- fix(sub): restore the subscription info page for browser visits
- fix(sub): keep copy page within mobile viewport
- fix(sub): render the full remark once per subscription, not once per credential (#6198) @n0ctal
- fix(sub): use a fullwidth percent in USAGE_PERCENTAGE (#6174) @n0ctal
- fix(migration): stop a half-applied startup migration from committing silently (#6182) @n0ctal
- fix(db): harden unrestricted freedom outbounds (#6184) @n0ctal
- fix(security): require a 2FA code to replace the stored TOTP secret
- fix(cli): stop -getApiToken accumulating admin tokens (#6175) @n0ctal
- fix(web): fallback to default secret when database setting is empty (#6189) @CaMeDoZa
- fix(web): report unexpected HTTP serve failures (#6210) @n0ctal
- fix(frontend): make the jalali expiry clear button actually clear
- fix(frontend): refresh subscription settings after save (#6287) @dawNotPoi
- fix(frontend): restore responsive table height
- fix(frontend): disable table virtualization
- fix(frontend): isolate swagger deps from main vendor chunk
- fix(frontend): restore the two rolldown bindings npm dropped from the lockfile
- fix(frontend): keep the MSW worker in step with the lockfile (#6222) @n0ctal
- fix(install): preserve custom bin/ files (e.g. hand-added geoip) across updates (#6152) @Kuzz007
- fix(panel): forward the panel's proxy to update.sh's own downloads (#6259) @Kuzz007
- fix(tgbot): split long messages at line boundaries (#6293) @sanmaxdev
- fix: dead code, typo, and minor bugs in main.go, process.go and index.go (#6167) @isuru709
- fix: follow-ups from the post-merge reviews of #6221, #6227, #6230 and #6239 (#6250) @n0ctal
Reports
New Contributors
- @fastnas2023 made their first contribution in #5650
- @FZ1010 made their first contribution in #5698
- @narcotics0507 made their first contribution in #6084
- @kobihikri made their first contribution in #6130
- @Kuzz007 made their first contribution in #6152
- @xMasterX made their first contribution in #6166
- @isuru709 made their first contribution in #6167
- @yelloduxx made their first contribution in #6168
- @CaMeDoZa made their first contribution in #6189
- @korsun009 made their first contribution in #6190
- @nrps9909 made their first contribution in #6202
- @rlex made their first contribution in #6216
- @hunmar made their first contribution in #6217
- @mrchatam made their first contribution in #6231
- @shustovTE made their first contribution in #6242
- @DIMFLIX made their first contribution in #6243
- @ZaneL1u made their first contribution in #6271
- @Masterain98 made their first contribution in #6272
- @rokokol made their first contribution in #6282
- @yzxcj797 made their first contribution in #6284
- @dawNotPoi made their first contribution in #6287
Full Changelog: v3.6.0...v3.7.0