Map

GooseRelayVPN

Toolbox toolboxgoproxyvpncensorship-circumventionserverless-relay-transportgoogle-apps-scriptdomain-frontingiranGoMIT โ†ณ show in map Markdown
title
GooseRelayVPN
type
toolbox
summary
SOCKS5 VPN tunneling raw TCP through a Google Apps Script relay to a small VPS exit, with end-to-end AES-256-GCM so Google never sees plaintext
tags
go, proxy, vpn, censorship-circumvention, serverless-relay-transport, google-apps-script, domain-fronting, iran
language
Go
license
MIT
created
2026-04-30
updated
2026-04-30

GooseRelayVPN is the third entry in the small but interesting "Apps-Script-as-a-circumvention-relay" cluster, after masterhttprelayvpn (Python original) and masterhttprelayvpn-rust (Rust port). The author Kianmhz cites the original explicitly: "This project was inspired by the idea in the main repository: MasterHttpRelayVPN."

What's different here is the architecture. Where the MasterHttpRelay tools front HTTPS request-response traffic through Apps Script with a local MITM CA, GooseRelay tunnels raw TCP end-to-end with AES-256-GCM, requiring a small VPS exit server. Google sees only opaque encrypted bytes; the AES key never touches Google. This trades the "no infrastructure required" property of MasterHttpRelay for being able to carry SSH, IMAP, custom binary protocols, anything SOCKS5 can wrap.

Architecture

Browser/App
  -> SOCKS5 (127.0.0.1:1080)
  -> AES-256-GCM raw-TCP frames
  -> HTTPS to Google edge IP (SNI=www.google.com, Host=script.google.com)
  -> Apps Script doPost() (~30-line dumb forwarder, never sees plaintext)
  -> Your VPS :8443/tunnel (decrypts, demuxes by session_id, dials target)
  <- Same path in reverse via long-polling

Five moving parts:

  1. Local SOCKS5 listener (goose-client) on the user's machine, port 1080
  2. AES-256-GCM frame encoder that wraps every TCP byte before it leaves
  3. Domain-fronted HTTPS connection to a Google edge IP (default 216.239.38.120) with SNI=www.google.com, Host=script.google.com โ€” see domain-fronting
  4. Google Apps Script web app (Code.gs, ~30 lines) โ€” a dumb forwarder that POSTs the encrypted batch to the VPS
  5. VPS exit server (goose-server) on a $4/month Linux box โ€” decrypts, multiplexes by session ID, runs the actual net.Dial

Two Go binaries: goose-client (run daily) and goose-server (run once on the VPS, systemd or NSSM). Apps Script is "Deploy as web app, anyone can access," with the deployment ID pasted into the client config.

Wire format

  • Frame: session_id (16) || seq (u64 BE) || flags (u8) || target_len (u8) || target || payload_len (u32 BE) || payload
  • Batch seal: nonce (12) || AES-GCM(u16 frame_count || [u32 frame_len || frame_bytes]โ€ฆ) โ€” one nonce + tag per HTTP body, not per frame
  • HTTP body: base64(nonce || ciphertext+tag) (base64 so it survives Apps Script's ContentService text round-trip)

Authentication is the AES-GCM tag itself โ€” no shared password, no certificates. Frames that fail Open() are dropped silently. The 64-character hex tunnel_key is the entire trust anchor and must match byte-for-byte between client and server.

Multi-deployment scaling

Each Apps Script deployment is rate-limited to ~20,000 calls/day. The client supports an array of deployment IDs:

"script_keys": ["FIRST_ID", "SECOND_ID", "THIRD_ID"]

Round-robin across deployments. Health-aware blacklist with exponential backoff (3s, 6s, 12s, โ€ฆ up to ~48s) on failures. Same-poll failover so one transient quota error doesn't drop traffic. README warns against more than 3-4 deployment IDs โ€” each adds 3 concurrent poll workers and going higher creates load without speed gains.

Setup cost

  • One-time: $4/month Linux VPS, 64-char AES key from scripts/gen-key.sh, two Go binaries, one Apps Script project + Deploy New Deployment with type "Web app" / access "Anyone"
  • Daily: run ./goose-client and point browser at SOCKS5 127.0.0.1:1080

The Apps Script step has the usual Google-deployment gotcha: every Code.gs edit requires a new deployment (Deploy โ†’ New deployment, not just save), with the new deployment ID pasted back into the client config.

Tradeoffs

GooseRelay MasterHttpRelay (Python/Rust) VLESS via xray-tutorial
Server cost $4/mo VPS required Free (Google only) $5/mo VPS minimum
Protocol Any TCP via SOCKS5 HTTPS only (MITM CA on local) Any TCP via VLESS
Setup VPS + Apps Script + AES key Apps Script + auth key VPS + domain + TLS + Xray config
Throughput Apps Script quota * # deployments Apps Script quota * # deployments VPS bandwidth
Observability Apps Script never sees plaintext Apps Script sees the full HTTP request Direct
Iran DPI fit TLS-to-Google + raw TCP โ€” strong TLS-to-Google + HTTP โ€” fingerprint risk Direct VPS = fingerprint risk

The end-to-end AES is the meaningful security improvement over MasterHttpRelay โ€” Google's request logs are obvious and Google ToS / Iran-sanctions exposure for the original maintainers is real. With GooseRelay, Google's logs are AES ciphertext; the only thing leaking is request count, body sizes, and timing. Still recoverable by a sufficiently motivated adversary, but qualitatively different from logging plaintext destinations.

The VPS requirement is the meaningful cost. The whole appeal of MasterHttpRelay was "free, no servers." GooseRelay drops that because the project's stated value is tunneling raw TCP โ€” SSH, IMAP, anything โ€” which fundamentally requires a real net.Dial somewhere.

Watchlist

This goes on watchlist โ€” single author (kianmhz), recent repo, single Persian-speaking-market target. Re-check 2026-07-29 for: independent contributors, Android/iOS clients (currently CLI-only), audit of the AES wrapper, evidence the threat model holds against Iran's TSPU-equivalent (see tspu for the Russian analogue).

Repo: https://github.com/Kianmhz/GooseRelayVPN