Connect OpenVPN service with Flutter, Issues and PRs are very welcome!

Android Setup

1. Permission handler

Add this to your onActivityResult in MainActivity.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);
    }

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

  1. You can use appbundle to publish the app
  2. 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

iOS

  1. View Apple Guidelines Relating to VPN
  2. This plugin DOES use Encryption BUT, It uses Exempt Encryptions

Licenses

Love my work?

Don't forget to give me a 👍  or support me with a cup of ☕️

Libraries

openvpn_flutter