<div dir="rtl">

# برنامهٔ اندروید mhrv-rs

راهنمای کامل نصب و راه‌اندازی برنامهٔ اندروید: نصب، تنظیمات اولیه، رفع اشکال و محدودیت‌های شناخته‌شده.

- [معرفی کلی](#معرفی-کلی)
- [پیش‌نیازها](#پیش‌نیازها)
- [۱. نصب APK](#۱-نصب-apk)
- [۲. ساخت Apps Script](#۲-ساخت-apps-script)
- [۳. وارد کردن تنظیمات در برنامه](#۳-وارد-کردن-تنظیمات-در-برنامه)
- [۴. تست SNI](#۴-تست-sni)
- [۵. نصب گواهی MITM](#۵-نصب-گواهی-mitm)
- [۶. اجرای تونل](#۶-اجرای-تونل)
- [راهنمای سریع رابط کاربری](#راهنمای-سریع-رابط-کاربری)
- [محدودیت‌های شناخته‌شده](#محدودیت‌های-شناخته‌شده)
- [رفع اشکال](#رفع-اشکال)
- [حذف برنامه](#حذف-برنامه)

---

## معرفی کلی

برنامهٔ اندروید همان کرت `Rust` پشت نسخهٔ دسکتاپ است که در قالب یک رابط `Compose` بسته‌بندی شده و از طریق `VpnService` و [`tun2proxy`](https://crates.io/crates/tun2proxy) تمام ترافیک `TUN` دستگاه را به پروکسی می‌سپارد. همهٔ برنامه‌های روی گوشی به‌طور خودکار از پروکسی رد می‌شوند — بدون نیاز به تنظیم per-app.

<div dir="ltr">

```
هر برنامه روی دستگاه
        │
        ▼
VpnService TUN  ──► tun2proxy (داخل فرایند)
                        │
                        ▼
                SOCKS5 محلی  ──► dispatcher در mhrv-rs
                                      │
                    ┌─────────────────┤
                    ▼                 ▼
          تونل sni-rewrite    رلهٔ Apps Script
          (دامنه‌های گوگل      (هر چیز دیگر، از
           مستقیم به google_ip)  طریق /exec شما)
```

</div>

زمان راه‌اندازی: **حدود ۱۰ دقیقه** اگر `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

۱. در مرورگر گوشی به <https://github.com/therealaleph/MasterHttpRelayVPN-RUST/releases/latest> بروید.
۲. فایل `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` فعال دارید، این مرحله را رد کنید.

این مرحله را روی لپ‌تاپ انجام دهید — کار با مرورگر روی گوشی دردناک است.

۱. به <https://script.google.com> بروید → **New project**.
۲. محتوای کامل [`assets/apps_script/Code.gs`](../assets/apps_script/Code.gs) از همین ریپو را کپی کنید.
۳. در ویرایشگر `Script`، کد پیش‌فرض `function myFunction() {}` را انتخاب و جایگزین کنید.
۴. خط زیر را نزدیک بالا پیدا کنید:
   <div dir="ltr">

   ```js
   const AUTH_KEY = "CHANGE_ME_TO_A_STRONG_SECRET";
   ```

   </div>

   مقدار `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 &lt;project name&gt; (unsafe)** → **Allow**
۹. **Web app URL** را کپی کنید. به شکل `https://script.google.com/macros/s/AKfyc.../exec` است.

<details>
<summary>اسکریپت دقیقاً چه می‌کند؟</summary>

درخواست `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` مسیر را تعیین می‌کند.

</details>

---

## ۳. وارد کردن تنظیمات در برنامه

برگردید به گوشی:

| فیلد | مقدار |
|---|---|
| **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»، مرحلهٔ ۵ را دوباره انجام دهید.

<details>
<summary>چرا برنامه گواهی را مستقیماً نصب نمی‌کند؟</summary>

اندروید ۱۱ مسیر `inline` با `KeyChain.createInstallIntent` را حذف کرد. قبلاً این `intent` یک `picker` داخل خود برنامه باز می‌کرد. روی اندروید فعلی یک دیالوگ بن‌بست با فقط دکمهٔ `Close` نشان می‌دهد — گوگل می‌خواهد نصب `CA` خودآگاه باشد. ما کار سخت (ذخیرهٔ فایل، باز کردن `Settings`، تأیید پس از نصب) را انجام می‌دهیم، ولی خود ناوبری در `Settings` اجباری است.

</details>

---

## ۶. اجرای تونل

۱. **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 -> <host>:443` | مرورگر یک جریان `TCP` باز کرد؛ `TUN` گرفت |
| `dispatch <host>:443 -> MITM + Apps Script relay` | تصمیم مسیریابی |
| `MITM TLS -> <host>:443 (sni=<host>)` | گواهی `leaf` ما را مرورگر پذیرفت |
| `relay GET https://<host>/...` | به `Apps Script` فرستاده شد |
| `preflight 204 <url>` | `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` کرده |

### جمع‌آوری لاگ مفید

اگر می‌خواهید باگ گزارش دهید:

<div dir="ltr">

```sh
adb logcat -c                              # پاک‌سازی
# مشکل را در برنامه بازتولید کنید
adb logcat -d | grep -E "MhrvVpnService|mhrv_rs|mhrv-crash|tun2proxy" > mhrv.log
```

</div>

`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` خودکار باطل می‌شود — چیزی نیست که جداگانه پاک کنید.

</div>
