🌐 فارسی
Android client for GooseRelayVPN that runs the GooseRelay core through a Go mobile bridge and provides a complete Android UI for VPN lifecycle, profiles, logs, and settings.
- Upstream core project: https://github.com/kianmhz/GooseRelayVPN
- This repository: Android-focused client implementation
This app creates a local SOCKS5 endpoint on Android and tunnels TCP traffic through the GooseRelay architecture:
- Local app/browser traffic → SOCKS5
- GooseRelay encrypted framing (AES-256-GCM key from your profile)
- HTTPS path through Google-facing endpoints (Apps Script flow)
- Your VPS exit server handles outbound target connections
The app wraps this flow in Android VpnService so selected/full traffic can be routed through the tunnel.
| Home | Profiles | Settings | Logs |
![]() |
![]() |
![]() |
![]() |
| Profile Import | Profile Sharing | Settings Sharing |
![]() |
![]() |
![]() |
- 🔐 Android VPN integration (
VpnService+ tun2socks) - 🔌 SOCKS5 proxy endpoint (configurable host:port)
- 🛡️ AES-256-GCM encryption with per-profile keys
- 📍 Domain fronting through Google infrastructure
- 🎯 Split tunneling with package selection
- 📋 Remote profile subscriptions - Sync profiles from remote HTTPS URLs
- 🔗 goose-relay:// protocol - Share profiles via Base64-encoded URI scheme
- 📤 JSON import/export - Full profile backup and restore
- 📋 Clipboard import/export - Quick copy-paste profile sharing
- 🔄 Remote updates - One-click refresh from remote source
- ⚙️ Auto-save - Changes saved automatically to local database
- Multiple deployment IDs - Support for multiple Google Apps Script deployments
- Custom SOCKS settings - Host, port, and optional auth (username/password)
- SNI list - Customizable Server Name Indication hostnames
- Coalescing - Fine-tune tunnel packet coalescing behavior
- Idle slots - Control idle slot distribution per bucket
- 🏠 Home tab - Real-time connection status with telemetry cards
- 📊 Live logs - Core and app-level diagnostic logs
- ⚙️ Global settings - Internet sharing, DNS, connection mode
- 🌍 Settings tab - Profile-specific configuration
- 🎨 Material Design 3 with dark mode support
- 📱 Internet sharing - Share VPN via SOCKS/HTTP proxy (LAN)
- 🔒 Split tunneling - Include/exclude specific apps from VPN
- 🌐 Fake DNS - Local DNS interception and resolution
- 🔐 Allow LAN - Route local network traffic outside VPN
- 🔋 Low overhead - Efficient Go-based core
Profile fields are aligned with GooseRelay client config. Create profiles manually or import JSON:
{
"name": "My VPN Profile",
"debug_timing": false,
"socks_host": "127.0.0.1",
"socks_port": 1080,
"socks_user": "",
"socks_pass": "",
"google_host": "216.239.38.120",
"sni": [
"www.google.com",
"mail.google.com",
"accounts.google.com"
],
"script_keys": [
"REPLACE_WITH_DEPLOYMENT_ID",
"OPTIONAL_SECOND_DEPLOYMENT_ID|account@example.com"
],
"tunnel_key": "REPLACE_WITH_OUTPUT_OF_scripts_gen-key.sh",
"coalesce_step_ms": 0,
"idle_slots_per_bucket": 2
}| Field | Type | Description |
|---|---|---|
name |
string | Profile display name |
debug_timing |
boolean | Enable timing debug logs |
socks_host |
string | SOCKS5 server host (usually 127.0.0.1) |
socks_port |
integer | SOCKS5 server port (1-65535) |
socks_user |
string | SOCKS5 username (optional, paired with password) |
socks_pass |
string | SOCKS5 password (optional, paired with username) |
google_host |
string | Google IP for domain fronting |
sni |
array | SNI hostnames for TLS |
script_keys |
array/string | Google Apps Script deployment ID(s). Format: ID or ID|account |
tunnel_key |
string | Tunnel encryption key (server-side match required) |
coalesce_step_ms |
integer | Packet coalescing timeout (milliseconds) |
idle_slots_per_bucket |
integer | Idle slots per bucket (1-3) |
- Tap the
+button → Select "Add Manual" - Fill in fields directly in the form
- Tap the
+button → Select "From JSON" - Choose a
.jsonfile from your device - Profile fields are auto-populated
- Copy JSON or
goose-relay://protocol to clipboard - Tap the
+button → Select "From Clipboard" - Profile is created instantly
- Open a profile → Tap Share icon
- Select "to Clipboard" to copy
goose-relay://URI - Share via messaging, QR code, or link
- Recipients paste into clipboard and tap "From Clipboard"
- Edit Profile and add Remote URL:
https://your-server.com/profiles/my-profile.json - Profile will fetch and auto-update from this URL on each refresh
- Tap Refresh (↻) icon in Profiles toolbar to manually sync
- Changes save locally automatically
https://example.com/path/to/profile.json
Supported endpoints:
- Any HTTPS server hosting profile JSON
- Optional HTTP Basic Auth:
https://user:pass@example.com/profile.json - Self-signed certs: Certificate validation required (add to system trust store)
- Profiles with remote URLs fetch on manual refresh only (not automatic)
- All fields except
remoteUrlare updated from remote - Local changes are preserved if remote URL is not set
- On update failure, error message displayed in snackbar
By default, these apps bypass the VPN (included in split tunnel list):
- Instagram (
com.instagram.android) - Telegram (
org.telegram.messenger) - WhatsApp (
com.whatsapp) - YouTube (
com.google.android.youtube) - Chrome (
com.android.chrome) - Gmail (
com.google.android.gm) - Google Play Store (
com.android.vending) - Google Search (
com.google.android.googlequicksearchbox) - Twitter/X (
com.twitter.android) - OpenAI ChatGPT (
com.openai.chatgpt)
Modify in Global Settings → Split Tunneling → Edit package list.
- VPN: Full VPN routing (default)
- SOCKS: Direct SOCKS proxy (app-by-app)
- Split Tunneling: Enable per-app VPN selection (default: enabled)
- Mode: Include selected apps or exclude selected apps
- Allow LAN: Route local network traffic outside VPN
- Fake DNS: Intercept DNS queries locally (default: enabled)
- Share VPN via Network: Enable/disable
- SOCKS Port: Proxy port for LAN devices (default: 8090)
- HTTP Port: HTTP proxy port (default: 8091)
- Auth: Optional username/password for proxies
- Custom DNS Servers: Comma-separated DNS IP addresses
- Auto-save: Changes persist automatically (default: enabled in v1.7.1+)
- Tap ⋮ (More) menu in Settings toolbar
- Export to Clipboard — Copy all settings as JSON
- Import from Clipboard — Paste previously exported settings
You still need upstream infrastructure prepared first:
-
Prepare VPS
- Deploy VPS with public IP
- Run
goose-serverbinary - Note the VPS IP/domain
-
Deploy Google Apps Script
- Copy
apps_script/Code.gsfrom upstream repo - Create Google Apps Script project
- Paste code and deploy as web app
- Note the Deployment ID
- Copy
-
Generate Encryption Key
- Run
scripts/gen-key.sh - Output is your
tunnel_key
- Run
-
Add Profile to App
- Create new profile in app
- Set
script_keysto deployment ID(s) - Set
tunnel_keyto generated key - Set
google_host(usually 216.239.38.120)
-
Connect & Verify
- Tap Connect on Home
- Check Logs for any errors
- Verify traffic flows through VPN
For complete infrastructure details, see upstream docs:
- Android Studio 2024.1+
- JDK 17+
- Go 1.25.0+ (was 1.22, upgraded in v1.7.1)
- Android SDK API 36+
- Android NDK (latest)
cd android
bash ../build_go_mobile.shThis creates AAR library with GooseRelay core compiled for all architectures.
cd android
./gradlew :app:assembleDebugOutput: app/build/outputs/apk/debug/GooseRelayVPN.apk
Requires signing configuration in local.properties:
ANDROID_KEYSTORE_PATH=/path/to/keystore.jks
ANDROID_KEYSTORE_PASSWORD=keystore_password
ANDROID_KEY_ALIAS=key_alias
ANDROID_KEY_PASSWORD=key_passwordThen:
cd android
./gradlew :app:bundleReleaseOutput: app/build/outputs/bundle/release/app-release.aab
.github/workflows/android-ci.yml
- Runs on every push to
main/masterand on every pull request - Builds the Go mobile AAR (
bash ./android/build_go_mobile.sh) - Builds the debug APK (
./gradlew :app:assembleDebug) - Runs unit tests (
./gradlew :app:testDebugUnitTest) — added in the test-baseline work; if your branch is older, this step may not be present yet - Uploads the APK and AAR as workflow artifacts for download from the Actions tab
.github/workflows/release-manual.yml
- Manually triggered (
workflow_dispatch) with a requiredtag_nameinput (e.g.v1.2.3) and optionalrelease_name/make_latestinputs - Builds a signed, split-by-ABI release APK set plus a universal APK
and a Go AAR; requires the
ANDROID_KEYSTORE_BASE64,ANDROID_KEYSTORE_PASSWORD,ANDROID_KEY_ALIAS, andANDROID_KEY_PASSWORDrepo secrets - Creates a GitHub Release with
softprops/action-gh-release@v2and uploads the AAR and all APKs as release assets
There is no
release.ymlworkflow. Tag-triggered releases are performed by manually dispatchingrelease-manual.ymlwith the desired tag. If you need a tag-triggered workflow, add one as a sibling torelease-manual.ymland update this section.
Configure these in GitHub repository settings:
ANDROID_KEYSTORE_BASE64— Base64-encoded keystore fileANDROID_KEYSTORE_PASSWORD— Keystore passwordANDROID_KEY_ALIAS— Key alias in keystoreANDROID_KEY_PASSWORD— Key password
Release produces:
GooseRelayVPN.apk— Universal APK (all architectures)GooseRelayVPN-arm64-v8a.apk— ARM64 onlyGooseRelayVPN-armeabi-v7a.apk— ARMv7 onlyGooseRelayVPN-x86_64.apk— x86_64 onlyapp-release.aab— Google Play App Bundle
SOCKS Port Busy
- Disconnect VPN, wait 3 seconds, reconnect
- Check no other app uses port 1080 (or configured port)
- Kill app via settings and restart
Connection Stays "Preparing"
- Verify
script_keys(deployment ID) is correct - Verify
tunnel_keymatches server-side key - Check Logs tab for core error messages
- Ensure VPS is running and reachable
No Traffic Flows
- Verify VPN permission is granted
- Check split tunneling app selection
- Ensure profile is selected and connected
- Review Logs for network errors
High Battery/Data Usage
- Disable debug logging (set
debug_timing: false) - Check split tunnel configuration
- Monitor active connections in Logs
Slow Connections
- Try different
google_hostvalues - Adjust
coalesce_step_ms(higher = more batch, more latency) - Test on different networks (WiFi vs mobile)
Gradle Error: "Failed to install gomobile"
- Check Go version:
go version(need 1.25.0+) - Delete
$GOPATH/pkg/mod/golang.org/x/mobileand retry
NDK Not Found
- Install via Android Studio: Settings → SDK Manager → SDK Tools
- Set
ANDROID_NDKenvironment variable
┌─────────────────────────────────────────────┐
│ Android UI Layer (Compose) │
│ ┌──────────────────────────────────────┐ │
│ │ Home │ Profiles │ Settings │ Logs │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ ViewModels & Repository Layer │
│ ┌──────────────────────────────────────┐ │
│ │ Room Database │ DataStore │ Hilt DI │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ VPN Service & Go Core │
│ ┌──────────────────────────────────────┐ │
│ │ tun2socks │ GooseRelay Core (Go) │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Network Layer │
│ ┌──────────────────────────────────────┐ │
│ │ SOCKS5 → Google Apps Script → VPS │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
- ✅ Remote profile subscriptions with manual refresh
- ✅ goose-relay:// protocol for URL-based profile sharing
- ✅ Clipboard import/export for profiles
- ✅ Global settings clipboard export/import
- ✅ Auto-save for profile and global settings changes
- ✅ Dropdown menus for profile management (+ button, share)
- ✅ Default split tunneling apps (Instagram, Telegram, WhatsApp, YouTube, Chrome, Gmail, Play Store, etc.)
- ✅ Updated to Gradle 8.13, Android Gradle Plugin 8.13.0
- ✅ Updated to Go 1.25.0 with latest dependencies
- ✅ JVM memory increased (Xmx4096m)
- ✅ Fixed SOCKS field defaults in JSON export
- ✅ Improved error handling for imports
- VPN service with tun2socks
- Profile management
- Live logs and diagnostics
- Split tunneling
- Internet sharing
- Language: Kotlin 2.1.0
- Framework: Jetpack Compose
- Architecture: MVVM with Clean Architecture
- Database: Room ORM
- DI: Hilt
- VPN: Android VpnService API, tun2socks
- Build: Gradle 8.13, Android Gradle Plugin 8.13.0
- Version: 1.25.0 (upgraded from 1.23.1)
- Crypto: AES-256-GCM (golang.org/x/crypto)
- Networking: golang.org/x/net 0.52.0, tun2socks
- Compression: klauspost/compress (Brotli, Gzip)
- Logging: Uber zap
Go:
github.com/things-go/go-socks5— SOCKS5 servergithub.com/xjasonlyu/tun2socks/v2— TUN device handlergolang.org/x/net v0.52.0— Networking utilitiesgolang.org/x/mobile v0.0.0-20260312152759-81488f6aeb60— Go mobile bindinggolang.org/x/crypto v0.49.0— Cryptography
Android:
- Jetpack Compose, Navigation, Hilt, Room
- Datastore Proto, Gson, Coil (images)
See go.mod, go.sum, and android/build.gradle.kts for complete lists.
-
Main GooseRelay Project
-
Inspiration
-
Community
- Go, Kotlin, Jetpack Compose teams
- tun2socks, SOCKS5, and networking library authors
See LICENSE file for details.
- Issues: Report bugs on GitHub Issues
- Discussions: Join GitHub Discussions
- Contributing: PRs welcome!
- Upstream: Questions about core protocol → GooseRelayVPN
This tool is for educational and authorized use only. Users are responsible for:
- Compliance with local laws and regulations
- Proper authorization from network administrators
- Ethical use of VPN technology
- Respecting terms of service of infrastructure providers
Developers are not liable for misuse or damages.






