Advanced Tailscale Client for Android with Userspace Networking & Transparent TUN VPN
English | Π ΡΡΡΠΊΠΈΠΉ
TailSocks is a high-performance Android client for Tailscale that operates in userspace-networking mode via tsnet. It provides a complete Tailscale environment β including Taildropβ’, Exit Nodes, Serve & Funnel, and Taildriveβ’ β without requiring Android's VpnService permission, enabling seamless coexistence with other VPN and firewall applications.
Optionally, TailSocks supports a transparent TUN VPN mode powered by the native hev-socks5-tunnel engine, providing full or split tunnel routing for system-wide connectivity.
| Feature | Description |
|---|---|
| Native LocalAPI | 100% CLI-less daemon management via Unix socket (tailscaled.sock) using LocalAPI v0. No shell commands. |
| SOCKS5 Proxy | Built-in local SOCKS5 proxy server with optional authentication for per-app routing. |
| LAN Access | One switch (Settings β Local proxies β Expose proxies to local network) binds the SOCKS5 proxy, HTTP proxy and local DNS to 0.0.0.0 so other devices on your Wi-Fi can route through your tailnet. The app shows the address to connect to and warns when the SOCKS5 proxy has no password β without one, anyone on the LAN can use it. |
| Root Mode (experimental) | On rooted devices the daemon runs as root with a real tailscale0 kernel interface, policy routing in table 53 via dedicated TAILSOCKS_MARK/TAILSOCKS_DNS iptables chains, per-app exclusions, an optional system-wide DNS redirect that is armed only while MagicDNS answers, a Check Routing diagnostics button and a ROOT log tab. When another VPN app holds Android's VPN slot, Root Mode steps aside β keeping the tailnet reachable while leaving that client its apps and its resolver β or carries only the apps that client bypasses; an override takes the device anyway. After a reboot the boot script installs tailnet reachability alone: the exit node and device-wide MagicDNS arrive when the app next runs. See the Root guide. |
| Control Plane Proxy | Route coordination server traffic through a custom SOCKS5/HTTP proxy for restricted regions. |
| TUN VPN Mode | Transparent system-wide VPN via native hev-socks5-tunnel β full tunnel & split tunnel, per-app exclusions, custom gateway IP. Tailnet IPv6 always rides the tunnel; routing the public IPv6 internet through it is opt-in, since an exit node that cannot carry v6 leaves those sites hanging. Enabling TUN asks first, because Android gives the VPN slot to one app at a time. |
| Exit Nodes Β© | Route all internet traffic through any authorized Tailscale peer with auto-healing and LAN access. |
| MagicDNS Β© | In-memory peer resolution (0ms), Split DNS over SOCKS5 TCP, smart upstream fallback with DoH support. |
| NAT Traversal | Real-time InMagicSock connectivity monitoring. STUN/DERP diagnostics via native netcheck. |
| Feature | Description |
|---|---|
| Tailscale Serve & Funnel Β© | Expose local ports to your Tailnet or the public internet. TCP & HTTPS modes, TLS certificate export. |
Tailscale Services (svc:) Β© |
Create named virtual services with dedicated VIPs and DNS names, managed from native UI. |
| Taildropβ’ Β© | Send & receive files between Tailnet devices. Inbox hub, system Share Sheet integration, DocumentsProvider. |
| Taildriveβ’ Β© | Share local folders over WebDAV. SAF integration, remote share mounting, SOCKS5-proxied access. Cross-platform path case-insensitivity fixes. |
| Feature | Description |
|---|---|
| Multi-Account Isolation | Strict per-profile data separation β independent state dirs, preferences, keypairs, and Taildrop folders. |
| Tailscale Admin API | Full api.tailscale.com/v2 integration β manage devices, DNS, users, services, webhooks, ACLs, and audit logs. |
| Biometric Lock | Admin Console protected by fingerprint/face authentication. |
| Auth Keys | Generate, view, and revoke authentication keys from inside the app. |
| Data Portability | Full encrypted app state backups (ZIP) and individual account exports (JSON, including the app-wide settings but never the automation secret, the API token or the node keys). Backups record the app version and format that produced them; an older app refuses to restore an archive made by a newer version instead of corrupting the profile (backups from older versions still restore). |
| Automation | Token-protected Broadcast Intents for Tasker/MacroDroid/ADB and 14 AppFunctions for on-device assistants (Gemini, Android 16+). See the Automation guide. |
| Feature | Description |
|---|---|
| Compact Dashboard | High-density 2Γ4 grid β Console, Peers, Logs, Files, DNS, Netcheck, Settings, Serve. |
| Material 3 Theming | System, Light, Dark, AMOLED Black modes. 7 color presets + Material You dynamic colors. |
| Localization | Crowdin-compatible i18n system. Russian language included. |
| Home Screen Widgets | Jetpack Glance widgets β Service Toggle, Exit Node, Stats Dashboard, Serve status. |
| Quick Settings Tile | System Quick Settings tile with active profile display and account switching. |
| Network Diagnostics | Native netcheck with DERP latency visualization, NAT type detection, and public IP reporting. |
| Background Reliability | Optional auto-reconnect with an attempt limit, a 15-minute watchdog that revives a service killed in the background, and a session-long wake lock (Keep the connection awake, which also decides whether the service starts after a reboot). A manual Stop is always final. See Background behaviour. |
Interface Screenshots
Main Dashboard
|
Account Switcher
|
Peers List
|
System Logs
|
Taildropβ’ (Incoming)
|
Taildriveβ’ Shares
|
DNS Management
|
App Settings
|
Profile Settings
|
Network Diagnostics
|
Serve & Funnel
|
Send via Taildropβ’
|
TailSocks is built as a hybrid multi-layer system:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Jetpack Compose UI (Kotlin) β
β Dashboard Β· Peers Β· Logs Β· DNS Β· Netcheck Β· Serve Β· Settings β
β Admin API Console Β· Taildrive Β· Taildrop Β· TUN Config β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β JNI / Gomobile Bridge (appctr) β
β LocalAPI Client Β· DNS Proxy Β· IPN Bus Β· Netcheck Β· Taildrop β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Tailscale Daemon (libtailscale.so) β
β tsnet Β· WireGuard Β· magicsock Β· DERP Β· Serve/Funnel Β· Drive β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ€
β SOCKS5 Proxy Mode β TUN VPN Mode (optional) β
β Per-app proxying via β System-wide routing via native β
β local SOCKS5 server β hev-socks5-tunnel (C library) β
β (no VpnService) β Full/Split tunnel + app exclusions β
βββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology | Purpose |
|---|---|---|
| Daemon | Go β libtailscale.so (PIE) |
Patched Tailscale core compiled with aggressive build tags to strip desktop/enterprise features. Targets arm64, arm, x86, x86_64. |
| Bridge | Go β appctr.aar (Gomobile) |
High-speed JNI bridge handling LocalAPI calls, DNS proxying, IPN bus monitoring, netcheck, Taildrop, and Taildrive WebDAV. |
| App | Kotlin + Jetpack Compose | Material 3 UI, foreground service lifecycle, Android system integrations (SAF, Widgets, Quick Settings, Share Sheet). |
| TUN Engine | C β hev-socks5-tunnel |
Optional transparent VPN interface. Routes traffic through the SOCKS5 proxy at kernel level. Per-app and per-IP exclusions. |
- Stateless Configuration: Every config update is explicit. Serve/Funnel uses a "Reset-then-Apply" pattern (POST
{}β POST new config) to prevent stale daemon state. - Passive Daemon Management: No aggressive polling loops. The daemon manages its own lifecycle, policy sync, and reconnection.
- Account Isolation: State in
files/states/{id}/, preferences inappctr_{id}. Full daemon restart on profile switch. - DNS Wrapping: MagicDNS resolved from in-memory node cache. Split DNS wrapped as TCP-over-SOCKS5. Fallback chain: SOCKS5 UDP β Direct UDP β DoH.
- 410 Wall Mitigation: Configuration updates are blocked while a Login URL is active to protect authentication sessions.
TailSocks maintains 16 minimal atomic patches in appctr/patches/ to inject capabilities not exposed via LocalAPI:
| Patch | Purpose |
|---|---|
01-enable-socks-android |
Enable SOCKS5 support in userspace-networking on Android |
02-socks5-auth |
Add username/password fields to the outbound SOCKS5 listener |
03-taildrop-monolithic-fs |
Pure-Go fsFileOps to avoid JNI panics in Taildrop |
04-vip-services |
Append VIP services to HostInfo for coordination server visibility |
05-localapi-cert |
Enable /cert endpoint compilation on Android |
06-android-netmon |
Custom netmon.InterfaceGetter for Android 10+ netlink restrictions; the Hostinfo masquerade (OS = linux by default, the real device with Report the real OS) |
07-taildrive-android |
Android-specific Taildrive adaptations |
08-netstack-cgnat |
CGNAT routing fix for netstack |
09-netstack-loopback |
Loopback routing for self-addressed packets in netstack |
10-taildrive-userspace-dial |
Route remote peer WebDAV via tsdial.Dialer |
11-noop-dns-fallback |
DNS fallback env var injection for SERVFAIL prevention |
12-socket-permissions |
tailscaled creates its socket world-readable, without an external chmod loop |
13-android-osrouter |
Android kernel-TUN router: manage addresses and routes only, leave iptables to the app |
14-dns-forwarder-netstack |
Dial tailnet resolvers through netstack, and rescue a query the exit node refuses |
15-dnscache-static-hosts |
Honour TS_STATIC_HOSTS so a control proxy behind a hostname resolves |
16-android-somark |
Mark the root daemon's own sockets so another VPN client cannot swallow them |
Grab the latest APK from the Releases page, or use the download buttons at the top of this README.
Supported architectures:
arm64-v8a,armeabi-v7a,x86,x86_64
Minimum Android version: 5.0 (API 21)
Build instructions
Prerequisites:
- Android NDK (set
ANDROID_NDK_HOME) - Go β no specific version to install; the build sets
GOTOOLCHAIN=autoand fetches the exact Go toolchain the module requires gomobile(go install golang.org/x/mobile/cmd/gomobile@latest && gomobile init)- Android SDK with Gradle
1. Clone:
git clone --recurse-submodules https://github.com/bropines/tailsocks.git
cd tailsocks2. Compile Go core (downloads the Tailscale source pinned in appctr/TAILSCALE_VERSION, patches, and cross-compiles):
cd appctr
bash build.sh
cd ..3. Build APK:
# Debug build (installs alongside the release app as *.dev, no keystore needed)
./gradlew app:assembleDebug
# Release build β requires your own keystore; the build refuses to sign with the debug key
KEYSTORE_FILE="$PWD/tailsocks.jks" KEYSTORE_PASSWORD=... \
KEY_ALIAS=... KEY_PASSWORD=... ./gradlew app:assembleReleaseThe build script automatically downloads the correct Tailscale version, applies all patches, and compiles PIE binaries for 4 architectures. No fork maintenance required.
Release builds are R8-minified with resource shrinking, and the
verifyReleaseNativeMethodstask fails the build if R8 ever drops a JNI method the TUN library needs. Details in Build Instructions.
| Document | Description |
|---|---|
| Architecture Deep Dive | DNS wrapping, account isolation, netcheck, and patch analysis |
| Build Instructions | NDK setup, Go core compilation, dynamic patch pipeline |
| Project Retrospective | Evolution from PoC to the current architecture |
| AdGuard Setup | Coexistence with system-wide ad blockers |
| Serve & Funnel Guide | Exposing local ports and virtual services |
| Root Integration & Service Guide | System-wide root autostart daemon, the routing and DNS rules it installs, living next to another VPN client, service.d, and the CLI wrapper |
| Tasker & Automation Guide | Intent automation setup for Tasker, MacroDroid, Automate, and ADB |
| Roadmap | Planned features and short-term goals |
| Contributing | Build, patch and commit rules for your first pull request |
| Changelog | Full version history |
For users in restricted regions (e.g., where controlplane.tailscale.com is blocked/dropped), TailSocks offers an in-app bypass mechanism for the control plane:
TailSocks bundles a native JNI implementation of ByeDPI directly inside the app process. This allows bypassing SNI-based deep packet inspection (DPI) without spawning external binary processes.
- Security: ByeDPI binds strictly to a randomized loopback IP (e.g.,
127.182.201.43) and a randomized port in the127.0.0.0/8subnet upon every startup. This prevents other applications on the device from discovering or connecting to the proxy via simple port scanning. - Usage: Enable DPI Bypass (ByeDPI) in Settings β Censorship bypass and configure custom ByeDPI flags (default:
-s 1 -d split -r).
TailSocks supports background control via Android Broadcast Intents. You can automate connections using Tasker, MacroDroid, Automate, or adb.
A secret token is required. Set one under Settings β Automation & API (there is a Generate button) and pass it with every intent as the string extra secret (token and key are accepted too). Since 4.0.0 the receiver ignores every intent until a token is configured, so no other app on the device can stop your VPN or reroute traffic.
- Target Receiver:
io.github.bropines.tailscaled/.core.TaskerReceiver(packageio.github.bropines.tailscaled) - Supported Actions (each also has a short alias, e.g.
io.github.bropines.tailscaled.START):io.github.bropines.tailscaled.action.CONNECT/DISCONNECT/TOGGLE/RESTARTβ control the connectionio.github.bropines.tailscaled.action.GET_STATUSβ refreshes the widgets/tile state (theSTATUS_CHANGEDbroadcast is not visible to other apps)io.github.bropines.tailscaled.action.SET_EXIT_NODEβ extraexit_node(IP, ornoneto clear)io.github.bropines.tailscaled.action.SWITCH_ACCOUNTβ extraaccount(profile name or ID)io.github.bropines.tailscaled.action.SET_BYEDPIβ extrasenabled(boolean),flags(string)io.github.bropines.tailscaled.action.SET_TUNβ extraenabled(boolean)
adb shell am broadcast -a io.github.bropines.tailscaled.action.DISCONNECT -n io.github.bropines.tailscaled/.core.TaskerReceiver --es secret YOUR_TOKEN- Action: System β Send Intent
- Action:
io.github.bropines.tailscaled.action.CONNECT - Target: Broadcast Receiver
- Package:
io.github.bropines.tailscaled, Class:io.github.bropines.tailscaled.core.TaskerReceiver - Extra:
secret:YOUR_TOKEN
Full reference β every action, its extras, the status broadcast, and the AppFunctions list β in the Tasker & Automation Guide.
On Android 16 and newer TailSocks exposes 14 AppFunctions to on-device assistants: getStatus, getAvailableExitNodes, getTailnetPeers, getAccounts, connect, disconnect, toggle, selectExitNode, clearExitNode, switchAccount, setByeDpi, setTunMode, setAllowLanAccess, setMagicDns. Every function that changes state obeys the Allow External Automation switch; the read-only ones always answer.
- Auto-reconnect (Settings β Background & permissions, off by default) restarts the daemon when the connection does not come up or drops, with a configurable attempt limit. Waiting for you to sign in is not treated as a failure.
- Revive service in background (same place, on by default) checks every 15 minutes that the service is still alive and starts it again after a background kill. Allowing "Alarms & reminders" (offered when you turn the switch on) lets the check start the service from the background; without it the check still runs, just later. If your ROM refuses the start anyway, you get a notification that reconnects in one tap, and the app tells you once where the autostart permission is.
- Keep the connection awake (Settings β Background & permissions, off by default) holds a wake lock for the whole session so the connection survives deep sleep, and is also what starts the service again after a reboot. Costs battery. In Root Mode it decides how long the device waits for its exit node and system-wide MagicDNS after a restart: with it off, they arrive only when you next open the app.
- A manual Stop is final. Stopping from the app, notification, Quick Settings tile, a
DISCONNECTintent or thedisconnectAppFunction clears the desired state first; neither the watchdog, auto-reconnect nor Android's sticky restart bring the service back until you start it again. - Swiping the app away keeps the connection. Removing the task from Recents does not stop the service.
| App & Patches | Bropines β app development, architecture, and the majority of upstream patches |
| Initial Android Patches | Asutorufa β original Android networking (anet) and network monitor (netmon) patches that served as a starting point |
| DPI Bypass | hufyhang/byedpi β local HTTP/SOCKS5 DPI bypass utility |
| TUN Engine | heiher/hev-socks5-tunnel β native SOCKS5-to-TUN implementation |
| Core Engine | Tailscale Inc. β userspace networking engine (tsnet) |
| AI Assistant | Google Gemini β interface development, LocalAPI research, and patch engineering |
Distributed under the BSD-3-Clause License. See LICENSE for details.
Tailscale, Taildrop, Taildrive, MagicDNS, and Funnel are trademarks of Tailscale Inc. This project is an independent open-source contribution and is not affiliated with Tailscale Inc.











