- Kotlin 32.7%
- Go 31.5%
- Swift 18%
- Shell 13.7%
- Nix 4.1%
| android | ||
| fastlane/metadata/android/en-US | ||
| ios | ||
| ios12 | ||
| tools | ||
| yggproxy | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.md | ||
Yggdrasil Proxy (no VPN)
An Yggdrasil node for Android, iOS 16+, and iOS 12 (jailbroken) that provides SOCKS5 + HTTP (CONNECT) proxies instead of a VPN tunnel.
apps ──SOCKS5/HTTP──► yggproxy ──gVisor netstack──► ipv6rwc ──► Yggdrasil mesh
(on-device 127.0.0.1 or gateway [::])
- No TUN interface, no VpnService, no NetworkExtension. Apps that support a SOCKS5/HTTP proxy opt in themselves; everything else is untouched.
- Gateway mode: bind
[::]and other devices (laptops, old iPhones, anything without native support) just point their proxy settings at the phone — this is also how iOS 7 / 9 devices get access (native Go binaries cannot run there at all; see ios12/README.md). - Port forwarding both ways (yggstack-style
local-tcp/remote-tcp, TCP + UDP), built-in<pubkey>.pk.yggresolution, optional in-mesh DNS, optional username/password auth.
Repository layout
| path | what |
|---|---|
flake.nix |
nix dev environment: Go 1.26, gomobile, JDK 17, Android SDK/NDK, Gradle |
yggproxy/mobileproxy/ |
Go core (gomobile binding, shared by all frontends) |
yggproxy/cmd/yggproxy/ |
CLI (Linux/macOS testing; also the iOS 12 daemon) |
android/ |
Android app (Kotlin + Jetpack Compose), package net.homodian.yggproxy |
ios/ |
iOS 16+ app (SwiftUI, XcodeGen) |
ios12/ |
iOS 12 jailbreak: launch daemon .deb + minimal UIKit app |
tools/ |
build scripts (build-aar.sh, build-ios.sh, build-ios12.sh) |
Build (Linux/macOS with nix)
nix develop # enter the toolchain (first run downloads SDK/NDK)
./tools/build-aar.sh # gomobile → android/app/libs/yggproxy.aar
cd android && gradle :app:assembleDebug
# → android/app/build/outputs/apk/debug/app-debug.apk (installs as net.homodian.yggproxy)
gradle :app:assembleRelease # signed release APK (android/keystore.properties if
# present, else debug-key fallback for local testing)
Publishing (Google Play / F-Droid)
1. Create YOUR release key (once, keep it safe!):
./tools/make-keystore.sh # → android/release.jks + keystore.properties (gitignored)
2. Google Play — Play requires an App Bundle, and you should enroll Play App Signing so Google holds the final signing key (your local key becomes a recoverable upload key):
cd android && gradle :app:bundleRelease # → app-release.aab (signs with your key)
Console → Create app → Internal testing → upload the AAB → fill in Data
safety (this app: no data collection; traffic is proxied locally), Content
rating, Privacy policy URL → rollout. Bump versionCode/versionName in
android/app/build.gradle.kts for every release.
3. F-Droid — two options:
- Official repo: F-Droid rebuilds from source reproducibly and signs
with THEIR keys. fdroiddata-ready overlay:
fdroid/metadata/(pinned Go 1.26.7 tarball + sha256, pinned gomobile/gobind, NDK r26b,gradle: yesproducingapp-release-unsigned.apk— signing is intentionally conditional in build.gradle.kts). Copy bothmetadata/net.homodian.yggproxy.ymland themetadata/net.homodian.yggproxy/en-US/summary.txttriple-store into the fdroiddata fork — current fdroiddata wants Summary OUT of the yml. Before the MR: push the source to a public git host, update the Repo URLs in the yml, andgit tag -a v0.5.14 && git push --tags. Submit at https://gitlab.com/fdroid/fdroiddata (→ MR). Reproducibility notes: gomobile bind deps are pinned viayggproxy/tools.go;tools/build-aar.shnever floats versions. - Self-hosted repo on homodian.net (keeps YOUR signature, ship anytime):
pipx install fdroidserver
./tools/fdroid-publish.sh # → fdroid-repo/ static tree
# upload fdroid-repo/ to https://homodian.net/fdroid
Clients: F-Droid → Settings → Repositories → + → https://homodian.net/fdroid
Android install: adb install app/build/outputs/apk/debug/app-debug.apk
(minSdk 21, targetSdk 34, ABIs: arm64-v8a / armeabi-v7a / x86 / x86_64).
Build (macOS only — iOS requires Xcode)
brew install go xcodegen dpkg
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
./tools/build-ios.sh # iOS 16+ SwiftUI app project + framework
./tools/build-ios12.sh # iOS 12 jb: .deb daemon + minimal app
See ios12/README.md for jailbreak install details.
CLI (works on desktop too)
nix develop
cd yggproxy
go run ./cmd/yggproxy -autoconf -socks 127.0.0.1:1080 \
-peers-not-needed... # see -h; config via -useconffile node.conf
curl --proxy socks5h://127.0.0.1:1080 http://<pubkey>.pk.ygg/
Test
nix develop
cd yggproxy
go test -run TestProxyLoop -v ./mobileproxy/
# hermetic A↔B loop test: client → proxy A → loopback peering → node B → local HTTP,
# covering SOCKS5 (IPv6 + .pk.ygg) and HTTP proxy (plain + CONNECT). No internet needed.
Note: the upstream yggdrasil-go checkout is NOT required locally — the
yggproxy module depends on the released v0.5.14 tag via go.mod
(Go module proxy, reproducible by go.sum/hashes).
Usage notes
- The app ships with no default peers — add nearby ones from https://yggdrasil-network.github.io/peers.html (or enable multicast for WiFi peer discovery), then toggle Start.
- "Share proxy on LAN" listens on all interfaces → set auth if the network isn't trusted.
- iOS apps (no VPN entitlement) are suspended in the background — for a gateway scenario keep the screen on (in-app toggle) or use the iOS 12 jailbreak daemon. Android uses a foreground service and runs with the screen off.
License
AGPL-3.0-only — see LICENSE.
Versioning follows the embedded Yggdrasil core: this release is v0.5.14
(upstream yggdrasil-go v0.5.14).
Upstream dependencies are fetched as Go modules under their own licenses: yggdrasil-go and yggstack (LGPL-3.0-or-later with linking exception), gVisor (Apache-2.0), things-go/go-socks5 (MIT).