L2TP/IPsec (IKEv1) for modern Android, with full-device VPN, proxy-only mode, and per-app routing.
Overview • Screenshots • Install • Development • Architecture • Security • Debugging • Feedback • Licensing
Android 12 removed the old built-in L2TP and PPTP VPN options. A lot of offices, schools, universities, and private networks still have L2TP/IPsec servers in place.
TunnelForge is an Android client for those setups. It connects to existing L2TP/IPsec (IKEv1) servers, so you can keep using the server you already have while running a current Android version.
- L2TP with optional IPsec (IKEv1) client flow
- Full-device VPN mode
- Proxy-only mode with local HTTP and SOCKS5 listeners
- Per-app routing (Inclusive and Exclusive)
- Multiple profiles with credential storage
- Connection status and detailed logs
- Custom DNS supporting UDP, TCP, TLS and HTTPS
- Variable MTU
|
|
|
Install TunnelForge from F-Droid to receive updates through your F-Droid client.
You can also download the latest APK directly from GitHub Releases for manual installation.
TunnelForge is only the client; you still need access to a compatible L2TP/IPsec server.
- Flutter with Dart
3.11+ - Go
1.25.9+for the Android gVisor userspace networking module - Android SDK configured for Flutter Android builds
- Android NDK and CMake, installed through Android Studio or
sdkmanager - Android
minSdk 31or newer for the app target
flutter pub get
cd android/gvisor
go mod download
cd ../..Run the app on a connected Android device or emulator:
flutter runThe Makefile wraps the commands used during normal development:
make format
make check
make test
make build-debugmake formatformats Dart and Android native C sources.make checkruns Flutter analysis, Android lint, and native C checks.make testruns Flutter, Android unit, and native C tests.make build-debugbuilds the Android debug APK.
For focused targets, run:
make helpflutter test --coverageThe included docker-compose.yml starts a local
hwdsl2/ipsec-vpn-server setup for Linux hosts.
- Copy .env.example to
.env. - Set
VPN_PUBLIC_IPto the address your Android client can reach. - Configure
VPN_IPSEC_PSK,VPN_USER, andVPN_PASSWORD. - Create a matching profile in the app.
Start the server:
docker compose up -dThe VPN container reads only the VPN_* values from the root .env.
TunnelForge is a Flutter app at the UI layer, but the VPN runtime is mostly Android-native. Flutter keeps the profile, settings, logs, and connection state, then talks to Kotlin through platform channels. Kotlin owns the Android VpnService and foreground service lifecycle, runs the Netty-based HTTP CONNECT/SOCKS5 proxy frontend, and hands tunnel work to native code. The C layer handles L2TP/IPsec and packet processing; proxy-only mode also uses a small Go/gVisor userspace networking module, built as a native shared library and loaded by the Android runtime.
Netty is the local proxy frontend. It accepts HTTP CONNECT and SOCKS5 clients with event-loop based I/O, while blocking tunnel transport work stays behind that frontend. The C engine remains the core L2TP/IPsec path, and Go/gVisor provides the userspace TCP/IP stack used by proxy-only mode.
| Path | Purpose |
|---|---|
lib/ |
Flutter UI, profiles, settings, logs, and app state |
android/app/src/main/kotlin/ |
Android VPN service, Netty proxy runtime, and platform channels |
android/app/src/main/cpp/ |
Native L2TP/IPsec tunnel engine and packet handling |
android/gvisor/ |
Go/gVisor userspace networking used by proxy mode |
fastlane/metadata/ |
Store metadata, screenshots, and changelogs |
tool/ |
Release, versioning, and VPN diagnostic scripts |
- VPN credentials are stored on-device with
flutter_secure_storage. - Debug logs stay local, and sensitive tokens are redacted before display or sharing.
- No analytics or crash-reporting SDKs are included in this repo.
- Review debug logs before sharing them in public issues.
General diagnostics:
sh tool/vpn_debug.sh check
sh tool/vpn_debug.sh diag --iface wlo1 --client-ip 192.168.1.100
sh tool/vpn_debug.sh capture --iface wlo1
sh tool/vpn_debug.sh log --iface wlo1Libreswan and container logs:
sh tool/vpn_debug.sh pluto-logs --container ipsec-vpn-server
docker exec -it ipsec-vpn-server tail -f /var/log/auth.logUse GitHub Issues or Telegram channel for bugs, feature requests or general feedback. When reporting a connection problem, include the values used in the profile (such as MTU and DNS), Android version, device model, and app logs (debug).
This project is licensed under GPL-3.0-only. See LICENSE.



