Skip to content

v1.9.25

Latest

Choose a tag to compare

@github-actions github-actions released this 13 May 20:07
· 1 commit to main since this release

نصب MITM CA در LibreWolf (#1145, PR #1159 by @dazzling-no-more). کاربران LibreWolf با خطای MOZILLA_PKIX_ERROR_MITM_DETECTED روی سایت‌های HSTS-protected (bing.com، youtube.com، …) مواجه می‌شدن. علت: cert_installer.rs فقط Firefox profile rootها رو scan می‌کرد. LibreWolf یک Firefox fork است که همون NSS DB layout رو share می‌کنه ولی profile tree خودش رو زیر app dir خودش نگه می‌داره — هیچ‌کدوم از certutil -A per-profile install یا user.js enterprise-roots auto-trust fallback به LibreWolf نمی‌رسیدن. راه‌حل: firefox_profile_dirs()mozilla_family_profile_dirs() که هم Firefox هم LibreWolf paths رو per-OS برمی‌گردونه. هیچ تغییری برای کاربران Firefox. ۲۳۱ → ۲۳۹ lib test (+۸ regression برای LibreWolf path discovery). همان class از bug که قبلاً در #955 و #959 (Firefox-fork) closed شده بود.

رفع باگ Full mode «Google و اکثر سایت‌ها خراب، تلگرام سالم» — udpgw magic IP از داخل virtual-DNS range tun2proxy منتقل شد (#251 by @dazzling-no-more).

در Full mode روی Android، تلگرام کار می‌کرد ولی Google search و اکثر سایت‌ها silently fail می‌شدن — apps_script mode روی همون device سالم بود و VPS هم idle.

علت: آدرس magic مربوط به udpgw (یعنی 198.18.0.1:7300) داخل 198.18.0.0/15 بود، یعنی دقیقاً همون range‌ای که tun2proxy --dns virtual ازش IPهای ساختگی رو برای hostname lookupها اختصاص می‌ده. هر دفعه که virtual DNS اتفاقاً 198.18.0.1 رو به یک hostname مثل www.google.com allocate می‌کرد، traffic اون host به‌عنوان udpgw connection مصادره می‌شد و drop می‌شد. تلگرام immune بود چون native clientش از IPهای عددی hardcoded استفاده می‌کنه؛ همچنین apps_script mode هم immune بود چون اصلاً --udpgw-server ست نمی‌کنه.

راه‌حل: ثابت UDPGW_MAGIC_IP به 192.0.2.1 (RFC 5737 TEST-NET-1) منتقل شد. دو فایل تغییر کرده: یکی tunnel-node/src/udpgw.rs (constant + tests) و دیگری android/.../MhrvVpnService.kt (که حالا از یک companion const به اسم UDPGW_MAGIC_DEST استفاده می‌کنه).

سازگاری با نسخه‌های قدیمی: نسخهٔ جدید tunnel-node همچنان 198.18.0.1:7300 قدیمی رو هم accept می‌کنه برای یک deprecation cycle (حذف در v1.10.0) — یعنی اگه VPS رو زودتر آپدیت کنی، Android قدیمی هنوز کار می‌کنه. ولی اگه Android رو زودتر آپدیت کنی، tunnel-node قدیمی UDP relay رو در Full mode break می‌کنه. توصیه: اول tunnel-node رو آپدیت کن، بعد APK رو.

--- • **Install MITM CA into LibreWolf NSS stores** ([#1145](https://github.com//issues/1145), [PR #1159](https://github.com//pull/1159) by @dazzling-no-more). LibreWolf users were getting `MOZILLA_PKIX_ERROR_MITM_DETECTED` when visiting HSTS-protected sites (bing.com, youtube.com, …) through mhrv-rs's MITM mode. HSTS gives no "Add Exception" affordance, so users were fully locked out despite the OS-level CA install having succeeded.

Root cause: cert_installer.rs only scanned Firefox profile roots (~/.mozilla/firefox, the snap variant, %APPDATA%\Mozilla\Firefox\Profiles, ~/Library/Application Support/Firefox/Profiles). LibreWolf is a Firefox fork that shares Firefox's NSS DB layout and respects the same security.enterprise_roots.enabled pref, but stores its profile tree under its own app dir — neither the per-profile certutil -A install nor the user.js enterprise-roots auto-trust fallback ever touched LibreWolf. Same failure mode as already-closed #955 / #959 (Firefox-fork users).

Fix: extend Mozilla-family profile discovery to cover LibreWolf on every supported platform. firefox_profile_dirs()mozilla_family_profile_dirs() (returns union of Firefox + LibreWolf paths per-OS). Per-OS coverage:

  • Linux: ~/.mozilla/firefox, snap variant, ~/.librewolf, $XDG_CONFIG_HOME/librewolf.
  • macOS: ~/Library/Application Support/Firefox/Profiles, ~/Library/Application Support/LibreWolf/Profiles.
  • Windows: %APPDATA%\Mozilla\Firefox\Profiles, %APPDATA%\LibreWolf\Profiles.

No behavioural change for Firefox installs. 231 → 239 lib tests (+8 regression for LibreWolf path discovery on each OS).


Fix Full mode "Google + most websites broken while Telegram works" — udpgw magic IP moved out of tun2proxy virtual-DNS range (#251 by @dazzling-no-more). Users on Android Full mode reported that Telegram worked fine but Google search and most other websites failed to load — while apps_script mode on the same device + same google_ip worked perfectly and the VPS was sitting idle.

Root cause: the udpgw magic destination address (198.18.0.1:7300) lived inside 198.18.0.0/15 — the exact same range that tun2proxy's --dns virtual allocator uses to synthesise fake IPs for hostname lookups. Whenever virtual DNS happened to assign 198.18.0.1 to a real hostname (e.g. www.google.com), that hostname's connections were intercepted by tun2proxy itself as a udpgw request before they ever reached the SOCKS5 proxy. Result: a random subset of DNS-resolved hosts silently broke per session, depending on which hostname won the 198.18.0.1 allocation. Telegram was unaffected because its native client uses hardcoded numeric IPs (no DNS allocation needed). apps_script mode was unaffected because it doesn't pass --udpgw-server to tun2proxy at all.

Fix: relocate UDPGW_MAGIC_IP from 198.18.0.1 to 192.0.2.1 (RFC 5737 TEST-NET-1). TEST-NET-1 is reserved for documentation, never routed on the public internet, and — critically — outside any virtual-DNS allocation pool. Structurally equivalent to the old address as a "guaranteed-not-real-destination", just no longer colliding with tun2proxy's reserved range.

Coordinated two-side change:

  1. tunnel-node/src/udpgw.rs: UDPGW_MAGIC_IP = [192, 0, 2, 1], doc comment now cites RFC 5737 + explicitly explains why it must stay out of 198.18.0.0/15. Test additions: is_udpgw_dest_works covers both the new IP and the legacy IP (back-compat assertion); new magic_ip_outside_virtual_dns_range enforces the invariant at the 198.18.0.0/15 range level, so any future move to 198.19.x.y would also fail the test rather than re-introducing the same class of bug.
  2. android/.../MhrvVpnService.kt: --udpgw-server $UDPGW_MAGIC_DEST where UDPGW_MAGIC_DEST = "192.0.2.1:7300" is a new companion-object constant, with a docstring pointing back at the Rust constant — gives the next editor a single, labelled place to update if the convention ever changes again.

Back-compatibility — partial, one-way:

The udpgw magic IP is a wire-protocol convention between the Android client and the mhrv-tunnel Docker container. v1.9.25 tunnel-nodes accept both the new 192.0.2.1:7300 and the legacy 198.18.0.1:7300 for one deprecation cycle (slated for removal in v1.10.0). That softens — but does not fully resolve — the asymmetric-upgrade matrix:

Android Tunnel-node Full-mode UDP relay
v1.9.25 v1.9.25 ✅ fully fixed
≤v1.9.24 v1.9.25 ⚠️ udpgw handshake works (legacy IP still recognised by the node), but the old client still asks tun2proxy for --udpgw-server 198.18.0.1:7300 — meaning the underlying #251 virtual-DNS-pool collision is still live on the device. Telegram works; the random Google-search-style breakage persists until the APK is updated.
v1.9.25 ≤v1.9.24 breaks silently — new client sends 192.0.2.1, old node treats it as a real TCP destination and the connect fails
≤v1.9.24 ≤v1.9.24 unchanged from before (still has the original #251 bug)

Recommended upgrade order: update both halves to v1.9.25. The fix is on the client side (which magic IP it asks tun2proxy to reserve) — the tunnel-node back-compat shim only prevents a hard handshake break during the window where the node is upgraded first; it does not fix the original bug. If you can only update one half right now: do the APK first (or both together), since updating just the tunnel-node leaves clients still hitting the virtual-DNS collision. apps_script-only users are unaffected (the udpgw path isn't used in apps_script mode).

Diagnostic note for stuck users: if Telegram works on Full mode but Google search / random websites silently fail on v1.9.24 or earlier, this is your bug. As a workaround pending upgrade, add Google domains to passthrough_hosts to route them through tunnel-node like Telegram does:

{
  "passthrough_hosts": [".google.com", ".gstatic.com", ".googleusercontent.com", ".googleapis.com", ".youtube.com", ".ytimg.com"]
}

Slower per-request (Apps Script overhead) but bypasses the virtual-DNS clash entirely. Remove once both halves are on v1.9.25.

What's Changed

Full Changelog: v1.9.24...v1.9.25