Skip to content

Commit 707491c

Browse files
committed
release: 1.3.5 — DNS-leak protection, routing semantics tests, rollback fix
Headline fix — DNS dial protection on routing chain Burn-in on 192.168.1.4 (1256-node subscription) exposed a footgun: a user rule like "Port Range 0-65535 → proxy" also caught xray's own DNS-upstream dial (TCP/UDP to 8.8.8.8:53 etc.), tunnelling DNS resolution through the active VPN node. If the node had any handshake hiccup, the resolver died → everything else cascaded (API freeze, SOCKS5 down, TPROXY stuck). Three-layer defence (the SYSTEM RULE is the actual fix; the others are belt-and- suspenders): 1. dns.servers[].outboundTag = "direct" on every entry — pins resolved-IP routing to direct. 2. dns-out outbound proxySettings.tag = "direct" — chains the outbound through direct. 3. THE REAL FIX: system-level routing rule `port: 53 → direct` prepended ahead of any user rule. xray evaluates rules top-to-bottom; this catches the dial first and bypasses user-defined catch-all-to-proxy rules. Why not strip dangerous user rules: surgical rewrite is brittle and user-surprising. A system rule that always wins is robust, visible in the generated config, and works regardless of how the operator twists their routing. Live verified: with `port 0-65535 → proxy` ENABLED, DNS resolves normally, SOCKS5 + TPROXY traffic still flows through the VPN. UI — Routing page banner for non-rules modes Routing rules apply only in `mode=rules`. In `global` mode every connection is force-routed through the active node; in `bypass` every connection goes direct. User-defined rules are ignored. Without a visible warning, the operator could save a "Bypass local networks" rule in Global mode and have it silently no-op. New amber banner explains the gotcha + points to the "Bypass private CIDRs" toggle on Dashboard (the actual lever for LAN-direct in Global mode). Backend — pin routing semantics + device routing modes with tests Two new test groups (98/98 still passing on touched modules): * `TestModes` (5 new cases) — pins the `bypass_private` contract across all three modes (rules / global / bypass). Verifies the private-CIDR rule lands BEFORE the catch-all, covers RFC 1918 + loopback + link-local + IPv6 LL/ULA, and pins that `global` mode IGNORES user RoutingRules (the contract the banner relies on). * `tests/test_devices_routing_modes.py` (7 new cases) — covers `get_device_macs_for_mode`: `all` / `include_only` / `exclude_list` paths, empty-list edge cases, missing-setting fallback to `all`. Until now only the setting read/write was tested; the actual MAC-list population per mode had no coverage. * `TestDNS` (6 new cases) — DNS-pinning rule order, per-server outboundTag, dns-out proxySettings, fakedns sentinel preserved. Misc — POST /api/network/rollback works body-less Endpoint signature required `body: RollbackBody` so a POST with no body returned 422 ("Field required") despite the docstring promising "no body → newest backup". UI's Rollback button (which sends no body) hit this. Make body Optional in the FastAPI signature, fall through to None-id when omitted. TUN audit (no code change) Audited the dormant TUN/Both inbound-mode code paths across six files (~150 LOC). Nothing safe to remove — every site is wired defensively (rollback-on-validation, upgrade-path from older installs that may have inbound_mode=tun in DB). Keep as-is until sing-box-core enablement re-uses it. Stack - 5 commits since v1.3.4 - 98/98 focused backend tests pass; frontend build clean
1 parent 2b07775 commit 707491c

3 files changed

Lines changed: 4 additions & 4 deletions

File tree

backend/app/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# OpenAPI metadata, `/health` response, and `/system/status` so the
66
# frontend can display it next to the xray version. Bump this on each
77
# release — frontend keeps its own version in `frontend/package.json`.
8-
APP_VERSION = "1.3.4"
8+
APP_VERSION = "1.3.5"
99

1010

1111
class Settings(BaseSettings):

frontend/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "pitun-frontend",
33
"private": true,
4-
"version": "1.3.4",
4+
"version": "1.3.5",
55
"license": "BSD-3-Clause",
66
"type": "module",
77
"scripts": {

0 commit comments

Comments
 (0)