Claude
Skills
Sign in
Back

gooserelayvpn-socks5-tunnel

Included with Lifetime
$97 forever

Expert knowledge for building, configuring, and operating GooseRelayVPN — a SOCKS5 VPN that tunnels raw TCP through Google Apps Script to a VPS exit server using AES-256-GCM encryption and domain fronting.

General

What this skill does


# GooseRelayVPN SOCKS5 Tunnel Skill

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

## What It Does

GooseRelayVPN is a SOCKS5 proxy that tunnels raw TCP through a Google Apps Script web app to a self-hosted VPS exit server. The traffic path:

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

Key properties:
- **Domain fronting**: TLS SNI shows `www.google.com`; actual host is `script.google.com`
- **End-to-end AES-256-GCM**: Google never holds the key
- **Raw TCP tunneling**: SSH, IMAP, custom protocols — anything SOCKS5 carries
- **Multi-deployment load balancing**: Round-robin + health-aware blacklist across multiple Apps Script deployments

---

## Architecture Overview

| Component | Location | Purpose |
|-----------|----------|---------|
| `goose-client` | Local machine | SOCKS5 listener, AES encrypt, HTTPS relay |
| Google Apps Script | Google cloud (free) | Dumb HTTP forwarder, domain-fronting layer |
| `goose-server` | Your VPS | AES decrypt, TCP dial to real targets |

---

## Installation

### Option A: Pre-built Binaries

```bash
# Client (local machine) - Linux example
wget https://github.com/kianmhz/GooseRelayVPN/releases/latest/download/GooseRelayVPN-client-vX.Y.Z-linux-amd64.tar.gz
tar -xzf GooseRelayVPN-client-vX.Y.Z-linux-amd64.tar.gz

# Server (VPS)
wget https://github.com/kianmhz/GooseRelayVPN/releases/latest/download/GooseRelayVPN-server-vX.Y.Z-linux-amd64.tar.gz
tar -xzf GooseRelayVPN-server-vX.Y.Z-linux-amd64.tar.gz
```

Platform suffixes: `windows-amd64`, `darwin-amd64`, `darwin-arm64`, `linux-amd64`, `android-arm64`

### Option B: Build from Source (Go 1.22+)

```bash
git clone https://github.com/kianmhz/GooseRelayVPN.git
cd GooseRelayVPN

# Build both binaries
go build -o goose-client ./cmd/client
go build -o goose-server ./cmd/server

# Cross-compile for Linux VPS from macOS/Windows
GOOS=linux GOARCH=amd64 go build -o goose-server-linux ./cmd/server
```

---

## Quick Start

### Step 1: Generate Secret Key

```bash
bash scripts/gen-key.sh
# Outputs a 64-character hex string — use this as tunnel_key in both configs
```

Or generate manually:
```bash
openssl rand -hex 32
```

### Step 2: Configure Client

`client_config.json`:
```json
{
  "socks_host":  "127.0.0.1",
  "socks_port":  1080,
  "google_host": "216.239.38.120",
  "sni":         "www.google.com",
  "script_keys": ["YOUR_APPS_SCRIPT_DEPLOYMENT_ID"],
  "tunnel_key":  "YOUR_64_CHAR_HEX_KEY"
}
```

### Step 3: Configure Server

`server_config.json`:
```json
{
  "server_host": "0.0.0.0",
  "server_port": 8443,
  "tunnel_key":  "SAME_64_CHAR_HEX_KEY_AS_CLIENT"
}
```

### Step 4: Deploy Google Apps Script

1. Go to [script.google.com](https://script.google.com) → New project
2. Replace default code with `apps_script/Code.gs` contents
3. Edit the VPS URL line:
   ```javascript
   const VPS_URL = 'http://YOUR_VPS_PUBLIC_IP:8443/tunnel';
   ```
4. **Deploy → New deployment** → Type: **Web app**
   - Execute as: **Me**
   - Who has access: **Anyone**
5. Copy the **Deployment ID** → paste into `script_keys` in client config

> ⚠️ Every code edit requires a **new deployment** (not just saving). Old deployment IDs stop working if you only save without redeploying.

### Step 5: Open VPS Firewall

```bash
# UFW
sudo ufw allow 8443/tcp

# Verify from local machine
curl http://YOUR_VPS_IP:8443/healthz
# Expected: HTTP 200 empty body
```

Also check cloud provider firewall (AWS Security Groups, DigitalOcean Firewall, etc.) for inbound TCP 8443.

### Step 6: Run Server on VPS

```bash
./goose-server -config server_config.json
```

### Step 7: Run Client Locally

```bash
./goose-client -config client_config.json
```

Expected output:
```
CLIENT  INFO    GooseRelayVPN client starting
CLIENT  INFO    SOCKS5 proxy: socks5://127.0.0.1:1080
CLIENT  INFO    pre-flight OK: relay healthy, AES key matches end-to-end
CLIENT  INFO    ready: local SOCKS5 is listening on 127.0.0.1:1080
```

---

## CLI Reference

```bash
# Client
./goose-client -config client_config.json
./goose-client -config /path/to/custom_client.json

# Server
./goose-server -config server_config.json
./goose-server -config /path/to/custom_server.json
```

Both binaries take only `-config` flag pointing to their respective JSON config file.

---

## Configuration Reference

### Client Config (`client_config.json`)

| Field | Type | Description |
|-------|------|-------------|
| `socks_host` | string | SOCKS5 listener address. Use `0.0.0.0` for LAN sharing |
| `socks_port` | int | SOCKS5 listener port (default: `1080`) |
| `google_host` | string | Google edge IP for domain fronting (e.g. `216.239.38.120`) |
| `sni` | string | TLS SNI value (must be `www.google.com`) |
| `script_keys` | []string | One or more Apps Script Deployment IDs or full `/exec` URLs |
| `tunnel_key` | string | 64-char hex AES-256 key — must match server |

### Server Config (`server_config.json`)

| Field | Type | Description |
|-------|------|-------------|
| `server_host` | string | Bind address on VPS (use `0.0.0.0`) |
| `server_port` | int | Listen port (default: `8443`) |
| `tunnel_key` | string | 64-char hex AES-256 key — must match client |

---

## Multiple Deployments (Scaling)

Each Apps Script deployment handles ~20,000 calls/day. Add multiple deployment IDs to scale:

```json
{
  "socks_host":  "127.0.0.1",
  "socks_port":  1080,
  "google_host": "216.239.38.120",
  "sni":         "www.google.com",
  "script_keys": [
    "AKfycbx_DEPLOYMENT_ID_ONE_xxxx",
    "AKfycbx_DEPLOYMENT_ID_TWO_xxxx",
    "AKfycbx_DEPLOYMENT_ID_THREE_xxxx"
  ],
  "tunnel_key":  "YOUR_64_CHAR_HEX_KEY"
}
```

The client automatically:
- **Round-robins** across all deployments
- **Backs off** failing deployments (3s → 6s → 12s → up to ~48s)
- **Retries** failed polls on another deployment in the same cycle

All deployments point to the same VPS and use the same `tunnel_key`.

---

## Systemd Service (VPS)

```bash
sudo nano /etc/systemd/system/goose-relay.service
```

```ini
[Unit]
Description=GooseRelayVPN exit server
After=network.target

[Service]
Type=simple
WorkingDirectory=/root
ExecStart=/root/goose-server -config /root/server_config.json
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl daemon-reload
sudo systemctl enable goose-relay
sudo systemctl start goose-relay
sudo systemctl status goose-relay --no-pager

# View logs
journalctl -u goose-relay -f
```

---

## Google Apps Script (`Code.gs`)

The Apps Script is a thin forwarder. Key structure to understand:

```javascript
// apps_script/Code.gs — dumb forwarder pattern
const VPS_URL = 'http://YOUR_VPS_PUBLIC_IP:8443/tunnel';

function doPost(e) {
  // Forwards request body verbatim to VPS
  // Never decrypts — AES key never touches Google
  const response = UrlFetchApp.fetch(VPS_URL, {
    method: 'post',
    payload: e.postData.contents,
    headers: { 'Content-Type': 'application/octet-stream' },
    muteHttpExceptions: true
  });
  return ContentService.createTextOutput(response.getContent())
    .setMimeType(ContentService.MimeType.OCTET_STREAM);
}
```

---

## Code Examples

### Programmatic Config Generation (Go)

```go
package main

import (
    "crypto/rand"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "os"
)

type ClientConfig struct {
    SocksHost  string   `json:"socks_host"`
    SocksPort  int      `json:"socks_port"`
    GoogleHost string   `json:"google_host"`
    SNI        string   `json:"sni"`
    ScriptKeys []string `json:"script_keys"`
    TunnelKey  string   `json:"tunnel_key"`
}

type ServerConfig struct {
    ServerHost string `json:"server_host"`
    ServerPort int    `json:"server_port"`
    TunnelKey

Related in General