๐ Multi-Node Hardening, Notification Event Bus, Managed Hosts & Scale to 100k Clients
- ๐ฐ๏ธ Per-node outbound routing & node hardening โ route each node through its own outbound, plus mTLS, hashed + zstd reconcile transport, and per-node network metrics.
- ๐ Notification event bus โ a pub/sub architecture with Telegram and SMTP subscribers, a card-based notification settings layout, and memory-threshold alerts.
- ๐ Managed Hosts โ per-host overrides for subscription links so each host can advertise its own address.
- ๐งพ Subscription engine upgrades โ dynamic remark variables (Jalali date, transport, status tokens), full XHTTP mapping for Clash/Mihomo, per-client external links + remote subscriptions, and an option to hide server settings (happ).
- ๐ Scale & stability to 50kโ100k clients โ faster traffic/auto-renew/node bulk ops, DB indexes on hot columns, atomic config writes, panic-recovering cron/jobs, and bounded gRPC deadlines & response sizes.
- ๐ก๏ธ fail2ban-native IP limiting โ IP limit is now gated on fail2ban (auto-installed on install/update) and reads onlines without parsing
access.log. - ๐ Native TLS/REALITY pinning โ remote cert pinning via a native uTLS handshake (no xray subprocess), ported xray TLS/REALITY fields, and cert-hash helpers.
- ๐ฏ Real client IP behind CDN/relay โ capture the visitor IP behind a CDN/relay and attribute IP-limit per node.
- ๐งฌ Xray-core v26.6.22 โ core upgrade with XHTTP
sessionIDtable/length controls, WireGuard field cleanup, andtrustedXForwardedForhonored on gRPC inbounds. - ๐ ๏ธ Deployment pipeline & test-quality audit โ release-driven golden-image & unattended-install pipeline, plus a test-quality pass adding mutation/fuzz/CI tooling.
โน๏ธ Heads-up: IP limiting now relies on fail2ban, which is auto-installed on install/update, and no longer parses
access.log. LegacypanelProxy/tgBotProxysettings are cleared automatically on upgrade. If you previously tuned IP limiting or those proxy settings, review them after upgrading.
๐ New
- feat(node): per node outbound routing (#5275) @NikanZeyaei
- feat(node): node hardening โ mTLS, hashed+zstd reconcile transport, per-node net metrics (#5382)
- feat(notifications): event bus architecture with Telegram and SMTP subscribers (#5326) @Ssentiago
- feat: replace notification checkboxes with card-based layout (#5421) @Ssentiago
- feat(memory): add memory threshold alerts (#5366) @Ssentiago
- feat(hosts): managed Hosts for per-host subscription link overrides (#5409)
- feat(nodes): per-node client IP attribution for IP-limit
- feat(inbounds): add Real client IP presets to capture visitor IP behind CDN/relay
- feat(sub): per-client external links and remote subscriptions
- feat(sub): add dynamic remark variables with Jalali date, transport, and status tokens (#5430) @wahh3b-lgtm
- feat(sub): full XHTTP field mapping for Clash/Mihomo subscriptions (#5417) @w3struk
- feat(sub): add option to hide server settings in subscription (happ) (#5433) @IgorKha
- feat(tls,reality): port xray TLS/REALITY fields, cert-hash helpers, fallback UX
- feat(finalmask): support Salamander packetSize (Gecko) and Realm tlsConfig for Hysteria2 (#5278) @rqzbeh
- feat(xray): add loopback sniffing and per-segment fragment masks
- feat(xray): preview export in a modal and switch rule enable toggle
- feat(xhttp): support sessionID* rename + sessionIDTable/Length (xray v26.6.22) (#5506) @rqzbeh
- Add Enable/Disable Toggle for Xray Routing Rules (#5296) @abdalrahmanx9
- feat(iplimit): gate IP limit on fail2ban and reset stale limits
- feat(iplimit): auto-install fail2ban on install and update
- feat(ui): show per-inbound live speed (#5261) @NikanZeyaei
- feat(metrics): extend history bucket options to include 12h, 24h, and 48h intervals (#5467) @shazzreab
- feat(sidebar): move Routing/Outbounds to top-level items with clean URLs
- feat(clients): orphan cleanup + export/import via CodeMirror modals
- feat(backup): name DB backup files after the server address
- feat(backup): prefer browser request host for backup filename
- feat(web): cap request body size on state-changing routes (#5271) @n0ctal
- feat(docker): support XUI_PORT runtime override (#5240) @surfdps
- feat: release-driven golden-image & unattended-install deployment pipeline (#5323)
โก Update & improvement
- Update Xray to v26.6.22
- perf(scale): speed up traffic, auto-renew, and node bulk ops at 50k-100k clients
- perf: prevent cron job overlap, auto-set GOMEMLIMIT, fix tgbot userStates race
- perf(settings): save all settings in one transaction
- perf(db): index group_name and client_traffics hot columns (#5268) @n0ctal
- perf(db): add an index on settings.key (#5359) @n0ctal
- perf(xray): compile log/traffic regexps once at package scope (#5362) @n0ctal
- chore(db): use DELETE journal mode so sqlite stays a single file
- refactor(web): centralize background job cadences (#5269) @n0ctal
- refactor(job): drop access log from IP limiting, wipe it daily instead
- refactor(frontend): stack client credential fields and use label hints on inbound form
- refactor(frontend): move form-item hints from extra to tooltip
- refactor(wireguard): drop removed workers field (xray v26.6.22) (#5509) @rqzbeh
- Use efficient APIs and simplify loops
- Frontend operation button size optimization (#5343) @tonymoses10
- Test-quality audit: fix 2 prod bugs, strengthen weak tests, add mutation/fuzz/CI tooling (#5345)
- chore(deps): bump frontend deps and override js-yaml to patch DoS advisory
- Bump frontend package & deps to new patch versions
- chore(deps): bump telego to v1.10.0
- chore: bump dompurify to 3.4.11 and expand VS Code tasks
- chore(deps): bump aws-actions/configure-aws-credentials from 4 to 6 (#5426)
- chore(deps): bump react-router-dom from 7.17.0 to 7.18.0 in /frontend (#5428)
- chore(deps): bump actions/upload-artifact from 4 to 7 (#5427)
- chore(deps): bump actions/checkout from 6 to 7 (#5454)
- i18n: sync 12 locales with en-US โ add missing Hosts/subscription keys
- Update zh-CN.json (#5459) @qin9125
- feat(ci): add PR review job and commit-capable mention bot
- feat(ci): let mention bot push commits to fork PR branches
- fix(ci): check out PR branch for mention bot so commits land on the PR
- fix(ci): use pull_request_target so claude bot gets secrets on fork PRs
- ci(claude-bot): tune models, Copilot-style PR review, issue research mode
- ci(smoke): set least-privilege GITHUB_TOKEN permissions
- ci(smoke): retry transient GitHub download failures
- ci: use .nvmrc for setup-node version in codeql/release workflows
๐ Bug fixed
- fix(security): confine GetCertHash to known cert files (CWE-22)
- fix(sub): deliver vision flow for VLESS+XHTTP+REALITY in share links and Clash (#5232)
- fix(sub): stop appending the node name to subscription remarks (#5231)
- fix(sub): emit Shadowsocks http-header links as SIP002 obfs-local plugin
- fix(sub): wrap JSON-subscription SS/Trojan outbound in servers[] array
- fix(sub): emit JSON-subscription pinnedPeerCertSha256 as comma-separated string
- fix(sub): {{INBOUND}} = inbound remark, fix {{TRAFFIC_LEFT}} across inbounds (#5443)
- fix(sub): re-add xhttp mode to extra JSON for Karing (#5446)
- fix(sub): add missing :// in Shadowrocket subscription deep link (#3945)
- fix(sub): SS2022 share links must not base64-encode userinfo (#5432)
- fix(sub): preserve non-default scMinPostsIntervalMs and use per-inbound xmux in JSON subscriptions (#5393) @w3struk
- fix(sub): set read/write/idle timeouts on the subscription server (#5360) @n0ctal
- fix(sub): error instead of silently truncating oversized subscription (#5495) @n0ctal
- fix(subscription): bound outbound response body (#5493) @n0ctal
- fix(subscriptions): avoid shared mutable state during generation (#5270) @n0ctal
- fix(links): bracket ipv6 hosts in share links and qr codes (#5310) @NikanZeyaei
- fix(nodes): honor TLS verify mode skip/pin for remote node operations (#5264)
- fix(nodes): propagate single-client deletion to remote nodes (#5352)
- fix(nodes): stop multi-attached client traffic inflating across node inbounds
- fix(nodes): route 'load inbounds' through the connection outbound
- fix(ui): match node connection-outbound picker to panel-outbound selector
- fix(nodes): sync "start after first connect" expiry so un-activated nodes do not reset it (#5319) @rqzbeh
- fix(nodes): strip central n- tag prefix when pushing inbounds to remote (#5399) @aleskxyz
- fix(nodes): block node delete while inbounds are still attached (#5394) @n0ctal
- fix(node): mark node dirty on Update so sync reconciles before snapshot sweep (#5469) @NikanZeyaei
- fix(nodes): cloned-node attribution, node-hosted client display (online/speed/counts), and sync robustness (#5488)
- fix(node-sync): give client-IP sync its own deadline; fix log spacing
- fix(traffic): prevent phantom quota consumption from stale node data (#5412) @younesvatan78
- fix(xray): guard process lifecycle fields against concurrent access (#5395) @n0ctal
- fix(xray): verify the release archive checksum before installing (#5396) @n0ctal
- fix(xray): guard log-writer race and bound handler gRPC deadlines (#5442) @n0ctal
- fix(xray): write generated config atomically (#5494) @n0ctal
- fix(web): recover panicking cron jobs instead of crashing the panel (#5363) @n0ctal
- fix(jobs): isolate per-node background goroutines from panics (#5397) @n0ctal
- fix(runtime): cap remote node response size to bound master memory (#5361) @n0ctal
- fix(service): serialize client/inbound writes to prevent Postgres deadlock
- fix(deps): bump xray-core past finalmask UDP buffer fix (#5462)
- fix(sockopt): honor trustedXForwardedFor on gRPC inbounds (xray v26.6.22) (#5503) @rqzbeh
- fix(tls): pin remote cert via native uTLS handshake instead of xray subprocess
- fix(tls): ping the inbound's own port for remote cert pinning
- fix(tls): default OCSP stapling to off for new inbound certs
- fix(inbound): strip XHTTP client-only fields from xray config, keep for subscriptions (#5349) @nima1024m
- fix(inbounds): flag conflicts with the reserved Xray API port (#5304)
- fix(inbound): regenerate SS-2022 client PSKs on method key-size change
- fix(inbound): persist streamSettings for tunnel so sockopt saves
- fix(reality): load
destastargetalias so existing inbounds aren't wiped (#5295) @volov-de - fix(routing): sync xray rules when panel inbound tags change or are deleted (#5367) @nima1024m
- fix(outbounds): test subscriptions in Test All, skip direct/dns
- fix(outbound): parse xmux from imported share links (#5353)
- fix(outbound): preserve non-ASCII characters in imported subscription tags (#5354)
- fix(clients): centre the online dot inside the Online tag (#5238)
- fix(clients): keep the client list live with a background poll (#5262)
- fix(client): clear group when removed in the single-client editor
- fix(frontend): TProxy schema, VLESS+XHTTP flow links, clearable Jalali date picker (#5339, #5322, #5313)
- fix(frontend): guard IntlUtil.formatDate against out-of-range timestamps (#5468) @NikanZeyaei
- fix(api-docs): exclude /panel/outbound and /panel/routing from route guard
- fix(tgbot): clear legacy panelProxy/tgBotProxy settings on upgrade
- fix(tgbot): dedupe exhausted-client report by email (#5453)
- fix(settings): rename remark model 'Other' to 'External Proxy' (#5265)
- fix(iplimit): ban UDP as well as TCP in fail2ban action (#5350)
- fix(script): report per-file geo update status and skip restart when nothing changed
- fix(cli): apply -webCert/-webCertKey on the setting subcommand (#5482) @Taov-Russo
- fix(install): support IPv6-only hosts (#5487) @m4tinbeigi-official
- fix: resolve a batch of open bug-tagged issues (traffic accounting, share strategy, sub address, CPU) (#5477)
Reports
New Contributors
- @surfdps made their first contribution in #5240
- @n0ctal made their first contribution in #5269
- @volov-de made their first contribution in #5295
- @tonymoses10 made their first contribution in #5343
- @Ssentiago made their first contribution in #5326
- @IgorKha made their first contribution in #5433
- @wahh3b-lgtm made their first contribution in #5430
- @qin9125 made their first contribution in #5459
- @Taov-Russo made their first contribution in #5482
- @m4tinbeigi-official made their first contribution in #5487
Full Changelog: v3.3.1...v3.4.0