# برنامهٔ اندروید mhrv-rs
راهنمای کامل نصب و راهاندازی برنامهٔ اندروید: نصب، تنظیمات اولیه، رفع اشکال و محدودیتهای شناختهشده.
- [معرفی کلی](#معرفی-کلی)
- [پیشنیازها](#پیشنیازها)
- [۱. نصب APK](#۱-نصب-apk)
- [۲. ساخت Apps Script](#۲-ساخت-apps-script)
- [۳. وارد کردن تنظیمات در برنامه](#۳-وارد-کردن-تنظیمات-در-برنامه)
- [۴. تست SNI](#۴-تست-sni)
- [۵. نصب گواهی MITM](#۵-نصب-گواهی-mitm)
- [۶. اجرای تونل](#۶-اجرای-تونل)
- [راهنمای سریع رابط کاربری](#راهنمای-سریع-رابط-کاربری)
- [محدودیتهای شناختهشده](#محدودیتهای-شناختهشده)
- [رفع اشکال](#رفع-اشکال)
- [حذف برنامه](#حذف-برنامه)
---
## معرفی کلی
برنامهٔ اندروید همان کرت `Rust` پشت نسخهٔ دسکتاپ است که در قالب یک رابط `Compose` بستهبندی شده و از طریق `VpnService` و [`tun2proxy`](https://crates.io/crates/tun2proxy) تمام ترافیک `TUN` دستگاه را به پروکسی میسپارد. همهٔ برنامههای روی گوشی بهطور خودکار از پروکسی رد میشوند — بدون نیاز به تنظیم per-app.
```
هر برنامه روی دستگاه
│
▼
VpnService TUN ──► tun2proxy (داخل فرایند)
│
▼
SOCKS5 محلی ──► dispatcher در mhrv-rs
│
┌─────────────────┤
▼ ▼
تونل sni-rewrite رلهٔ Apps Script
(دامنههای گوگل (هر چیز دیگر، از
مستقیم به google_ip) طریق /exec شما)
```
زمان راهاندازی: **حدود ۱۰ دقیقه** اگر `Apps Script` را قبلاً `deploy` کردهاید، ۱۵ دقیقه اگر از صفر شروع میکنید.
---
## پیشنیازها
| | |
|---|---|
| **نسخهٔ اندروید** | ۷.۰ (`API 24`) یا بالاتر |
| **معماری دستگاه** | هر کدام. APK جهانی است: `arm64-v8a`، `armeabi-v7a`، `x86_64`، `x86` |
| **حساب گوگل** | بله — `Apps Script` را زیر آن منتشر میکنید. یک `Gmail` یکبارمصرف کافی است |
| **قفل صفحه** | PIN، الگو، رمز، یا بیومتریک + `fallback`. **الزام اندروید برای نصب گواهی کاربری است.** بعد از نصب میتوانید برش دارید؛ گواهی معتبر باقی میماند |
| **مصرف داده** | حدود ۵ مگابایت برای APK، سپس حدود ۲ مگابایت سربار به ازای هر گیگابایت مرور وب (`base64` و بستهبندی `JSON`) |
> **نکتهٔ دامنهٔ کار.** `mhrv-rs` از طریق `Apps Script` رله میکند. همین است که ابزار را ارزان و در برابر `DPI` مقاوم میسازد، ولی همین هم [محدودیتهای بخش پایین](#محدودیتهای-شناختهشده) را تحمیل میکند. اگر میخواهید با یک `VPN` واقعی (`WireGuard`/`Tailscale`/`OpenVPN`) مقایسه کنید، اول آن بخش را بخوانید.
---
## ۱. نصب APK
۱. در مرورگر گوشی به بروید.
۲. فایل `mhrv-rs-android-universal-v*.apk` را دانلود کنید.
۳. روی نوتیفیکیشن دانلود ضربه بزنید تا `installer` باز شود.
۴. وقتی اندروید پرسید **«Allow this source to install apps?»**:
- روی **Settings** بزنید
- **Allow from this source** را روشن کنید
- **← Back** → **Install**
۵. بعد از اتمام نصب روی **Open** بزنید.
> اگر اندروید با پیام «App not installed» رد کرد: نسخهٔ قدیمی با کلید امضای متفاوتی نصب است. `Settings → Apps → mhrv-rs → Uninstall` بزنید و دوباره امتحان کنید. (از v1.0.2 به بعد این یکباره است — بهروزرسانیها با کلید ثابت امضا میشوند.)
---
## ۲. ساخت Apps Script
اگر قبلاً یک `/exec URL` فعال دارید، این مرحله را رد کنید.
این مرحله را روی لپتاپ انجام دهید — کار با مرورگر روی گوشی دردناک است.
۱. به بروید → **New project**.
۲. محتوای کامل [`assets/apps_script/Code.gs`](../assets/apps_script/Code.gs) از همین ریپو را کپی کنید.
۳. در ویرایشگر `Script`، کد پیشفرض `function myFunction() {}` را انتخاب و جایگزین کنید.
۴. خط زیر را نزدیک بالا پیدا کنید:
```js
const AUTH_KEY = "CHANGE_ME_TO_A_STRONG_SECRET";
```
مقدار `placeholder` را با یک رشتهٔ تصادفی قوی (حداقل ۲۰ کاراکتر حروف + رقم) جایگزین کنید. این مقدار را جایی ذخیره کنید — در برنامه هم همین را میخواهید.
۵. ذخیره کنید (⌘S / Ctrl+S). نام پروژه را چیزی مثل `mhrv-relay` بگذارید.
۶. **Deploy → New deployment**.
۷. روی آیکون چرخدنده بزنید → **Web app**. این فیلدها را پر کنید:
| فیلد | مقدار |
|---|---|
| Description | `mhrv-relay v1` (یا هر چیزی) |
| Execute as | **Me** |
| Who has access | **Anyone** |
۸. **Deploy** را بزنید. بار اول گوگل دسترسی میخواهد:
- **Authorize access** → حسابتان را انتخاب
- در صفحهٔ «Google hasn't verified this app» → **Advanced** → **Go to <project name> (unsafe)** → **Allow**
۹. **Web app URL** را کپی کنید. به شکل `https://script.google.com/macros/s/AKfyc.../exec` است.
اسکریپت دقیقاً چه میکند؟
درخواست `POST { method, url, headers, body_base64 }` را از پروکسی ما دریافت میکند، داخل دیتاسنتر گوگل `UrlFetchApp.fetch(url, ...)` را اجرا میکند، و `{ status, headers, body_base64 }` را برمیگرداند. عبور از `DPI` به این دلیل کار میکند که ما به `script.google.com` با `SNI` متفاوت از `Host` هدر متصل میشویم — ISP میبیند `www.google.com` ولی `Google edge` بر اساس `Host` هدر داخل `TLS` مسیر را تعیین میکند.
---
## ۳. وارد کردن تنظیمات در برنامه
برگردید به گوشی:
| فیلد | مقدار |
|---|---|
| **Deployment URL(s) or script ID(s)** | همان `/exec URL` که کپی کردید. میتوانید چند تا بگذارید — یکی در هر خط — تا `round-robin` چرخانده شوند (وقتی به سقف روزانهٔ `20k` هر اسکریپت خوردید مفید است) |
| **auth_key** | دقیقاً همان رشتهای که در `AUTH_KEY` داخل `Code.gs` گذاشتید |
| **google_ip** | پیشفرض را نگه دارید. مرحلهٔ بعد خودکار پر میکند |
| **front_domain** | `www.google.com` را نگه دارید |
برای بستن کیبورد، جایی بیرون فیلدها ضربه بزنید.
---
## ۴. تست SNI
قبل از شروع تونل، ببینید مسیر خروجی کار میکند. بخش **SNI pool + tester** را باز کنید و **Test all** بزنید.
| نتیجه | معنا | کار بعدی |
|---|---|---|
| ✅ تیک سبز + زمان | `google_ip` در دسترس است و `SNI` را قبول میکند | ادامه بدهید |
| ❌ `connect timeout` روی همه | `google_ip` تنظیمشده در دسترس نیست | زیر بخش `Network` روی **Auto-detect google_ip** بزنید، بعد دوباره `Test all` |
| ❌ `connect timeout` روی بعضی | آن `SNI`های خاص در شبکهٔ شما `DPI-filtered` هستند | تیک آنها را بردارید؛ `pool` فقط از موارد تیکدار استفاده میکند |
| ❌ `dns: ...` | دستگاه اصلاً `www.google.com` را `resolve` نمیکند | Wi-Fi / Airplane mode را بررسی کنید |
اگر `Auto-detect` هم زدید و باز همه `fail` شد، شبکهٔ شما کل `Google edge` را مسدود کرده — `mhrv-rs` از پسش بر نمیآید.
---
## ۵. نصب گواهی MITM
پروکسی `TLS` را محلی باز میکند (قبل از ارسال به `Apps Script` دوباره رمزگذاری میشود)، پس گوشی باید به یک گواهی که در اولین اجرا ساختهایم اعتماد کند.
۱. در برنامه روی **Install MITM certificate** بزنید.
۲. دیالوگ تأیید `fingerprint` گواهی را نشان میدهد. **Install** را بزنید.
۳. برنامه:
- یک نسخهٔ `PEM` در مسیر `Downloads/mhrv-ca.crt` ذخیره میکند
- برنامهٔ **Settings** اندروید را باز میکند
۴. **اگر قفل صفحه ندارید** — اندروید از شما میخواهد الان یکی تنظیم کنید. مجبورید. این الزام `OS` برای نصب هر گواهی کاربری است. بعد از نصب میتوانید قفل را بردارید؛ گواهی معتبر میماند.
۵. در `Settings`، روی **نوار جستوجو** بالا بزنید و `CA certificate` را تایپ کنید. نتیجهای که **CA certificate** نوشته را باز کنید (یا روی بعضی `OEM`ها «Install CA certificate»).
> **حواستان باشد**: «VPN & app user certificate» یا «Wi-Fi certificate» را نزنید — دستهٔ اشتباه، کار نمیکند.
دلیل اینکه میگوییم `search` کنید: مسیر منو روی Pixel / Samsung / Xiaomi / … کاملاً متفاوت است، ولی همهشان توی نتیجهٔ جستوجوی `CA certificate` پیدایش میکنند.
۶. اندروید هشدار میدهد **«Your network may be monitored by an unknown third party»**. ما هستیم. **Install anyway** بزنید.
۷. **Downloads** را انتخاب کنید → روی `mhrv-ca.crt` بزنید. یک اسم دوستانه بدهید (یا پیشفرض را قبول کنید). **OK**.
۸. به برنامهٔ `mhrv-rs` برگردید. یک `snackbar` پایین تأیید میکند **Certificate installed ✓** — برنامه با مقایسهٔ `fingerprint` در `AndroidCAStore` مطمئن میشود نصب شده.
اگر گفت «not yet installed»، مرحلهٔ ۵ را دوباره انجام دهید.
چرا برنامه گواهی را مستقیماً نصب نمیکند؟
اندروید ۱۱ مسیر `inline` با `KeyChain.createInstallIntent` را حذف کرد. قبلاً این `intent` یک `picker` داخل خود برنامه باز میکرد. روی اندروید فعلی یک دیالوگ بنبست با فقط دکمهٔ `Close` نشان میدهد — گوگل میخواهد نصب `CA` خودآگاه باشد. ما کار سخت (ذخیرهٔ فایل، باز کردن `Settings`، تأیید پس از نصب) را انجام میدهیم، ولی خود ناوبری در `Settings` اجباری است.
---
## ۶. اجرای تونل
۱. **Start** را بزنید.
۲. اندروید دیالوگ مجوز `VPN` را نشان میدهد: *«mhrv-rs wants to set up a VPN connection...»*. **OK**.
۳. آیکون کلید در `status bar` ظاهر میشود. این یعنی `VPN` فعال است.
۴. `Chrome` را باز کنید. برای تست فشار سنگین: `https://www.cloudflare.com`، `https://yahoo.com`، `https://discord.com` — همه باید عادی `load` شوند.
بخش **Live logs** را باز کنید تا ترافیک را زنده ببینید:
| خط لاگ | معنا |
|---|---|
| `SOCKS5 CONNECT -> :443` | مرورگر یک جریان `TCP` باز کرد؛ `TUN` گرفت |
| `dispatch :443 -> MITM + Apps Script relay` | تصمیم مسیریابی |
| `MITM TLS -> :443 (sni=)` | گواهی `leaf` ما را مرورگر پذیرفت |
| `relay GET https:///...` | به `Apps Script` فرستاده شد |
| `preflight 204 ` | `CORS preflight` که خودمان جواب دادیم (عادی، نگران نباشید) |
---
## راهنمای سریع رابط کاربری
| کنترل | محل | توضیح |
|---|---|---|
| **Deployment URL(s) or script ID(s)** | بخش `Apps Script relay` | یکی در هر خط؛ `round-robin` |
| **auth_key** | بخش `Apps Script relay` | باید دقیقاً با `AUTH_KEY` در `Code.gs` یکی باشد |
| **google_ip** / **front_domain** | بخش `Network` | دکمهٔ `Auto-detect` با `DNS` پر میکند |
| **Auto-detect google_ip** | زیر ردیف `Network` | `www.google.com` را دوباره `resolve` میکند + اگر `front_domain` به یک `IP` تبدیل شده بود ترمیم میکند |
| **SNI pool + tester** | باز/بسته میشود | تیک برای `rotation`؛ `Test` برای هر ردیف + `Test all` |
| **Advanced** | باز/بسته میشود | `verify_ssl`، `log_level`، `parallel_relay`، `upstream_socks5` |
| **Start / Stop** | ردیف پایین | ۲ ثانیه `debounce` بین `tap`ها |
| **Install MITM certificate** | زیر `Start/Stop` | ذخیرهٔ `PEM` → باز کردن `Settings` → جستوجوی `CA certificate` |
| **Live logs** | باز/بسته میشود (زیر دکمهٔ `Install`) | هر ۵۰۰ میلیثانیه `ring buffer` پروکسی خوانده میشود |
| **v1.0.x (badge نسخه)** | بالا سمت راست | ضربه بزنید تا `GitHub` را برای نسخهٔ جدیدتر چک کند |
---
## محدودیتهای شناختهشده
قبل از گزارش باگ، این را بخوانید — بیشتر گزارشهای «کار نمیکند» یکی از اینهاست.
### Cloudflare Turnstile («Verify you are human») حلقهٔ بیپایان
روی سایتهای تحت محافظت `Cloudflare` که **هر درخواست** را `challenge` میکنند، شما `Turnstile` را حل میکنید، به صفحه میرسید، بعد روی `click` بعدی دوباره `challenge` میشوید. این ذاتی مدل `Apps Script` است:
| عامل | مرورگر عادی | رلهٔ Apps Script |
|---|---|---|
| `IP` خروج | ثابت (ISP شما) | بین `pool` دیتاسنترهای گوگل میچرخد |
| `User-Agent` | مال `Chrome` | ثابت `Google-Apps-Script` (گوگل قفل کرده؛ قابل تغییر نیست) |
| `TLS JA3/JA4` | مال `Chrome` | مال دیتاسنتر گوگل |
کوکی `cf_clearance` کلادفلر به سهتایی `(IP, UA, JA3)` چسبیده که `challenge` با آن حل شده. درخواست بعدی با `IP` دیگر → `challenge` دوباره.
**سایتهایی که فقط بارگذاری اول را `gate` میکنند** (اکثر مشتریان `Bot Fight Mode` کلادفلر) بعد از یک حل بیمشکل کار میکنند. سایتهایی که هر درخواست `challenge` میزنند (صرافیهای رمزارز، بزرگسال، بعضی فورومها) ذاتاً با این معماری نمیشوند — برایشان از تونل دیگری استفاده کنید.
### UDP / QUIC (HTTP/3)
در حالت `full`، `SOCKS5 listener` دستور `UDP ASSOCIATE` را هم میفهمد و دیتاگرامهای UDP را داخل مسیر Apps Script تا `tunnel-node` میبرد؛ بعد `tunnel-node` از سمت سرور UDP واقعی به مقصد میفرستد. ISP شما همچنان فقط HTTPS به Google میبیند. در حالت `apps_script`، UDP هنوز مسیر قدیمی را دارد: `Chrome` اول `HTTP/3` را امتحان میکند و بعد به `HTTP/2 over TCP` برمیگردد.
### نشت IPv6
`TUN` فقط `IPv4` (`addRoute 0.0.0.0/0`) را روت میکند. `IPv6` از رابط معمولی میرود، شامل `WebRTC`. اگر هدفتان حریم خصوصی است (نه فقط عبور از `DPI`)، روی `Wi-Fi` کلاً `IPv6` را خاموش کنید.
### سقف روزانهٔ Apps Script
هر `/exec` یک سقف اجرای روزانه دارد (۲۰ هزار در روز برای حساب مصرفکننده، بیشتر برای `Workspace`). سایتهای ویدیو / `infinite scroll` سنگین آن را میخورند. راهحل: ۲-۳ اسکریپت `deploy` کنید، همهٔ `/exec URL`ها را در فیلد برنامه بچسبانید، یکی در هر خط — `round-robin` میکند.
### اکثر برنامههای غیر مرورگری به گواهی کاربری اعتماد نمیکنند
بهطور پیشفرض، برنامههای اندروید از اعتماد به `CA`های کاربری `opt-out` میکنند (پیشفرض `Network Security Config` از `Android 7` به بعد). برنامههای بانکی، `Netflix`، `Spotify`، اکثر پیامرسانها — همه از `mhrv-rs` با خطای `cert` رد میشوند. `TUN` ترافیکشان را به ما میفرستد؛ آنها `leaf` ما را رد میکنند. فقط برنامههایی که صریحاً `opt-in` کردهاند (مرورگرها، `curl`، بعضی ابزارهای توسعهدهنده) کار میکنند. این محدودیت کلی `MITM proxy` است.
---
## رفع اشکال
| علامت | احتمال علت | راهحل |
|---|---|---|
| `504 Relay timeout` در `Chrome` | دیپلوی `Apps Script` جواب نمیدهد | دوباره `/exec URL` را چک کنید (باید `/exec` ختم شود، نه `/dev`). در `Live logs` دنبال `Relay timeout` در مقابل `connect:` بگردید |
| `NET::ERR_CERT_AUTHORITY_INVALID` | گواهی `MITM` نصب نشده یا پیدا نشد | [مرحلهٔ ۵](#۵-نصب-گواهی-mitm) را دوباره انجام دهید. مطمئن شوید `CA certificate` را در `Settings` زدید، نه `VPN` یا `Wi-Fi` |
| `NET::ERR_CERT_COMMON_NAME_INVALID` روی سایتهای `Cloudflare` | باگ قبل از v1.0.0 | به v1.0.0 یا بالاتر بهروزرسانی کنید |
| قسمتهای `JS` سایت `load` نمیشوند | رد `OPTIONS` قبل از v1.0.0 | به v1.0.0+ بهروزرسانی کنید. اگر باز هم بود: `Live logs` → `Relay failed` پیدا کنید، گزارش دهید |
| همه `SNI`ها در `tester` تایماوت | `google_ip` قدیمی است (گوگل `A record` را عوض کرده) | **Auto-detect google_ip** را بزنید |
| `SNI tester` فقط بعضی ردیفها قرمز | آن `SNI`ها در شبکهٔ شما `DPI-filtered` هستند | تیک ردیفهای خراب را بردارید |
| برنامه با ضربه به `Stop` بسته میشود | باگ `race` نسخهٔ ۱.۰.۰/۱.۰.۱ | به v1.0.2 بهروزرسانی کنید. اگر روی v1.0.2+ هست: `adb logcat -s MhrvVpnService mhrv-crash mhrv_rs` و گزارش دهید |
| هنگام `update`، `INSTALL_FAILED_UPDATE_INCOMPATIBLE` | APK قدیمی با کلید متفاوت امضا شده (قبل از v1.0.2) | ابتدا `uninstall` کنید، سپس APK جدید را نصب کنید. فقط یکبار — از v1.0.2 به بعد امضا ثابت است |
| `Chrome` سفید بدون خطا | معمولاً باگ `render` روی `emulator` با `GPU` نرمافزاری | روی دستگاه واقعی تست کنید. `Live logs` را ببینید آیا رله واقعاً درخواست میفرستد |
| حلقهٔ `Cloudflare Turnstile` | [محدودیت شناختهشده](#cloudflare-turnstile-verify-you-are-human-حلقهٔ-بیپایان) | در این معماری راهحلی ندارد |
| برنامههای بانکی/استریم خطای `cert` میدهند | [محدودیت شناختهشده](#اکثر-برنامههای-غیر-مرورگری-به-گواهی-کاربری-اعتماد-نمیکنند) | راهحل ندارد — خود برنامه `opt-out` کرده |
### جمعآوری لاگ مفید
اگر میخواهید باگ گزارش دهید:
```sh
adb logcat -c # پاکسازی
# مشکل را در برنامه بازتولید کنید
adb logcat -d | grep -E "MhrvVpnService|mhrv_rs|mhrv-crash|tun2proxy" > mhrv.log
```
`mhrv.log` را به `issue` پیوست کنید. اینها را هم بگویید:
- نسخهٔ اندروید (`Settings → About phone → Android version`)
- `OEM` (Pixel / Samsung / Xiaomi / …)
- نسخهٔ برنامه (روی `badge` نسخه در `top bar` ضربه بزنید)
- چه کردید، چه انتظار داشتید، چه شد
---
## حذف برنامه
۱. `Settings → Apps → mhrv-rs → Uninstall`.
۲. اختیاری: حذف `CA MITM` — `Settings → Security → Encryption & credentials → User credentials → mhrv-rs MITM CA → Remove`. (اگر مسیر منو پیدا نمیشود، در `Settings` عبارت `user credentials` را جستوجو کنید.)
۳. پروفایل `VPN` هنگام `uninstall` خودکار باطل میشود — چیزی نیست که جداگانه پاک کنید.