DEV Community

Cover image for Build a Device-Wide SSH Tunnel on Android with Abdal 4iProto Android
Ebrahim Shafiei
Ebrahim Shafiei

Posted on

Build a Device-Wide SSH Tunnel on Android with Abdal 4iProto Android

Build a Device-Wide SSH Tunnel on Android with Abdal 4iProto
If you've ever run ssh -D 1080 and pointed your browser at a local SOCKS5 proxy, you already understand half of what this app does. The other half is the interesting part: doing it for every app on your phone, with no root, and with leak protection that actually holds up. Let's walk through it hands-on.
Abdal 4iProto Android is the Android client of the open-source Abdal 4iProto ecosystem by Ebrahim Shafiei (EbraSha). It builds a device-wide SSH tunnel on Android, routing all traffic through an encrypted connection to your own server. No third-party VPN provider, no per-app juggling.
TL;DR of the data flow
Here's the path a packet takes, start to finish:

 App → VpnService (TUN, raw IP packets)
    → hev-socks5-tunnel (native tun2socks via JNI)
    → local SOCKS5 bridge
    → SSH direct-tcpip channel (JSch)
    → your Abdal 4iProto Server → Internet
Enter fullscreen mode Exit fullscreen mode

The trick is that SSH forwards TCP streams, but the OS gives you raw IP packets. The native tun2socks engine bridges that gap by turning packets into SOCKS5 connections, which then get forwarded over SSH.
Step 1: Stand up a server
This is a client, so you need the other end. Grab the server component from the ecosystem repo and get it running first. You'll need its IP/hostname, port, and an SSH username/password.
Step 2: Install and add a server
Open the app, then:

Hamburger menu → Server Management → Add Server
Enter a friendly name, your server's IP/hostname, port, username, and password
Select the server on the main screen

You can store multiple named servers and switch between them — handy if you run more than one.
Step 3: Configure before connecting
A gotcha worth flagging up front: connection options are applied at connect time, so toggle them before you tap Connect.
The ones worth knowing:

Fake-IP / FakeDNS — resolves domains on the server (remote DNS) so no real DNS query leaves your device. Turn this on to close the DNS-leak gap. With it off, you still get tunneled DNS-over-TCP.
Kill Switch — blocks all traffic if the tunnel drops unexpectedly, with no leak gap, until it reconnects or you disconnect.
Advanced Settings → Whitelist IPs / CIDR — comma-separated IPs or CIDR blocks that should bypass the tunnel.

Step 4: Per-app split tunneling (optional)
Open the Per-App Split Tun screen and pick a mode:

Route via Tunnel → only the apps you select are tunneled.
Bypass Tunnel → everything is tunneled except the apps you select.

The list is searchable and each app gets its own toggle. Apps kept off the tunnel are also exempt from the kill switch, so they keep normal connectivity.
Step 5: Connect
Tap Connect and grant the VPN permission when Android prompts. That permission is what lets the app stand up its VpnService TUN interface. Once it's up, your whole device is tunneled. Watch the real-time logs from the menu to confirm what's happening.
Tap Disconnect to tear it down.
Why it doesn't leak
Two implementation details do the heavy lifting here, and they're worth understanding if you build networking apps yourself:

The control socket is protected. The SSH connection itself is wrapped in VpnService.protect() so it doesn't get routed back into the TUN interface. Skip this and you get a routing loop that kills reconnects.
Local ranges bypass automatically. Private/LAN ranges (192.168.x.x, 10.x.x.x) skip the tunnel, so your router, printer, and any phone-hosted services keep working. On API 33+ this uses excludeRoute().

The stack, quickly

minSdk 24 (Android 7.0)  ·  compileSdk/targetSdk 36 (Android 16)
applicationId net.abdal.abdal4iproto.client  ·  versionName 5.2

Kotlin 2.2.10 · AGP 9.1.1 · Gradle 9.3.1 · KSP 2.3.5 · Java 11
UI: Jetpack Compose (Material 3), Navigation Compose 2.8.9
SSH: JSch (mwiede fork) 0.2.21
Crypto: Bouncy Castle bcprov-jdk18on 1.84  → ssh-ed25519 host keys
Coroutines: kotlinx-coroutines 1.10.2
Persistence: Room 2.7.0 (KSP)
Native: hev-socks5-tunnel (.so) tun2socks via JNI (TProxyService)
Enter fullscreen mode Exit fullscreen mode

The native tun2socks engine is the deliberate performance call — packet translation stays in compiled native code instead of crossing the JNI boundary per packet in managed Kotlin.
Wrapping up
The whole design comes down to one principle: capture everything, leak nothing, and keep the trust boundary at your server. No telemetry, open source, auditable via live logs. If you've been meaning to graduate from per-app proxies to a real device-wide tunnel you actually control, this is a clean way to do it.
FAQ
Do I need root? No — it uses VpnService.
Why does my home network still work while connected? Private/LAN ranges bypass the tunnel by design.
What's the minimum Android version? API 24. Some routing features need API 33+.
Can I tunnel only specific apps? Yes — use the Per-App Split Tun screen's "Route via Tunnel" mode.

https://github.com/ebrasha/abdal-4iproto-client-android

🤵 Programmer

Handcrafted with Passion by Ebrahim Shafiei (EbraSha)

Top comments (0)