Global Proxy for Android
See the codeA global proxy app for Android, modernised around a VPN-first architecture.
ProxyDroid forwards device traffic to an upstream SOCKS5 or HTTP proxy
without requiring root. It installs a VpnService, captures IP packets on
a TUN device, and converts TCP/UDP flows into proxy connections in
userspace.
VpnService, which works on every supported Android
release.app/src/main/rust/proxydroid-tun2socks, built with
netstack-smoltcp and
invoked from Kotlin through JNI. Cargo builds are wired in via
org.mozilla.rust-android-gradle.VpnService addDisallowedApplication API.CONNECT (with optional Basic auth)compileSdk 36 installed25.1.89373933.22.1aarch64-linux-android, armv7-linux-androideabi,
i686-linux-android, x86_64-linux-androidAGP is pinned to 8.1.2 and Kotlin to 1.9.10. See
gradle/libs.versions.tomlfor every version. Do not bump AGP without verifying therust-android-gradle0.9.6mergeJniLibFoldersduplicate-resources interaction (cf. commits0249f91,8875c74).
cargoBuild and feeds the
JNI libraries into the merged APK.Build > Make Project../gradlew assembleDebug # debug APK at app/build/outputs/apk/debug/
./gradlew assembleRelease # release APK; requires signing config (see below)
Signing for release is opt-in. Add a local.properties with:
KEYSTORE_PATH=/absolute/path/to/keystore.jks
KEYSTORE_PASSWORD=...
KEY_ALIAS=...
KEY_PASSWORD=...
If those keys are absent the release variant builds unsigned.
app/
├── src/main/
│ ├── java/org/proxydroid/ # Kotlin sources (Compose UI + VpnService)
│ ├── res/ # Resources
│ ├── cpp/ # Native helpers built via CMake
│ │ └── exec/ # termExec — JNI native-process helper
│ ├── rust/
│ │ └── proxydroid-tun2socks/ # Rust tun2socks crate (netstack-smoltcp)
│ └── AndroidManifest.xml
├── build.gradle # App module build (consumes libs.versions.toml)
└── proguard-rules.pro
gradle/
├── libs.versions.toml # Single source of truth for dependency versions
└── wrapper/
build.gradle # Root build, repos + plugin classpath
gradle.properties # JVM args + AGP compileSdk suppression
settings.gradle
scripts/ # Test helpers (Python SOCKS5/HTTP servers, etc.)
Legacy
cpp/libeventandcpp/redsocksdirectories from the iptables era are scheduled for removal in the ongoing refactor. The redsocks path is no longer reachable from Kotlin.
HostSocks5ProxyIntegrationTest runs inside an Android emulator and
routes an HTTP request through a SOCKS5 proxy listening on the host. The
host proxy is a small stdlib-only Python server in
scripts/socks5_test_server.py.
The emulator reaches the host loopback via the alias 10.0.2.2, so a
host proxy bound to 0.0.0.0:1080 is seen by the device as
10.0.2.2:1080.
# Terminal 1 — start the SOCKS5 proxy on the host:
python3 scripts/socks5_test_server.py --host 0.0.0.0 --port 1080
# Terminal 2 — boot any AVD, then run the instrumentation test:
./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.class=org.proxydroid.HostSocks5ProxyIntegrationTest
Override defaults with
-Pandroid.testInstrumentationRunnerArguments.socksHost=...,
socksPort, targetHost, targetPort.
armeabi-v7a, arm64-v8a, x86, x86_64.
minSdk 24 (Android 7.0)targetSdk / compileSdk 36 (Android 16) — required by Google Play
2025/2026 policyGPLv3.
227 followers · starred Jan 2012
61 followers · starred Mar 2021
144 followers · starred Jan 2012
259 followers · starred Aug 2026
Global Proxy for Android
See the codeA global proxy app for Android, modernised around a VPN-first architecture.
ProxyDroid forwards device traffic to an upstream SOCKS5 or HTTP proxy
without requiring root. It installs a VpnService, captures IP packets on
a TUN device, and converts TCP/UDP flows into proxy connections in
userspace.
VpnService, which works on every supported Android
release.app/src/main/rust/proxydroid-tun2socks, built with
netstack-smoltcp and
invoked from Kotlin through JNI. Cargo builds are wired in via
org.mozilla.rust-android-gradle.VpnService addDisallowedApplication API.CONNECT (with optional Basic auth)compileSdk 36 installed25.1.89373933.22.1aarch64-linux-android, armv7-linux-androideabi,
i686-linux-android, x86_64-linux-androidAGP is pinned to 8.1.2 and Kotlin to 1.9.10. See
gradle/libs.versions.tomlfor every version. Do not bump AGP without verifying therust-android-gradle0.9.6mergeJniLibFoldersduplicate-resources interaction (cf. commits0249f91,8875c74).
cargoBuild and feeds the
JNI libraries into the merged APK.Build > Make Project../gradlew assembleDebug # debug APK at app/build/outputs/apk/debug/
./gradlew assembleRelease # release APK; requires signing config (see below)
Signing for release is opt-in. Add a local.properties with:
KEYSTORE_PATH=/absolute/path/to/keystore.jks
KEYSTORE_PASSWORD=...
KEY_ALIAS=...
KEY_PASSWORD=...
If those keys are absent the release variant builds unsigned.
app/
├── src/main/
│ ├── java/org/proxydroid/ # Kotlin sources (Compose UI + VpnService)
│ ├── res/ # Resources
│ ├── cpp/ # Native helpers built via CMake
│ │ └── exec/ # termExec — JNI native-process helper
│ ├── rust/
│ │ └── proxydroid-tun2socks/ # Rust tun2socks crate (netstack-smoltcp)
│ └── AndroidManifest.xml
├── build.gradle # App module build (consumes libs.versions.toml)
└── proguard-rules.pro
gradle/
├── libs.versions.toml # Single source of truth for dependency versions
└── wrapper/
build.gradle # Root build, repos + plugin classpath
gradle.properties # JVM args + AGP compileSdk suppression
settings.gradle
scripts/ # Test helpers (Python SOCKS5/HTTP servers, etc.)
Legacy
cpp/libeventandcpp/redsocksdirectories from the iptables era are scheduled for removal in the ongoing refactor. The redsocks path is no longer reachable from Kotlin.
HostSocks5ProxyIntegrationTest runs inside an Android emulator and
routes an HTTP request through a SOCKS5 proxy listening on the host. The
host proxy is a small stdlib-only Python server in
scripts/socks5_test_server.py.
The emulator reaches the host loopback via the alias 10.0.2.2, so a
host proxy bound to 0.0.0.0:1080 is seen by the device as
10.0.2.2:1080.
# Terminal 1 — start the SOCKS5 proxy on the host:
python3 scripts/socks5_test_server.py --host 0.0.0.0 --port 1080
# Terminal 2 — boot any AVD, then run the instrumentation test:
./gradlew connectedAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.class=org.proxydroid.HostSocks5ProxyIntegrationTest
Override defaults with
-Pandroid.testInstrumentationRunnerArguments.socksHost=...,
socksPort, targetHost, targetPort.
armeabi-v7a, arm64-v8a, x86, x86_64.
minSdk 24 (Android 7.0)targetSdk / compileSdk 36 (Android 16) — required by Google Play
2025/2026 policyGPLv3.
227 followers · starred Jan 2012
61 followers · starred Mar 2021
144 followers · starred Jan 2012
259 followers · starred Aug 2026