Library / SDK
denuitt1/mhr-cfw avatar
denuitt1/mhr-cfw

MHR-CFW: a relay that dresses your traffic as www.google.com

A Domain-Fronting Relay that routes traffic though GAS (Google Apps Script) and forwards it to Cloudflare Workers. Designed to bypass DPI.

4,418 stars416 forksPythonMIT

At a glance

What is it?
MHR-CFW is a MIT-licensed Python domain-fronting relay that routes browser traffic through a Google Apps Script deployment and a Cloudflare Worker, so a network DPI filter sees ordinary traffic to an allowed Google domain while the real destination stays hidden inside the relay request. It ships a local HTTP and SOCKS proxy, a setup wizard, Docker support, and a Persian README alongside the English one.
Who is it for?
Use MHR-CFW when an outbound DPI filter only permits mainstream destinations and a self-assembled relay from free Google Apps Script and Cloudflare Workers accounts is an acceptable trade, and add the self-hosted upstream forwarder when CAPTCHA token binding makes the Workers' rotating edge IPs fail verification.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 146 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Google on the outside, Cloudflare on the inside

The primary architecture is a chain, Client to Local Relay to Google or CDN front, into a Google Apps Script relay, out through a Cloudflare Worker, and finally to the destination, with the branch annotation showing what the network's DPI filter actually observes, www.google.com. In normal use the browser sends traffic to the proxy running on your computer, the proxy sends it through Google-facing infrastructure so the network only sees an allowed domain, and the deployed relay fetches the real website through the Cloudflare Worker and returns the response along the same path. The filter sees normal-looking Google traffic while the actual destination stays hidden inside the relay request. Domain fronting is the entire trick, the observable connection and the real payload ride different parts of the same infrastructure, and here the front is one of the most universally allowed domains on restrictive networks.

Two pastes, one password, one deployment ID

Deployment is manual but short. The Cloudflare side means opening the dashboard, creating a Worker under Compute, Workers and Pages, starting from Hello World, deleting the default code, and pasting the entire contents of deploy/cloudflare-worker/worker.js, then editing one line to your own worker address:

javascript
const WORKER_URL = "myworker.workers.dev";

The Google side means creating a new project at script.google.com, deleting the default code, pasting deploy/gas/Code.gs, and setting two values, a password only you know and your worker URL:

javascript
const AUTH_KEY = "your-secret-password-here";
const WORKER_URL = "https://myworker.workers.dev";

The Apps Script deploys as a Web app executing as you, accessible to Anyone, and its long random Deployment ID is what the local relay will dial. The AUTH_KEY is the shared secret proving a relay request came from your client rather than a stranger who found the script URL.

A wizard, then 127.0.0.1:8085

The repository lands with git clone and pip install -r requirements.txt, with a documented fallback mirror for networks that cannot reach PyPI directly. First launch is run.bat on Windows or run.sh on Linux, which starts a setup wizard prompting for the AUTH_KEY and the Google Apps Script Deployment ID, the two values produced during deployment. The wizard is a real Python program, setup.py, an interactive script that writes a ready-to-use config.json by prompting only for values the user must actually choose, everything else getting a sane default, and it can generate a random 32 character auth key from letters and digits on its own. Once configured, the message to expect is that the HTTP proxy is running on 127.0.0.1:8085. For clients, the README recommends v2rayN configured with a SOCKS5 proxy, or the FoxyProxy extensions for Chrome and Firefox, and the verification step is opening ipleak.net and confirming the visible IP belongs to Cloudflare. The setup script also respects the NO_COLOR environment variable and disables its colored prompts entirely when output is not a terminal, so the wizard stays usable from scripts and non interactive contexts.

A Persian README and a PyPI mirror

Two small signals say who this is for. The README exists in English and Persian, README_FA.md, linked side by side at the top, which places the primary audience among Persian speakers living behind national filtering. And the installation step includes an alternative pip index, a mirror at mirror-pypi.runflare.com with a trusted-host flag, for the situation where the network being circumvented blocks PyPI itself, so the bootstrap instructions assume the hostile network from the very first command. The project's description states its purpose plainly, a domain-fronting relay routing traffic through Google Apps Script and forwarding to Cloudflare Workers, designed to bypass DPI. Release activity clustered in spring 2026, v2.0.2 on 2026-05-10, v2.0.1 on 2026-05-03 and v2.0.0 on 2026-04-29, with the last push on 2026-05-10.

CAPTCHAs bind to IPs, Workers rotate them

The optional upstream forwarder exists because of a subtle failure. CAPTCHA systems, Cloudflare Turnstile, reCAPTCHA and hCaptcha, bind their tokens to the IP address that solved the challenge, but Cloudflare Workers exit through different edge IPs per request, so verification on the target site fails even when the challenge was solved legitimately. The second architecture adds one hop to fix it, Client to Local Relay to GAS relay to Cloudflare Worker to a self-hosted upstream forwarder, and finally Exit, keeping the visible front identical while the Worker forwards all its fetch calls through that single self-hosted box, giving the outside world one stable exit IP for the CAPTCHA machinery to trust. It is a corrective for a side effect of serverless egress rather than a change to the core relay design.

SSL inspection means installing ca.crt everywhere

Because this proxy performs SSL inspection, clients see certificate errors until its CA is trusted, and the README walks through the two hardest cases. Inside a virtual machine, the host's localhost is unreachable, so the proxy address becomes the hypervisor's gateway, 10.0.2.2 in VirtualBox NAT mode:

bash
export http_proxy="http://10.0.2.2:8085"
export https_proxy="http://10.0.2.2:8085"
export all_proxy="socks5://10.0.2.2:8085"

with the CA installed on the guest via sudo cp ca.crt /usr/local/share/ca-certificates/ followed by update-ca-certificates. For phones sharing the proxy over LAN, the Windows host may need a netsh portproxy rule from its LAN address to 127.0.0.1 plus an inbound firewall rule for port 8085, the phone sets a manual HTTP proxy to the host IP, and the CA certificate is installed as a device profile on iOS or a CA certificate on Android, with iOS additionally requiring trust to be enabled in Certificate Trust Settings.

A dependency list that is nearly empty by design

The requirements file opens with a statement of intent, no external dependencies for basic modes, Python 3.10+ required, and everything after it is optional and annotated. cryptography at 41.0.0 or later enables the MITM interception used in apps_script mode. h2 at 4.1.0 or later adds HTTP/2 multiplexing for a faster Apps Script relay. certifi provides the CA bundle for TLS verification except on Windows, where the system certificate store is used instead. brotli and zstandard handle the compression encodings modern websites and some CDNs actually send, br and zstd. LAN interface detection deliberately uses only the standard library, noted as working on Windows, Linux, macOS and Android Termux without a C compiler, which keeps the lightest deployments toolchain free.

Docker with an HTTP port and a SOCKS port

Container deployment is first class. The Dockerfile builds on python:3.13-slim, installs the requirements, copies the project including the generated config.json, exposes ports 8085 and 1080, and runs main.py. The compose file names the stack mhr-cfw-docker, sets restart to unless-stopped, publishes 8085 as the HTTP port and 1080 as the SOCKS5 port, and places the container on its own bridge network. The two-port split matches the client guidance, browser extensions and phones use the HTTP proxy on 8085 while v2rayN speaks SOCKS5 to 1080. The repository rounds out with config.example.json as the configuration template, a TODO.md tracking open work, and the deploy directory holding the two paste-ready payloads, worker.js and Code.gs, that turn free platform accounts into the relay's middle hops. A TODO.md at the root records what remains unfinished, a quiet signal that the optional forwarding architecture is the active frontier while the core relay is treated as settled.

Editorial conclusion

Use MHR-CFW when an outbound DPI filter only permits mainstream destinations and a self-assembled relay from free Google Apps Script and Cloudflare Workers accounts is an acceptable trade, and add the self-hosted upstream forwarder when CAPTCHA token binding makes the Workers' rotating edge IPs fail verification. It is not a tool for hiding wrongdoing from endpoint security or for anything touching other people's systems, it is a personal circumvention proxy whose whole surface is your own traffic. Before deploying, verify you can live with its MITM design, every connection is decrypted locally and re-signed by the bundled CA, so installing ca.crt on each client is mandatory, and confirm Google Apps Script and Workers are reachable and permitted from your network at all.

Frequently asked questions

What is mhr cfw?

MHR-CFW is a MIT-licensed Python domain-fronting relay that routes traffic through a Google Apps Script deployment and forwards it to a Cloudflare Worker, designed so a network DPI filter only sees traffic to an allowed domain like www.google.com. It runs a local HTTP proxy on 127.0.0.1:8085, with Docker support publishing an additional SOCKS5 port.

How do you deploy MHR-CFW?

Paste deploy/cloudflare-worker/worker.js into a new Cloudflare Worker and set your worker URL, then paste deploy/gas/Code.gs into a Google Apps Script project, set the AUTH_KEY password and worker URL, and deploy it as a Web app executing as you with access set to Anyone, copying the Deployment ID. Clone the repository, install requirements, run run.bat or run.sh, and enter the AUTH_KEY and Deployment ID in the setup wizard.

Why does MHR-CFW require installing a CA certificate?

The proxy performs SSL inspection, so clients see certificate errors until its CA is trusted. Linux guests can install ca.crt with sudo cp ca.crt /usr/local/share/ca-certificates/ followed by update-ca-certificates, and phones sharing the proxy install the certificate as a CA certificate on Android or as a trusted profile on iPhone.

Official sources

  1. denuitt1/mhr-cfw on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/denuitt1-mhr-cfw.svg)](https://hysenlabs.com/projects/denuitt1-mhr-cfw)