- Top-of-page anchor is راهنمای فارسی (not URL-encoded) - Document the launcher scripts as the recommended first run - Update CA path (user-data dir, not ./ca) - Mirror the English and Persian sections feature-for-feature - Add a short security posture section - Wrap the Persian block in <div dir=rtl> for correct rendering
25 KiB
MasterHttpRelayVPN-RUST
Rust port of @masterking32's MasterHttpRelayVPN. All credit for the original idea and the Python implementation goes to @masterking32. This is a faithful reimplementation of the apps_script mode, packaged as two tiny binaries (CLI + desktop UI) with no runtime dependencies.
Free DPI bypass via Google Apps Script as a remote relay, with TLS SNI concealment. Your ISP's censor sees traffic going to www.google.com; behind the scenes a free Google Apps Script that you deploy in your own Google account fetches the real website for you.
Why this exists
The original Python project is excellent but requires Python + pip install cryptography h2 + system deps. For users in hostile networks that install process is often itself broken (blocked PyPI, missing wheels, Windows without Python). This port is a single ~2.5 MB executable that you download and run. Nothing else.
How it works
Browser / Telegram / xray
|
| HTTP proxy (8085) or SOCKS5 (8086)
v
mhrv-rs (local)
|
| TLS to Google IP, SNI = www.google.com
v ^
DPI sees www.google.com |
| | Host: script.google.com (inside TLS)
v |
Google edge frontend ---------+
|
v
Apps Script relay (your free Google account)
|
v
Real destination
The censor's DPI sees www.google.com in the TLS SNI and lets it through. Google's frontend hosts both www.google.com and script.google.com on the same IP and routes by the HTTP Host header inside the encrypted stream.
For a handful of Google-owned domains (google.com, youtube.com, fonts.googleapis.com, …) the same tunnel is used directly instead of going through the Apps Script relay. This bypasses the per-fetch quota and fixes the "User-Agent is always Google-Apps-Script" problem for those domains. You can add more domains via the hosts map in config.
Platforms
Linux (x86_64, aarch64), macOS (x86_64, aarch64), Windows (x86_64). Prebuilt binaries on the releases page.
What's in a release
Each archive contains two binaries and a launcher script:
| file | purpose |
|---|---|
mhrv-rs / mhrv-rs.exe |
CLI. Headless use, servers, automation. Works on all platforms; no system deps on macOS/Windows. |
mhrv-rs-ui / mhrv-rs-ui.exe |
Desktop UI (egui). Config form, Start/Stop/Test buttons, live stats, log panel. |
run.sh / run.command / run.bat |
Platform launcher: installs the MITM CA (needs sudo/admin) and then starts the UI. Use this on first run. |
macOS archives also ship mhrv-rs.app (in *-app.zip) — double-click to launch the UI without a terminal. You'll still need to run the CLI (mhrv-rs --install-cert) or run.command once to install the CA.
Linux UI also needs common desktop libraries available: libxkbcommon, libwayland-client, libxcb, libgl, libx11, libgtk-3. On most desktop distros these are already present; on a headless box install them via your package manager, or just use the CLI.
Where things live
Config and the MITM CA live in the OS user-data dir:
- macOS:
~/Library/Application Support/mhrv-rs/ - Linux:
~/.config/mhrv-rs/ - Windows:
%APPDATA%\mhrv-rs\
Inside that dir:
config.json— your settings (written by the UI's Save button or hand-edited)ca/ca.crt,ca/ca.key— the MITM root certificate. Only you have the private key.
The CLI also falls back to ./config.json in the current directory for backward compatibility with older setups.
Setup Guide
Step 1 — Deploy the Apps Script relay (one-time)
This part is unchanged from the original project. Follow @masterking32's guide or the summary below:
- Open https://script.google.com while signed into your Google account.
- New project, delete the default code.
- Copy the contents of
Code.gsfrom the original repo (raw) into the editor. - Change
const AUTH_KEY = "..."to a strong secret only you know. - Deploy → New deployment → Web app.
- Execute as: Me
- Who has access: Anyone
- Copy the Deployment ID (the long random string in the URL).
Step 2 — Download
Grab the archive for your platform from the releases page and extract it.
Or build from source:
cargo build --release --features ui
# Binaries: target/release/mhrv-rs and target/release/mhrv-rs-ui
Step 3 — First run
The launcher handles the one-time CA install, then starts the UI:
| platform | how |
|---|---|
| macOS | double-click run.command in Finder (or ./run.command in a terminal) |
| Linux | ./run.sh from a terminal |
| Windows | double-click run.bat |
It will ask for your password (sudo / UAC) to add the MITM root to the system trust store. After that the CA is trusted and you can launch the UI directly next time.
Step 4 — Configure in the UI
Open the UI and fill in the form:
- Apps Script ID — the Deployment ID from Step 1. Comma-separate multiple IDs for round-robin rotation across several deployments (higher quota, more throughput).
- Auth key — the same secret you set in
Code.gs. - Google IP —
216.239.38.120is a solid default. Use the scan button to probe for a faster one from your network. - Front domain — keep
www.google.com. - HTTP port / SOCKS5 port — defaults
8085/8086.
Hit Save, then Start. Use Test any time to send one request end-to-end through the relay and report the result.
Step 4 (alternative) — CLI only
Everything the UI does is also available in the CLI. Copy config.example.json to config.json (either next to the binary or into the user-data dir shown above), fill it in:
{
"mode": "apps_script",
"google_ip": "216.239.38.120",
"front_domain": "www.google.com",
"script_id": "PASTE_YOUR_DEPLOYMENT_ID_HERE",
"auth_key": "same-secret-as-in-code-gs",
"listen_host": "127.0.0.1",
"listen_port": 8085,
"socks5_port": 8086,
"log_level": "info",
"verify_ssl": true
}
Then:
./mhrv-rs # serve (default)
./mhrv-rs test # one-shot end-to-end probe
./mhrv-rs scan-ips # rank Google frontend IPs by latency
./mhrv-rs --install-cert # reinstall the MITM CA
./mhrv-rs --help
script_id can also be a JSON array: ["id1", "id2", "id3"].
Step 5 — Point your client at the proxy
The tool listens on two ports. Use whichever your client supports:
HTTP proxy (browsers, generic HTTP clients) — 127.0.0.1:8085
- Firefox — Settings → Network Settings → Manual proxy. HTTP host
127.0.0.1, port8085, tick Also use this proxy for HTTPS. - Chrome / Edge — use the system proxy settings, or the Proxy SwitchyOmega extension.
- macOS system-wide — System Settings → Network → Wi-Fi → Details → Proxies → enable Web Proxy (HTTP) and Secure Web Proxy (HTTPS), both
127.0.0.1:8085. - Windows system-wide — Settings → Network & Internet → Proxy → Manual proxy setup, address
127.0.0.1, port8085.
SOCKS5 proxy (Telegram, xray, app-level clients) — 127.0.0.1:8086, no auth.
- Works for HTTP, HTTPS, and non-HTTP protocols (Telegram's MTProto, raw TCP). The server auto-detects each connection and falls back to plain TCP passthrough when the payload isn't HTTP.
Diagnostics
mhrv-rs test— sends one request through the relay and reports success/latency. Use this first whenever something breaks — it isolates "relay is up" from "client config is wrong".mhrv-rs scan-ips— parallel TLS probe of 28 known Google frontend IPs, sorted by latency. Take the winner and put it ingoogle_ip. The UI has the same thing behind the scan button next to the Google IP field.- Periodic stats are logged every 60 s at
infolevel (relay calls, cache hit rate, bytes relayed, active vs. blacklisted scripts). The UI shows them live.
What's implemented vs. not
This port focuses on the apps_script mode — the only one that reliably works against a modern censor in 2026. Implemented:
- Local HTTP proxy (CONNECT for HTTPS, plain forwarding for HTTP)
- Local SOCKS5 proxy with smart TLS/HTTP/raw-TCP dispatch (Telegram, xray, etc.)
- MITM with on-the-fly per-domain cert generation via
rcgen - CA generation + auto-install on macOS / Linux / Windows
- Firefox NSS cert install (best-effort via
certutil) - Apps Script JSON relay, protocol-compatible with
Code.gs - Connection pooling (45 s TTL, max 20 idle)
- Gzip response decoding
- Multi-script round-robin
- Auto-blacklist failing scripts on 429 / quota errors (10-minute cooldown)
- Response cache (50 MB, FIFO + TTL,
Cache-Control: max-ageaware, heuristics for static assets) - Request coalescing: concurrent identical GETs share one upstream fetch
- SNI-rewrite tunnels (direct to Google edge, bypassing the relay) for
google.com,youtube.com,youtu.be,youtube-nocookie.com,fonts.googleapis.com. Extra domains configurable via thehostsmap. - Automatic redirect handling on the relay (
/exec→googleusercontent.com) - Header filtering (strip connection-specific, brotli)
testandscan-ipssubcommands- Script IDs masked in logs (
prefix…suffix) soinfologs don't leak deployment IDs - Desktop UI (egui) — cross-platform, no bundler needed
Intentionally not implemented (rationale included so future contributors don't spend cycles on them):
- HTTP/2 multiplexing — the
h2crate state machine (stream IDs, flow control, GOAWAY) has too many subtle hang cases; coalescing + 20-connection pool already gets most of the benefit for this workload. - Request batching (
q:[...]mode) — our connection pool + tokio async already parallelizes well; batching adds ~200 lines of state management with unclear incremental gain. - Range-based parallel download — edge cases (non-Range servers, chunked mid-stream, content-encoding) are real; YouTube-style video already bypasses Apps Script via SNI-rewrite tunnel.
- Other modes (
domain_fronting,google_fronting,custom_domain) — Cloudflare killed generic domain fronting in 2024; Cloud Run needs a paid plan. Skip unless specifically requested.
Known limitations
These are inherent to the Apps Script + domain-fronting approach, not bugs in this client. The original Python version has the same issues.
- User-Agent is fixed to
Google-Apps-Scriptfor anything going through the relay.UrlFetchApp.fetch()does not allow overriding it. Consequence: sites that detect bots (e.g., Google search, some CAPTCHA flows) serve degraded / no-JS fallback pages to relayed requests. Workaround: add the affected domain to thehostsmap so it's routed through the SNI-rewrite tunnel with your real browser's UA instead.google.com,youtube.com,fonts.googleapis.comare already there by default. - Video playback is slow and quota-limited for anything that goes through the relay. YouTube HTML loads through the tunnel (fast), but chunks from
googlevideo.comgo through Apps Script. Each Apps Script consumer account has a ~2 MUrlFetchAppcalls/day quota and a 50 MB body limit per fetch. Fine for text browsing, painful for 1080p. Rotate multiplescript_ids for more headroom, or use a real VPN for video. - Brotli is stripped from forwarded
Accept-Encodingheaders. Apps Script can decompress gzip, but notbr, and forwardingbrproduces garbled responses. Minor size overhead. - WebSockets don't work through the relay — it's single request/response JSON. Sites that upgrade to WS fail (ChatGPT streaming, Discord voice, etc.).
- HSTS-preloaded / hard-pinned sites will reject the MITM cert. Most sites are fine because the CA is trusted; a handful aren't.
- Google / YouTube 2FA and sensitive logins may trigger "unrecognized device" warnings because requests originate from Google's Apps Script IPs, not yours. Log in once via the tunnel (
google.comis in the rewrite list) to avoid this.
Security posture
- The MITM root stays on your machine only. The
ca/ca.keyprivate key is generated locally and never leaves the user-data dir. auth_keybetween the client and the Apps Script relay is a shared secret you pick. The server-sideCode.gsrejects requests without a matching key.- Traffic between your machine and Google's edge is standard TLS 1.3.
- What Google can see: the destination URL and headers of each request (because Apps Script fetches on your behalf). This is the same trust model as any hosted proxy — if that's not acceptable, use a self-hosted VPN instead.
License
MIT. See LICENSE.
Credit
Original project: https://github.com/masterking32/MasterHttpRelayVPN by @masterking32. The idea, the Google Apps Script protocol, the proxy architecture, and the ongoing maintenance are all his. This Rust port exists purely to make client-side distribution easier.
راهنمای فارسی
پورت Rust پروژهٔ MasterHttpRelayVPN از @masterking32. تمام اعتبار ایده و پیادهسازی اصلی پایتون متعلق به ایشان است. این نسخه فقط مدل apps_script را بهصورت دو فایل اجرایی کوچک (CLI + رابط گرافیکی) بدون هیچ وابستگی run-time ارائه میدهد.
عبور رایگان از DPI با استفاده از Google Apps Script بهعنوان رله، بههمراه مخفیسازی SNI در TLS. سانسور ISP فکر میکند ترافیک شما به سمت www.google.com میرود؛ در پشت صحنه یک Apps Script که خودتان در اکانت گوگل خودتان دیپلوی کردهاید سایت اصلی را برای شما واکشی میکند.
چرا این نسخه؟
نسخهٔ اصلی پایتون عالی است، اما نیاز به Python + نصب cryptography و h2 و چند وابستگی سیستمی دارد. برای کاربرانی که PyPI فیلتر است یا Python ندارند این فرآیند خودش یک دردسر است. این پورت فقط یک فایل اجرایی ~۲.۵ مگابایتی است که دانلود میکنید و اجرا میکنید. تمام.
نحوهٔ کار
مرورگر/تلگرام/xray شما با این ابزار بهعنوان HTTP proxy یا SOCKS5 proxy صحبت میکند. ابزار ترافیک را از طریق TLS به یک IP گوگل میفرستد، اما SNI را www.google.com میگذارد. داخل TLS رمزگذاریشده، header بهنام Host: script.google.com رد میشود. DPI فقط www.google.com را میبیند و اجازه عبور میدهد. Apps Script سایت مقصد را واکشی میکند و پاسخ را به شما بازمیگرداند.
برای چند دامنهٔ متعلق به خود گوگل (google.com، youtube.com، fonts.googleapis.com و …) از همین تونل مستقیم استفاده میشود بدون عبور از Apps Script. این کار هم مشکل سهمیهٔ Apps Script را حل میکند و هم مشکل «User-Agent همیشه Google-Apps-Script است» را برای این دامنهها از بین میبرد. میتوانید دامنههای بیشتری را از طریق hosts در config اضافه کنید.
پلتفرمها
لینوکس (x86_64، aarch64)، مکاواس (x86_64، aarch64)، ویندوز (x86_64). فایلهای آماده در صفحهٔ releases.
محتوای هر release
هر آرشیو شامل دو باینری و یک اسکریپت راهانداز است:
mhrv-rs/mhrv-rs.exe— نسخهٔ CLI، برای سرور و استفادهٔ headless.mhrv-rs-ui/mhrv-rs-ui.exe— رابط گرافیکی دسکتاپ (egui). فرم تنظیمات، دکمههای Start/Stop/Test، آمار زنده، لاگ.run.sh/run.command/run.bat— اسکریپت راهانداز مخصوص هر سیستمعامل: اول CA را نصب میکند (نیاز به sudo/Administrator) بعد UI را اجرا میکند. بار اول حتماً همین را اجرا کنید.
نسخهٔ مک آرشیو *-app.zip هم دارد که داخلش mhrv-rs.app است — با دو بار کلیک از Finder اجرا میشود. ولی بار اول باید CA را نصب کنید (با mhrv-rs --install-cert یا همان run.command).
مسیر فایلها
Config و ریشهٔ MITM در پوشهٔ کاربر سیستمعامل قرار میگیرند:
- مک:
~/Library/Application Support/mhrv-rs/ - لینوکس:
~/.config/mhrv-rs/ - ویندوز:
%APPDATA%\mhrv-rs\
داخل این پوشه: config.json، ca/ca.crt (گواهی عمومی) و ca/ca.key (کلید خصوصی — فقط روی سیستم شماست و هرگز جایی ارسال نمیشود).
مراحل راهاندازی
۱. دیپلوی Apps Script (یک بار)
این بخش دقیقاً همان نسخهٔ اصلی است:
۱. به https://script.google.com بروید و با اکانت گوگل وارد شوید.
۲. New project بزنید و کد پیشفرض را پاک کنید.
۳. محتوای Code.gs (لینک raw) را از ریپو اصلی کپی و Paste کنید.
۴. خط const AUTH_KEY = "..." را به یک رمز قوی و مختص خودتان تغییر دهید.
۵. Deploy → New deployment → Web app
- Execute as: Me
- Who has access: Anyone ۶. Deployment ID را کپی کنید (رشتهٔ تصادفی طولانی داخل URL).
۲. دانلود
آرشیو پلتفرم خود را از صفحهٔ releases بگیرید و extract کنید.
۳. اجرای بار اول
- مک: روی
run.commandدو بار کلیک کنید (یا از ترمینال./run.command). - لینوکس: در ترمینال
./run.sh. - ویندوز: روی
run.batدو بار کلیک کنید.
اسکریپت رمز شما را میخواهد (sudo یا UAC) تا CA داخل trust store سیستم نصب شود. بعد از این کار UI باز میشود و در اجراهای بعدی میتوانید مستقیماً خود UI یا mhrv-rs.app را اجرا کنید.
۴. تنظیمات در UI
فرم را پر کنید:
- Apps Script ID — همان Deployment ID مرحلهٔ ۱. برای استفاده از چند deployment بهصورت round-robin، با کاما جدا کنید.
- Auth key — همان رمز
AUTH_KEYداخلCode.gs. - Google IP — پیشفرض
216.239.38.120خوب است. دکمهٔ scan کنارش IPهای دیگر گوگل را از شبکهٔ شما تست میکند و سریعترین را معرفی میکند. - Front domain — همان
www.google.comرا نگه دارید. - HTTP port / SOCKS5 port — پیشفرضها
8085و8086.
Save بعد Start. دکمهٔ Test در هر زمان یک درخواست کامل از طریق رله میفرستد و نتیجه را گزارش میدهد.
۴ (جایگزین). فقط CLI
هر کاری که UI میکند از CLI هم قابل انجام است. config.example.json را به config.json کپی و مقادیر را پر کنید، بعد:
./mhrv-rs # اجرای proxy
./mhrv-rs test # تست یک درخواست کامل
./mhrv-rs scan-ips # رتبهبندی IPهای گوگل بر اساس تأخیر
./mhrv-rs --install-cert # نصب مجدد CA
./mhrv-rs --help
۵. تنظیم proxy در کلاینت
ابزار روی دو پورت گوش میدهد:
HTTP proxy (مرورگرها) — 127.0.0.1:8085
- Firefox — Settings → Network Settings → Manual proxy. HTTP برابر
127.0.0.1، port8085، تیک Also use this proxy for HTTPS. - Chrome / Edge — از تنظیمات proxy سیستم یا افزونهٔ Proxy SwitchyOmega استفاده کنید.
- مک (system-wide) — System Settings → Network → Wi-Fi → Details → Proxies → Web Proxy (HTTP) و Secure Web Proxy (HTTPS) را فعال کنید، هر دو
127.0.0.1:8085. - ویندوز (system-wide) — Settings → Network & Internet → Proxy → Manual proxy setup، address
127.0.0.1، port8085.
SOCKS5 proxy (تلگرام، xray، کلاینتهای app-level) — 127.0.0.1:8086، بدون auth.
برای HTTP و HTTPS و هم پروتکلهای غیر-HTTP (MTProto تلگرام، TCP خام) کار میکند. ابزار بهصورت هوشمند تشخیص میدهد و اگر ترافیک HTTP نبود، بهصورت plain TCP passthrough میفرستد.
محدودیتهای شناختهشده
اینها محدودیتهای ذاتی روش Apps Script + SNI هستند، نه باگ در این کلاینت. نسخهٔ اصلی پایتون هم دقیقاً همینها را دارد.
- User-Agent همیشه
Google-Apps-Scriptاست برای هر چیزی که از رله رد میشود.UrlFetchApp.fetch()گوگل اجازهٔ تغییر این را نمیدهد. نتیجه: سایتهایی که ربات را تشخیص میدهند (مثل جستوجویgoogle.com، بعضی CAPTCHAها) نسخهٔ سادهٔ بدون JS را نشان میدهند. راهحل: دامنهٔ موردنظر را بهhostsدرconfig.jsonاضافه کنید تا از تونل SNI-rewrite (با UA واقعی مرورگر) رد شود.google.com،youtube.com،fonts.googleapis.comاز قبل در این لیست هستند. - پخش ویدیو کند است و سهمیه دارد برای چیزهایی که از رله رد میشوند. HTML یوتوب از تونل میآید (سریع)، اما chunkهای ویدیو از
googlevideo.comاز طریق Apps Script میآیند. هر اکانت consumer گوگل روزانه ~۲ میلیونUrlFetchAppcall و سقف ۵۰ مگابایت روی هر fetch دارد. برای مرور متنی عالی است، برای ۱۰۸۰p دردناک. چندscript_idبگذارید، یا برای ویدیو از VPN واقعی استفاده کنید. - Brotli فیلتر میشود از header ارسالی
Accept-Encoding. Apps Script میتواند gzip باز کند اما brotli نه، و اگرbrرا رد کنیم پاسخ خراب میشود. gzip فعال است. سربار حجمی جزئی. - WebSocket کار نمیکند از طریق رله (تک request/response JSON است). سایتهایی که به WS ارتقا میدهند fail میکنند (streaming ChatGPT، voice دیسکورد و غیره).
- سایتهای HSTS-preloaded / pin-شده گواهی MITM را قبول نمیکنند. اکثر سایتها مشکلی ندارند چون CA ما trust شده، ولی چند مورد استثنا هستند.
- ورود دومرحلهای گوگل/یوتوب ممکن است «دستگاه ناشناس» هشدار بدهد چون درخواست از IP Apps Script میآید نه IP شما. یک بار با تونل (
google.comاز قبل در لیست است) لاگین کنید.
امنیت
- ریشهٔ MITM فقط روی سیستم شما میماند. کلید خصوصی
ca/ca.keyمحلی ساخته میشود و هرگز از user-data dir خارج نمیشود. auth_keyبین کلاینت و Apps Script یک secret مشترک است که خودتان انتخاب میکنید. کد سرور (Code.gs) هر درخواستی را که این کلید را نداشته باشد رد میکند.- ترافیک بین سیستم شما و لبهٔ گوگل TLS 1.3 استاندارد است.
- آنچه گوگل میبیند: URL و headerهای درخواست (چون Apps Script بهجای شما fetch میکند). این دقیقاً همان trust model هر proxy میزبانیشده است — اگر قابل قبول نیست از VPN self-hosted استفاده کنید.
اعتبار
پروژهٔ اصلی: https://github.com/masterking32/MasterHttpRelayVPN توسط @masterking32. ایده، پروتکل Apps Script، معماری proxy و نگهداری همه متعلق به ایشان است. این پورت Rust فقط برای سادهکردن توزیع سمت کلاینت درست شده.