Connect OpenVPN service with Flutter, Issues and PRs are very welcome!
Android Setup
1. Permission handler
JAVA
Add this to your onActivityResult in MainActivity.java (if you are using Java)
OpenVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK);
So it look like this
...
import id.laskarmedia.openvpn_flutter.OpenVPNFlutterPlugin;
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
OpenVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK);
super.onActivityResult(requestCode, resultCode, data);
}
Kotlin
Add this to your onAcivityResult in MainActivity.kt (if you are using Kotlin)
OpenVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK);
So it look like this
...
import id.laskarmedia.openvpn_flutter.OpenVPNFlutterPlugin
...
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
OpenVPNFlutterPlugin.connectWhileGranted(requestCode == 24 && resultCode == RESULT_OK)
super.onActivityResult(requestCode, resultCode, data)
}
iOS Setup
1. Add Capabillity
Add 2 capabillity on Runner's Target, App Groups and Network Extensions, Look at the image below to get clearer details
2. Add New Target
Click + button on bottom left, Choose NETWORK EXTENSION, and follow instruction's image bellow
Add Capabillity on VPNExtension, Do it same like Runner's Capabillitiy
3. Copy Paste
Add the following lines to your Podfile (ios/Podfile
)
target 'VPNExtension' do
use_frameworks!
pod 'OpenVPNAdapter', :git => 'https://github.com/ss-abramchuk/OpenVPNAdapter.git', :tag => '0.8.0'
end
Open VPNExtension > PacketTunnelProvider.swift and copy paste this script PacketTunnelProvider.swift
Note
You must use iOS Devices instead of Simulator to connect
Recipe
Initialize
Before start, you have to initialize the OpenVPN plugin.
late OpenVPN openvpn;
@override
void initState() {
openvpn = OpenVPN(onVpnStatusChanged: _onVpnStatusChanged, onVpnStageChanged: _onVpnStageChanged);
openvpn.initialize(
groupIdentifier: "GROUP_IDENTIFIER", ///Example 'group.com.laskarmedia.vpn'
providerBundleIdentifier: "NETWORK_EXTENSION_IDENTIFIER", ///Example 'id.laskarmedia.openvpnFlutterExample.VPNExtension'
localizedDescription: "LOCALIZED_DESCRIPTION" ///Example 'Laskarmedia VPN'
);
}
void _onVpnStatusChanged(VPNStatus? vpnStatus){
setState((){
this.status = vpnStatus;
});
}
void _onVpnStageChanged(VPNStage? stage){
setState((){
this.stage = stage;
});
}
Connect to VPN
void connect() {
openvpn.connect(
config,
name,
username: username,
password: password,
bypassPackages: [],
// In iOS connection can stuck in "connecting" if this flag is "false".
// Solution is to switch it to "true".
certIsRequired: false,
);
}
Disconnect
void disconnect(){
openvpn.disconnect();
}
Publishing to Play Store and App Store
Android
- You can use appbundle to publish the app
- Add this to your files in
android
folder (special thanks to https://github.com/nizwar/openvpn_flutter/issues/10). Otherwise connection will not be established in some cases and will siliently report "disconnected" when trying to connect. Most likely it's related to some symbols stripping by Google Play.
gradle.properties > android.bundle.enableUncompressedNativeLibs=false
AndroidManifest > android:extractNativeLibs="true" in application tag
app/build.gradle add these inside android tag
android{
...
//from here ======
lintOptions {
disable 'InvalidPackage'
checkReleaseBuilds false
}
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
bundle {
language {
enableSplit = false
}
density {
enableSplit = false
}
abi {
enableSplit = false
}
}
//to here
...
}
Notifications
As the plugin shows notification for connection status and connection detail, you have to request permission by using 3rd-party packages.
Example by using permission_handler
///Put it anywhere you wish like once you initialize the vpn or pre-connect the server
Permission.notification.isGranted.then((_) {
if (!_) Permission.notification.request();
});
iOS
- View Apple Guidelines Relating to VPN
- This plugin DOES use Encryption BUT, It uses Exempt Encryptions
Licenses
- openvpn_flutter for this plugin
- ics-openvpn for Android Engine
- OpenVPNAdapter for iOS Engine
Love my work?
Don't forget to give me a 👍 or support me with a cup of ☕️