GooseRelayVPN: Raw TCP Through Google Apps Script
SOCKS5 VPN that tunnels raw TCP through Google Apps Script to a VPS exit server, with end-to-end AES-256-GCM and domain-fronted TLS to Google
At a glance
- What is it?
- GooseRelayVPN is a Go-based SOCKS5 client and VPS exit server that carries raw TCP through a Google Apps Script web app. It suits users who need SSH, IMAP, and custom protocols tunnelled with AES-256-GCM, but it adds a paid VPS, Google account quotas, and a domain-fronted deployment to the chain.
- Who is it for?
- GooseRelayVPN fits users who specifically need raw TCP through a Google Apps Script transport and already have a public-IP VPS plus an Apps Script deployment. It does not suit users seeking a conventional VPN, an HTTP-only proxy, or a system without a continuously reachable exit server.
- 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 147 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
GooseRelayVPN's raw TCP exit design
GooseRelayVPN addresses a narrow but specific limitation of proxy systems built entirely inside Google Apps Script. Its local `goose-client` exposes a SOCKS5 listener at `127.0.0.1:1080`, receives arbitrary application TCP streams, and sends them through a Google Apps Script web app to a separate `goose-server` running on a public-IP VPS. The README explicitly says this permits SSH, IMAP, custom protocols, and anything else SOCKS5 can carry, rather than limiting the system to HTTP-shaped proxy requests.
That capability requires an important tradeoff. Apps Script does not perform the final outbound connection. The VPS executes the real `net.Dial` to the requested target and returns response bytes through the same relay path. The project therefore needs two continuously available programs: the client on the user's computer and the exit server on the VPS. The README describes a small VPS as sufficient and gives $4 per month as an example, but it does not state bandwidth, CPU, memory, or concurrency guarantees.
The intended user is therefore someone who needs a portable raw TCP exit and is willing to operate the infrastructure. It is not a direct replacement for an operating-system VPN client. Applications must be configured to use the local SOCKS5 proxy unless the optional LAN-sharing setup is added.
Frame, encryption, and session routing
The data path has several distinct stages. On the client side, TCP bytes are grouped into frame batches and compressed with Zstandard. The README says this can reduce body size by as much as 65 percent for compressible traffic such as plain HTTP or JSON APIs. Compressing before encryption is significant because the request body is the unit submitted through Apps Script, so a smaller body can reduce network transfer and consumption of Google's URLFetch quota.
The client then seals the entire compressed batch in an AES-256-GCM envelope. The documentation states that the key remains end to end between client and VPS, while Apps Script receives only an opaque body to forward verbatim. The VPS decrypts the batch and uses `session_id` to demultiplex traffic belonging to multiple SOCKS sessions. It opens a connection to the destination and pumps response bytes back toward the client. Return traffic uses long polling according to the architecture diagram.
The outer request goes to a Google edge IP with `SNI=www.google.com` and `Host=script.google.com`. The Apps Script web app is described as a roughly 30-line forwarder, and the README says it never receives the plaintext or AES key. Domain fronting gives the transport the shape of ordinary HTTPS traffic to Google, but it does not make the tunnel independent of Google Apps Script availability, execution limits, URLFetch quotas, or account policy.
Apps Script quota and VPS failure boundaries
The main capacity boundary is Google Apps Script execution quota, not the cryptographic format. The README estimates about 20,000 `UrlFetch` executions per day on the free tier and emphasizes that this quota is shared across every deployment under the same Google account. Dividing the account across several Apps Script deployments does not divide the quota. It resets at midnight Pacific, which the README approximates as 10:30 AM Iran time in summer and 11:30 AM in winter.
Compression can improve how much traffic fits into a given request count for compressible payloads, but the README does not promise that compression applies equally to encrypted application traffic, binary streams, or already compressed content. Applications that generate many small transactions can still create request patterns that are inefficient for a request-and-long-polling relay. Engineers should treat the quoted daily execution count as a deployment constraint to verify against current Google quotas rather than a fixed GooseRelayVPN limit.
The VPS is also a mandatory failure domain. If it is stopped, loses its public network path, or cannot accept the tunnel connection, the client cannot complete outbound TCP sessions even when Apps Script remains reachable. Conversely, an Apps Script outage or quota exhaustion blocks relay requests. The README does not document retry policy, offline behavior, failover between Apps Script deployments, or a rollback procedure, so those behaviours should not be assumed.
Building the client and exit server
The repository contains separate command trees at `./cmd/client` and `./cmd/server`, plus example configuration files named `client_config.example.json` and `server_config.example.json`. A source build can create both binaries from the Go 1.22 module. The Makefile emits them into `bin/` and injects a version derived from Git tags.
From the repository root, this command builds both programs:
make buildThe resulting files are `bin/goose-client` and `bin/goose-server`. The README also documents prebuilt archives for Windows, macOS on Intel and Apple Silicon, Linux, and Android or Termux. It recommends the releases route for ordinary installation. The archive version placeholder must be replaced with the version listed on the Releases page.
For a Linux VPS with root access, the documented installer combines download, configuration, key generation, systemd setup, and firewall work:
bash <(curl -Ls https://raw.githubusercontent.com/Kianmhz/GooseRelayVPN/main/scripts/goose-server.sh)The README states that this script verifies the release tarball against `SHA256SUMS.txt`, generates a fresh `tunnel_key`, and provides `install`, `update`, `uninstall`, and reconfigure menus when run again. This is the most complete documented server installation path, but executing a piped remote script still deserves inspection in environments with strict change-control requirements.
A container image is also defined as `ghcr.io/kianmhz/gooserelayvpn-server:latest`. The image listens on port `8443` and starts the server with `-config /app/server_config.json`. A host `server_config.json` is mounted read-only by the Compose definition. The README excerpt does not include the configuration contents, so it does not support inventing exact JSON keys for the tunnel endpoint, certificate, or listener.
First SOCKS5 session through the relay
A working deployment requires three configured pieces: `goose-server` on the public-IP VPS, the Apps Script forwarding web app, and `goose-client` on the local machine. The tunnel key created during server setup must be placed in the client configuration, according to the README's installer description. Apps Script must forward request bodies verbatim to the VPS and expose the resulting service as a web app endpoint consumed by the client.
After those values are present in the respective configuration files, start the server and client according to the project's configuration mechanism, then point an application at the documented local SOCKS5 address:
127.0.0.1:1080The expected path is an application TCP connection to the SOCKS5 listener, a Zstd-compressed and AES-256-GCM-protected batch sent through the Apps Script URL, a destination connection created by the VPS, and response data returned through long polling. If the connection does not establish, the first distinction is whether the VPS is reachable on its tunnel listener and whether the client has the same tunnel key. If both are correct, quota exhaustion or an Apps Script deployment problem becomes more likely.
The README excerpt ends before the complete client launch command and the contents of the example configuration files. It also does not show a first destination address, expected log output, or a health-check command. This article therefore stops short of inventing invocation flags or claiming a complete copy-and-run example. The repository examples are the appropriate first files to inspect when configuring the exact client and server versions.
GooseRelayVPN versus an Apps Script-only proxy
The relevant alternative is a pure Google Apps Script proxy that terminates requests without a separate VPS exit. The distinction is architectural. A pure Apps Script proxy remains inside Google's execution environment and is suited to request types that the Apps Script handler itself can serve. GooseRelayVPN deliberately inserts a VPS because raw TCP requires a real outbound socket somewhere outside Apps Script.
That design expands protocol coverage to SSH, IMAP, and arbitrary SOCKS5-compatible streams. It also adds a public IP, a long-running server process, key distribution between two binaries, server maintenance, and a two-service dependency graph. A user who only needs simple web requests through Apps Script may prefer the simpler architecture and accept its narrower protocol range. A user who needs raw TCP cannot remove the VPS requirement without replacing the exit mechanism elsewhere.
Docker does not remove these boundaries. The `docker-compose.yml` file publishes `8443`, mounts the server configuration read-only, and restarts the container unless stopped. It packages the exit process, but the container still needs reachable networking and a valid `server_config.json`.
Release cadence, upgrades, and MIT terms
The repository is not archived, and its last push was on 2026-05-29. The README also lists releases v1.6.0 on 2026-05-06, v1.7.0 on 2026-05-21, and v1.7.1 on 2026-05-23. That sequence indicates several releases within a short period, so adopters should read release notes and configuration differences before replacing an existing deployment.
Upgrade cost is not limited to replacing binaries. Client and server versions must remain compatible, the shared tunnel key must be preserved or migrated, and Apps Script forwarding must continue to send opaque bodies to the expected endpoint. The server installer exposes an `update` menu according to the README, while the Makefile supports builds, tests, race checks, vetting, dependency tidying, and local cross-compilation. The README does not document automatic client updates, zero-downtime server replacement, database migrations, or rollback, so users should not infer those capabilities from the updater menu.
The repository uses the MIT license. That permits use, modification, distribution, and sublicensing under the license's stated conditions, including preservation of its copyright and permission notice. It does not transfer ownership of the project or imply warranties or operational responsibility. Users remain responsible for VPS costs, account quota compliance, endpoint security, and the legal use of the tunnel in their jurisdiction.
Editorial conclusion
GooseRelayVPN fits users who specifically need raw TCP through a Google Apps Script transport and already have a public-IP VPS plus an Apps Script deployment. It does not suit users seeking a conventional VPN, an HTTP-only proxy, or a system without a continuously reachable exit server. Before adoption, verify the installed client and server configuration files, confirm how the VPS accepts its tunnel connection, and estimate request volume against the account's shared URLFetch quota.
Frequently asked questions
Does GooseRelayVPN require a VPS?
Yes. The README states that a small public-IP VPS is required because the server must perform a real outbound `net.Dial` for raw TCP traffic.
Which protocols can GooseRelayVPN carry?
The project describes support for anything SOCKS5 can carry, with SSH, IMAP, and custom protocols given as examples. HTTP is only one possible application protocol.
What is the main capacity limitation of GooseRelayVPN?
The documented free-tier limit is about 20,000 Apps Script `UrlFetch` executions per Google account per day. The quota is shared across deployments, and Zstandard compression can reduce body size for compressible traffic.
Official sources
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.
[](https://hysenlabs.com/projects/kianmhz-gooserelayvpn)Was this useful?