Skip to content

Xrayebator v0.7.2

Choose a tag to compare

@Ap3x0s Ap3x0s released this 04 Nov 01:02
· 18 commits to main since this release
289ec76

Xrayebator v0.7.2 — Xray-core 26.10.31, CVE-2026-98432 hardening and the domainStrategy move

An update of the server manager and of the Xrayebator Desktop GUI. Installs over 0.7.1 and any 0.6.x — the migrations finish the job themselves. Found a problem or have logs? Comment on the release: logs are the fastest way to a fix.

Changes since 0.7.1

19 commits since the 0.7.1 tag, 13 of them in this cycle; the rest are the previous cycle's documentation (choosing a VPS, a domain and DNS, plus a week of stability observations) that had not been released yet.

Two independent reasons to update: Xray-core moved to 26.10.31, an urgent security release, and the manager now closes both surfaces of the Linux kernel vulnerability it actually controls.

  • kernel-guard — a new command (and menu item 16): disables MPTCP in the kernel and drops inbound IPv4 packets carrying IP options. Hardening against CVE-2026-98432, a Linux kernel remote-root with a CVSS of 9.8.
  • MPTCP is off by default via migration netguard_mptcp_2026: the same thing Xray-core did inside the listener, but at the server level — and for every Go service, not only Xray.
  • freedom.domainStrategy moved to sockopt: 26.10.31 marks the old field deprecated and «will be removed», while the core updates itself. Migration freedom_sockopt_2026 moves the value on existing servers.
  • The kernel-guard rule no longer duplicates itself — the bug surfaced on a live server at the very first enable.
  • The legacy installer is pinned to 26.10.31 (it was 26.7.28 — a core that still enables MPTCP in the listener).
  • A VPS/domain/DNS guide in docs/recommendations.md (ru/en/zh): selection criteria without brands or affiliate links, getting a domain, Cloudflare and Route 53 step by step, and a resource table built from real measurements.

In two words

On 31 October Xray-core shipped an urgent update: a use-after-free in IPv4 option processing was found in the Linux kernel, and through an MPTCP listener a server could be rooted remotely, without a password. Go 1.24+ enables MPTCP by default — which means Xray enabled it too. 26.10.31 turns MPTCP off in the listener; this release also disables MPTCP in the kernel and drops IPv4 packets that carry options — exactly the code path with the bug.

The boundary matters: this is not a replacement for a kernel update. Every IPv4 TCP listener is affected (Xray, nginx, sshd), and the real fix only arrives as a kernel package. As of 2 November 2026 the Ubuntu fixes sat in -proposed (jammy 5.15.0-203.213, noble 6.8.0-149.149) with nothing in -updates yet, so compare uname -r against the current advisory yourself.

The second half of the release is technical: the new core complained at every start about our own freedom.domainStrategy field («deprecated and will be removed»). Waiting for the removal is not an option — the core updates itself through xrayebator update, and once the field is gone domains would resolve differently (on an IPv6-only server the traffic would simply stop). The value now lives in streamSettings.sockopt; the old form survives only inside the migration.

What is new

1. kernel-guard — kernel hardening against CVE-2026-98432

sudo xrayebator kernel-guard --status    # facts as JSON
sudo xrayebator kernel-guard --enable    # MPTCP off + drop IPv4 packets with IP options
sudo xrayebator kernel-guard --disable   # revert both

What --enable does:

  1. MPTCP is disabled in the kernel — net.mptcp.enabled = 0 in /etc/sysctl.d/99-xrayebator-netguard.conf. Nothing in this stack uses MPTCP: VLESS/Reality is TCP, Hysteria 2 and AmneziaWG are UDP.
  2. Inbound IPv4 TCP packets carrying IP options are dropped (IHL > 5) — Ubuntu Security Team's rule verbatim, in a dedicated nftables table cve_2026_98432 at priority -310 (before the UFW filter hook) with its own boot unit xrayebator-netguard.service.

Why a dedicated table instead of nftables.service: the stock /etc/nftables.conf on Debian/Ubuntu starts with flush ruleset, and enabling it would wipe the whole UFW ruleset at boot. Our unit loads only its own table and never flushes — neither on start nor on stop.

--status reports the running kernel, newer_kernel_installed (a newer kernel is installed but not booted), reboot_required, mptcp_supported/mptcp_enabled, ipv4_options_drop, the Xray-core version and xray_mptcp_safe (≥ 26.10.31). There is deliberately no hard-coded «fixed in kernel version X» table: it goes stale faster than it helps.

If nft is missing (happens on minimal images: UFW is present but the nftables package is not), the command disables MPTCP and honestly reports partial: true — install the package and run it again, it is idempotent.

2. MPTCP is off by default

On already-deployed servers the migration netguard_mptcp_2026 applies net.mptcp.enabled = 0 on the first run of the menu, quickstart or happ-setup. It does not touch config.json, so it reports «no-op» and does not restart the Xray core — a restart here would be a regression, not caution.

The IPv4-option drop stays an explicit operator decision: it changes which packets the server accepts at all.

What is fixed

1. freedom.domainStrategy → streamSettings.sockopt.domainStrategy

26.10.31 prints this on every start:

The "freedom.domainStrategy" setting is deprecated and will be removed.
For compatibility, its value has been automatically migrated to "sockopt.domainStrategy".

On 26.3.27 (what production was running) there is no such warning, so the behaviour changed in this very update. install.sh now writes the new form directly, and migration freedom_sockopt_2026 moves the value on existing servers and deletes the legacy key. An explicit sockopt value is never overwritten; when there is no legacy field the migration stays silent and leaves the core alone.

2. The kernel-guard rule duplicated itself when the unit was activated

Live finding on a fresh install: after kernel-guard --enable the nft chain held two identical drop rules. Cause: nft -f of a file containing table inet X { ... } does not replace the table, it appends the rule to the existing one, and systemctl enable --now starts the unit, which loads the same file a second time. The extra drop is harmless (the first already dropped the packet), but the chain would grow with every activation.

ExecStartPre/ExecReload now delete our table first (-nft delete table inet cve_2026_98432), and the validation demands that line. Verified live: three enables in a row leave exactly one rule, and after a reboot there is still one.

3. The legacy installer shipped a vulnerable core

gui-legacy (the archival PySide6 interface) deploys a server-side core from a pinned version and was installing v26.7.28 — a core that still enables MPTCP in DefaultListener. The pin is now 26.10.31, with SHA-256 of both assets verified against the release .dgst files and against the files we actually downloaded.

What this is not

  • Not a Linux kernel update. Dropping IPv4 options narrows the attack surface; it does not replace the patch. The kernel package is a normal apt install followed by a reboot.
  • Not «completely safe». Ubuntu's rule removes the easiest exploitation path; the race in TCP processing remains in the kernel until it is updated.
  • Not a GUI feature. kernel-guard lives in the CLI and in menu item 16, like the Telegram alerts: the desktop app has no card for it.
  • Not a pinned core version. The manager still installs the latest GitHub release; you do not have to pick 26.10.31 by hand, you only need the server to run that version or newer (check xrayebator kernel-guard --status → xray_mptcp_safe).

How well this is verified

  • 47 Bash validations in validation/, two of them new (test-kernel-guard.sh, test-freedom-sockopt.sh), plus an updated test-main-menu-numbering.sh (item 16). In CI on ubuntu-24.04 the whole set is green on both dev and main.
  • 174 unit tests and a clean npm run typecheck (0 errors). On Windows 173 are green — the single red is the known shell-command case without /bin/sh, which was already red in 0.7.1; the renderer did not change in this cycle.
  • The config was validated against two Xray cores. A config in our shape (Reality+vision, xhttp, grpc, tcp-mux, PQ VLESS Encryption, api/stats, policy, routing, dns) fed to xray run -test answers Configuration OK on both 26.3.27 and 26.10.31. The only difference in the output is the freedom.domainStrategy warning, which the new form no longer triggers. Separately re-checked: a temp config without the .json extension is still refused (unsupported config file extension), so the 0.7.1 fix is still needed.
  • SHA-256 of the release assets Xray-linux-64.zip and Xray-linux-arm64-v8a.zip matched the .dgst files, so the installer downloads the same bytes we tested.
  • Live run on a clean Ubuntu 22.04 (1 vCPU / 1 GB VPS):
    • a fresh install.sh from the main branch → Xray 26.10.31, an IP subscription with a real Let's Encrypt certificate (ip_tls), 7 routes;
    • channel-test — 7/7 twice in a row, 7/7 after a reboot and 7/7 after every operation below (132–252 ms, the PQ route 219–242 ms);
    • all four subscription bodies — 200 (HAPP 4909 B / 7 vless, base64 2624 B, Clash 3433 B, sing-box 4628 B), subscription-userinfo with real traffic;
    • Hysteria 2: install, grant to a profile, unit active, UDP 443 listening, certificate taken from the LE issuance — plus an end-to-end test with a real client: the tunnel came up, a request through it returned 200 in 132 ms, and the server journal shows client connected {id: "happ"};
    • AmneziaWG: DKMS built on the spot (headers were pulled in, no reboot needed), module loaded, awg0 up, peer issued — plus an end-to-end test: a client interface next to the server, latest handshake on both sides, ping 3/3;
    • kernel-guard: enabling without nft yields partial: true and disables MPTCP; after installing nftables it fully succeeds with exactly one rule in the chain; --disable restores MPTCP=1 and cleans up; after a reboot there is again one rule, MPTCP=0 from sysctl.d, and every unit came up on its own;
    • operations: profile-pq (a second inbound), sni-change/fp-change/port-change with --route N, profile-revoke --full, a traffic limit (the subscription answers 410, and 200 again once the limit is cleared, with the clients restored), profile-delete (cleans the config, the firewall and the listening port), backend-start after a stopped AWG;
    • certificate renewal: a real certbot renew --force-renewal succeeded, the deploy hook restarted Hysteria 2 and reloaded nginx, and the serial number matched on all three sides (LE, the backend directory, what TLS serves).
  • What could not be checked. There was no live run on Ubuntu 24.04 or Debian 12 in this cycle — only on Ubuntu 22.04. The HAPP subscription body and AmneziaWG were exercised with our own clients (hysteria client, awg-quick), not with the official HAPP/AmneziaVPN apps: junk-parameter dialect compatibility with them stays out of scope for this cycle.

Before you upgrade

Server requirements

Unchanged: Debian 12/13 or Ubuntu 22.04/24.04, bash, root/sudo, systemd, apt. The IPv4-option drop needs nft (the nftables package; without it --enable says so and enables MPTCP only).

Worth knowing

  • No breaking changes. Ports, profiles, subscriptions and the Hysteria 2/AmneziaWG passwords are untouched.
  • The Xray core restarts once after the update (as any xrayebator update does) — active clients reconnect on their own.
  • On an existing server the kernel protection most likely has to be enabled by hand: MPTCP is disabled by the migration, the IPv4-option drop is sudo xrayebator kernel-guard --enable or menu item 16.
  • --route in sni-change/fp-change/port-change is a zero-based route index, not a label. On a multi-route profile the command refuses without it and tells you so.
  • Updating a server from the dev branch with xrayebator update keeps the branch at dev; for stable use xrayebator update main.

How to upgrade

Server

sudo xrayebator-update          # full project lifecycle
# or the manager + Xray-core only:
sudo xrayebator update
# and, once, the kernel protection if you want it:
sudo xrayebator kernel-guard --enable

Xrayebator Desktop GUI

Download the installer from the release assets and install it over the current one — data and server settings are preserved.

Build

Produced by the same workflow: Ubuntu (AppImage), macOS arm64 (dmg + zip), Windows (exe). Typecheck, unit tests and all 47 Bash validations run before the build.

Links